summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1996-08-22 06:32:03 +0000
committerAndrew Tridgell <tridge@samba.org>1996-08-22 06:32:03 +0000
commit5c3e8326cc45d3cbd076475e445ce461a2bf7560 (patch)
tree0ca50dc20b40cdcd2ffb014ef0b80cf96a678fc4
parentef3f5e57ae5091a66e73cfad2d0da2684cfac3db (diff)
downloadsamba-5c3e8326cc45d3cbd076475e445ce461a2bf7560.tar.gz
samba-5c3e8326cc45d3cbd076475e445ce461a2bf7560.tar.xz
samba-5c3e8326cc45d3cbd076475e445ce461a2bf7560.zip
- add timeouts to connect() for password server connections. This
makes multiple password servers practical.
-rw-r--r--source/client/client.c4
-rw-r--r--source/client/clientutil.c4
-rw-r--r--source/include/local.h4
-rw-r--r--source/include/proto.h3
-rw-r--r--source/lib/util.c69
-rw-r--r--source/nmbd/nmbd.c15
-rw-r--r--source/smbd/password.c2
7 files changed, 86 insertions, 15 deletions
diff --git a/source/client/client.c b/source/client/client.c
index 6bd94be7569..cc178967a16 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -2956,7 +2956,7 @@ static BOOL send_session_request(char *inbuf,char *outbuf)
putip((char *)&dest_ip,inbuf+4);
close_sockets();
- Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
+ Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
if (Client == -1)
return False;
@@ -4025,7 +4025,7 @@ static BOOL open_sockets(int port )
}
}
- Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
+ Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
if (Client == -1)
return False;
diff --git a/source/client/clientutil.c b/source/client/clientutil.c
index e684d426121..3058f654741 100644
--- a/source/client/clientutil.c
+++ b/source/client/clientutil.c
@@ -212,7 +212,7 @@ BOOL cli_send_session_request(char *inbuf, char *outbuf)
putip((char *)&dest_ip,inbuf+4);
close_sockets();
- Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
+ Client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT);
if (Client == -1)
return False;
@@ -835,7 +835,7 @@ BOOL cli_open_sockets(int port)
putip((char *)&dest_ip,(char *)hp->h_addr);
}
- Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
+ Client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT);
if (Client == -1)
return False;
diff --git a/source/include/local.h b/source/include/local.h
index 5a577909e14..3f8572e73dc 100644
--- a/source/include/local.h
+++ b/source/include/local.h
@@ -150,4 +150,8 @@
by many apps */
#define KEEP_PASSWORD_SERVER_OPEN 1
+/* how long to wait for a socket connect to happen */
+#define LONG_CONNECT_TIMEOUT 30
+#define SHORT_CONNECT_TIMEOUT 5
+
#endif
diff --git a/source/include/proto.h b/source/include/proto.h
index f8685d21ea1..e20238fee42 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -856,6 +856,7 @@ BOOL strhaslower(char *s);
int count_chars(char *s,char c);
void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date);
void close_low_fds(void);
+int set_blocking(int fd, int set);
int write_socket(int fd,char *buf,int len);
int read_udp_socket(int fd,char *buf,int len);
int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out);
@@ -891,7 +892,7 @@ void Abort(void );
BOOL get_myname(char *my_name,struct in_addr *ip);
BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
int open_socket_in(int type, int port, int dlevel,uint32 socket_addr);
-int open_socket_out(int type, struct in_addr *addr, int port );
+int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
int interpret_protocol(char *str,int def);
int interpret_security(char *str,int def);
uint32 interpret_addr(char *str);
diff --git a/source/lib/util.c b/source/lib/util.c
index 2fedded3292..e13a4c37e80 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -478,6 +478,12 @@ struct
#ifdef SO_RCVLOWAT
{"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
#endif
+#ifdef SO_SNDTIMEO
+ {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
+#endif
+#ifdef SO_RCVTIMEO
+ {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
+#endif
{NULL,0,0,0,0}};
@@ -1655,6 +1661,35 @@ void close_low_fds(void)
}
}
+/****************************************************************************
+Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
+else
+if SYSV use O_NDELAY
+if BSD use FNDELAY
+****************************************************************************/
+int set_blocking(int fd, int set)
+{
+ int val;
+#ifdef O_NONBLOCK
+#define FLAG_TO_SET O_NONBLOCK
+#else
+#ifdef SYSV
+#define FLAG_TO_SET O_NDELAY
+#else /* BSD */
+#define FLAG_TO_SET FNDELAY
+#endif
+#endif
+
+ if((val = fcntl(fd, F_GETFL, 0)) == -1)
+ return -1;
+ if(set) /* Turn blocking on - ie. clear nonblock flag */
+ val &= ~FLAG_TO_SET;
+ else
+ val |= FLAG_TO_SET;
+ return fcntl( fd, F_SETFL, val);
+#undef FLAG_TO_SET
+}
+
/****************************************************************************
write to a socket
@@ -2813,10 +2848,12 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
/****************************************************************************
create an outgoing socket
**************************************************************************/
-int open_socket_out(int type, struct in_addr *addr, int port )
+int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
{
struct sockaddr_in sock_out;
- int res;
+ int res,ret;
+ int connect_loop = 250; /* 250 milliseconds */
+ int loops = (timeout * 1000) / connect_loop;
/* create a socket to write to */
res = socket(PF_INET, type, 0);
@@ -2831,15 +2868,35 @@ int open_socket_out(int type, struct in_addr *addr, int port )
sock_out.sin_port = htons( port );
sock_out.sin_family = PF_INET;
+ /* set it non-blocking */
+ set_blocking(res,0);
+
DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
/* and connect it to the destination */
- if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
- DEBUG(0,("connect error: %s\n",strerror(errno)));
- close(res);
- return(-1);
+connect_again:
+ ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
+
+ if (ret < 0 && errno == EINPROGRESS && loops--) {
+ msleep(connect_loop);
+ goto connect_again;
}
+ if (ret < 0 && errno == EINPROGRESS) {
+ DEBUG(2,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
+ close(res);
+ return -1;
+ }
+
+ if (ret < 0) {
+ DEBUG(2,("error connecting to %s:%d (%s)\n",
+ inet_ntoa(*addr),port,strerror(errno)));
+ return -1;
+ }
+
+ /* set it blocking again */
+ set_blocking(res,1);
+
return res;
}
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 097e4f794a5..5b3fd19491d 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -357,17 +357,22 @@ static BOOL open_sockets(BOOL isdaemon, int port)
****************************************************************************/
static BOOL init_structs()
{
- if (!get_myname(myhostname,NULL))
- return(False);
+ extern fstring local_machine;
+ char *p;
if (! *myname) {
- char *p;
strcpy(myname,myhostname);
p = strchr(myname,'.');
if (p) *p = 0;
}
strupper(myname);
+ strcpy(local_machine,myname);
+ trim_string(local_machine," "," ");
+ p = strchr(local_machine,' ');
+ if (p) *p = 0;
+ strlower(local_machine);
+
return True;
}
@@ -479,11 +484,15 @@ static void usage(char *pname)
DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
+ get_myname(myhostname,NULL);
+
if (!reload_services(False))
return(-1);
init_structs();
+ reload_services(True);
+
set_samba_nb_type();
if (!is_daemon && !is_a_socket(0)) {
diff --git a/source/smbd/password.c b/source/smbd/password.c
index a5f597682f6..fd3ff4fd179 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -1287,7 +1287,7 @@ BOOL server_cryptkey(char *buf)
continue;
}
- password_client = open_socket_out(SOCK_STREAM, &dest_ip, port);
+ password_client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT);
if (password_client >= 0) {
DEBUG(3,("connected to password server %s\n",p));
StrnCpy(pserver,p,sizeof(pserver)-1);