--- smbd/server.orig 2006-11-10 15:52:14.000000000 -0800 +++ smbd/server.c 2006-11-10 17:21:28.000000000 -0800 @@ -228,16 +228,76 @@ Open the socket communication. ****************************************************************************/ +static BOOL parse_ports_and_listen(const int sock_addr, char* ports, fdset *listenset, int *fd_listenset, int *num_sockets) { +{ + + unsigned port; + + int s; + + fstring tok; + + while(next_token(&ports, tok, " \t,", sizeof(tok))) + { + + port = atoi(tok); + +/* + Isn't this effectively a waste of CPU cycles over the long term? or was it put here to purposely delay execution? + -Garrett + + if (port == 0) { + continue; + } +*/ + + s = open_socket_in(SOCK_STREAM, port, 0, sock_addr, True); + // "fd_listenset[num_sockets] = s" equivalent below + *(fd_listenset+(*num_sockets)) = s; + + if(s == -1) { + return False; + } + + /* ready to listen */ + set_socket_options(s, "SO_KEEPALIVE"); + set_socket_options(s, user_socket_options); + + /* Set server socket to non-blocking for the accept. */ + set_blocking(s,False); + + if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { + DEBUG(0,("listen: %s\n", strerror(errno))); + close(s); + return False; + } + + FD_SET(s, listen_set); + maxfd = MAX( maxfd, s); + + (*num_sockets)++; + + if (*num_sockets >= FD_SETSIZE) { + DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n")); + return False; + } + + } + + return True; + +} + + static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports) { + int num_interfaces = iface_count(); int num_sockets = 0; int fd_listenset[FD_SETSIZE]; fd_set listen_set; - int s; int maxfd = 0; int i; - char *ports; if (!is_daemon) { return open_sockets_inetd(); @@ -247,10 +307,12 @@ #ifdef HAVE_ATEXIT { static int atexit_set; + if(atexit_set == 0) { atexit_set=1; atexit(killkids); } + } #endif @@ -261,17 +323,23 @@ /* use a reasonable default set of ports - listing on 445 and 139 */ if (!smb_ports) { + ports = lp_smb_ports(); + if (!ports || !*ports) { ports = smb_xstrdup(SMB_PORTS); - } else { + } + else { ports = smb_xstrdup(ports); } + } else { ports = smb_xstrdup(smb_ports); } - if (lp_interfaces() && lp_bind_interfaces_only()) { + if (lp_interfaces() && lp_bind_interfaces_only()) + { + /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. @@ -279,102 +347,56 @@ /* Now open a listen socket for each of the interfaces. */ + + struct in_addr *ifip; + for(i = 0; i < num_interfaces; i++) { - struct in_addr *ifip = iface_n_ip(i); - fstring tok; - const char *ptr; + + ifip = iface_n_ip(i); if(ifip == NULL) { DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i)); continue; } - for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) { - unsigned port = atoi(tok); - if (port == 0) { - continue; - } - s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True); - if(s == -1) - return False; - - /* ready to listen */ - set_socket_options(s,"SO_KEEPALIVE"); - set_socket_options(s,user_socket_options); - - /* Set server socket to non-blocking for the accept. */ - set_blocking(s,False); - - if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { - DEBUG(0,("listen: %s\n",strerror(errno))); - close(s); - return False; - } - FD_SET(s,&listen_set); - maxfd = MAX( maxfd, s); - - num_sockets++; - if (num_sockets >= FD_SETSIZE) { - DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n")); - return False; - } + if(False == parse_addr_and_listen( ifip->s_addr, + &ports, + &listen_set, + &fd_listenset[0], + &num_sockets) + ) { + return False; } + } - } else { + + } + + else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ - fstring tok; - const char *ptr; - num_interfaces = 1; - - for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) { - unsigned port = atoi(tok); - if (port == 0) { - continue; - } - /* open an incoming socket */ - s = open_socket_in(SOCK_STREAM, port, 0, - interpret_addr(lp_socket_address()),True); - if (s == -1) - return(False); - - /* ready to listen */ - set_socket_options(s,"SO_KEEPALIVE"); - set_socket_options(s,user_socket_options); - - /* Set server socket to non-blocking for the accept. */ - set_blocking(s,False); - - if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { - DEBUG(0,("open_sockets_smbd: listen: %s\n", - strerror(errno))); - close(s); - return False; - } - - fd_listenset[num_sockets] = s; - FD_SET(s,&listen_set); - maxfd = MAX( maxfd, s); - - num_sockets++; - if (num_sockets >= FD_SETSIZE) { - DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n")); - return False; - } + if(False == parse_addr_and_listen( interpret_addr( lp_socket_address() ), + &ports, + &listen_set, + &fd_listenset[0], + &num_sockets) + ) { + return False; } + } SAFE_FREE(ports); - /* Listen to messages */ + /* Listen to messages */ - message_register(MSG_SMB_SAM_SYNC, msg_sam_sync); - message_register(MSG_SMB_SAM_REPL, msg_sam_repl); - message_register(MSG_SHUTDOWN, msg_exit_server); - message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed); + message_register(MSG_SMB_SAM_SYNC, msg_sam_sync); + message_register(MSG_SMB_SAM_REPL, msg_sam_repl); + message_register(MSG_SHUTDOWN, msg_exit_server); + message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed); message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated); #ifdef DEVELOPER @@ -384,7 +406,10 @@ /* now accept incoming connections - forking a new process for each incoming connection */ DEBUG(2,("waiting for a connection\n")); - while (1) { + + while (1) + { + fd_set lfds; int num; @@ -399,7 +424,9 @@ num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL); - if (num == -1 && errno == EINTR) { + if (num == -1 && errno == EINTR) + { + if (got_sig_term) { exit_server_cleanly(NULL); } @@ -412,7 +439,9 @@ reload_after_sighup = 0; } - continue; +// unnecessary delay.. +// continue; + } /* check if we need to reload services */ @@ -421,18 +450,24 @@ /* Find the sockets that are read-ready - accept on these. */ for( ; num > 0; num--) { + struct sockaddr addr; socklen_t in_addrlen = sizeof(addr); s = -1; + for(i = 0; i < num_sockets; i++) { - if(FD_ISSET(fd_listenset[i],&lfds)) { + + if(FD_ISSET(fd_listenset[i], &lfds)) { + s = fd_listenset[i]; /* Clear this so we don't look at it again. */ FD_CLR(fd_listenset[i],&lfds); break; + } + } smbd_set_server_fd(accept(s,&addr,&in_addrlen)); @@ -441,8 +476,7 @@ continue; if (smbd_server_fd() == -1) { - DEBUG(0,("open_sockets_smbd: accept: %s\n", - strerror(errno))); + DEBUG(0,("open_sockets_smbd: accept: %s\n", strerror(errno))); continue; } @@ -453,12 +487,13 @@ return True; if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) { + /* Child code ... */ /* close the listening socket(s) */ for(i = 0; i < num_sockets; i++) close(fd_listenset[i]); - + /* close our standard file descriptors */ close_low_fds(False);