r22495: Create wrapper to hide the details of obtaining a set of sockets
authorJames Peach <jpeach@samba.org>
Mon, 23 Apr 2007 22:17:06 +0000 (22:17 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:19:39 +0000 (12:19 -0500)
to listen on.

source/Makefile.in
source/smbd/server.c
source/smbd/sockinit.c [new file with mode: 0644]

index f8efbcd9275eb971a5e7bb032867fdb35da5fa20..c5db7023d6f64b67931141ad7651c9003ba0290a 100644 (file)
@@ -498,7 +498,8 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
               smbd/change_trust_pw.o smbd/fake_file.o \
               smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
               $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
-              smbd/dmapi.o lib/launchd.o $(MANGLE_OBJ) @VFS_STATIC@
+              smbd/dmapi.o lib/launchd.o smbd/sockinit.o \
+              $(MANGLE_OBJ) @VFS_STATIC@
 
 SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
                $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \
index 78f9779cfc35619bcdeec2bbe6d5e5d5cebdbda5..ee5d219b97cd00154994194aa12451c825d808ea 100644 (file)
@@ -22,7 +22,6 @@
 */
 
 #include "includes.h"
-#include "smb_launchd.h"
 
 static_decl_rpc;
 
@@ -298,153 +297,6 @@ static BOOL allowable_number_of_smbd_processes(void)
        return num_children < max_processes;
 }
 
-static int init_sockets_smbd(const char *smb_ports,
-                               int fd_listenset[FD_SETSIZE])
-{
-       int num_interfaces = iface_count();
-       char * ports;
-       int num_sockets = 0;
-       int i, s;
-
-       /* 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 {
-                       ports = smb_xstrdup(ports);
-               }
-       } else {
-               ports = smb_xstrdup(smb_ports);
-       }
-
-       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.
-               */
-               
-               /* Now open a listen socket for each of the
-                  interfaces. */
-               for(i = 0; i < num_interfaces; i++) {
-                       struct in_addr *ifip = iface_n_ip(i);
-                       fstring tok;
-                       const char *ptr;
-
-                       if(ifip == NULL) {
-                               DEBUG(0,("init_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 0;
-
-                               /* 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 0;
-                               }
-
-                               num_sockets++;
-                               if (num_sockets >= FD_SETSIZE) {
-                                       DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
-                                       return 0;
-                               }
-                       }
-               }
-       } 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 0;
-               
-                       /* 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,("init_sockets_smbd: listen: %s\n",
-                                        strerror(errno)));
-                               close(s);
-                               return 0;
-                       }
-
-                       fd_listenset[num_sockets] = s;
-                       num_sockets++;
-
-                       if (num_sockets >= FD_SETSIZE) {
-                               DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
-                               return 0;
-                       }
-               }
-       } 
-
-       SAFE_FREE(ports);
-       return num_sockets;
-}
-
-static int init_sockets_launchd(const struct smb_launch_info *linfo,
-                               const char * smb_ports,
-                               int fd_listenset[FD_SETSIZE])
-{
-       int num_sockets;
-       int i;
-
-       /* The launchd service configuration does not have to provide sockets,
-        * even though it's basically useless without it.
-        */
-       if (!linfo->num_sockets) {
-               return init_sockets_smbd(smb_ports, fd_listenset);
-       }
-
-       /* Make sure we don't get more sockets than we can handle. */
-       num_sockets = MIN(FD_SETSIZE, linfo->num_sockets);
-       memcpy(fd_listenset, linfo->socket_list, num_sockets * sizeof(int));
-
-       /* Get the sockets ready. This could be hoisted into
-        * open_sockets_smbd(), but the order of socket operations might
-        * matter for some platforms, so this approach seems less risky.
-        *      --jpeach
-        */
-       for (i = 0; i < num_sockets; ++i) {
-               set_socket_options(fd_listenset[i], "SO_KEEPALIVE");
-               set_socket_options(fd_listenset[i], user_socket_options);
-
-               /* Set server socket to non-blocking for the accept. */
-               set_blocking(fd_listenset[i], False);
-       }
-
-       return num_sockets;
-}
-
 /****************************************************************************
  Open the socket communication.
 ****************************************************************************/
@@ -458,7 +310,6 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
        int maxfd = 0;
        int i;
        struct timeval idle_timeout = {0, 0};
-       struct smb_launch_info linfo;
 
        if (server_mode == SERVER_MODE_INETD) {
                return open_sockets_inetd();
@@ -480,25 +331,9 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
        FD_ZERO(&listen_set);
 
        /* At this point, it doesn't matter what daemon mode we are in, we
-        * need some sockets to listen on. If we are in FOREGROUND mode,
-        * the launchd checkin might succeed. If we are in DAEMON or
-        * INTERACTIVE modes, it will fail and we will open the sockets
-        * ourselves.
+        * need some sockets to listen on.
         */
-       if (smb_launchd_checkin(&linfo)) {
-               /* We are running under launchd and launchd has
-                * opened some sockets for us.
-                */
-               num_sockets = init_sockets_launchd(&linfo,
-                                           smb_ports,
-                                           fd_listenset);
-               idle_timeout.tv_sec = linfo.idle_timeout_secs;
-               smb_launchd_checkout(&linfo);
-       } else {
-               num_sockets = init_sockets_smbd(smb_ports,
-                                           fd_listenset);
-       }
-
+       num_sockets = smbd_sockinit(smb_ports, fd_listenset, &idle_timeout);
        if (num_sockets == 0) {
                return False;
        }
diff --git a/source/smbd/sockinit.c b/source/smbd/sockinit.c
new file mode 100644 (file)
index 0000000..a4b9d63
--- /dev/null
@@ -0,0 +1,201 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Andrew Tridgell               1992-1998
+   Copyright (C) James Peach                   2007
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "smb_launchd.h"
+
+extern pstring user_socket_options;
+
+static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE])
+{
+       int num_interfaces = iface_count();
+       char * ports;
+       int num_sockets = 0;
+       int i, s;
+
+       /* 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 {
+                       ports = smb_xstrdup(ports);
+               }
+       } else {
+               ports = smb_xstrdup(smb_ports);
+       }
+
+       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.
+               */
+               
+               /* Now open a listen socket for each of the
+                  interfaces. */
+               for(i = 0; i < num_interfaces; i++) {
+                       struct in_addr *ifip = iface_n_ip(i);
+                       fstring tok;
+                       const char *ptr;
+
+                       if(ifip == NULL) {
+                               DEBUG(0,("init_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 = listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
+                               if(s == -1)
+                                       return 0;
+
+                               /* 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 0;
+                               }
+
+                               num_sockets++;
+                               if (num_sockets >= FD_SETSIZE) {
+                                       DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
+                                       return 0;
+                               }
+                       }
+               }
+       } 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 0;
+               
+                       /* 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,("init_sockets_smbd: listen: %s\n",
+                                        strerror(errno)));
+                               close(s);
+                               return 0;
+                       }
+
+                       listenset[num_sockets] = s;
+                       num_sockets++;
+
+                       if (num_sockets >= FD_SETSIZE) {
+                               DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
+                               return 0;
+                       }
+               }
+       } 
+
+       SAFE_FREE(ports);
+       return num_sockets;
+}
+
+static int init_sockets_launchd(const struct smb_launch_info *linfo,
+                               const char * smb_ports,
+                               int listenset[FD_SETSIZE])
+{
+       int num_sockets;
+       int i;
+
+       /* The launchd service configuration does not have to provide sockets,
+        * even though it's basically useless without it.
+        */
+       if (!linfo->num_sockets) {
+               return init_sockets_smbd(smb_ports, listenset);
+       }
+
+       /* Make sure we don't get more sockets than we can handle. */
+       num_sockets = MIN(FD_SETSIZE, linfo->num_sockets);
+       memcpy(listenset, linfo->socket_list, num_sockets * sizeof(int));
+
+       /* Get the sockets ready. This could be hoisted into
+        * open_sockets_smbd(), but the order of socket operations might
+        * matter for some platforms, so this approach seems less risky.
+        *      --jpeach
+        */
+       for (i = 0; i < num_sockets; ++i) {
+               set_socket_options(listenset[i], "SO_KEEPALIVE");
+               set_socket_options(listenset[i], user_socket_options);
+
+               /* Set server socket to non-blocking for the accept. */
+               set_blocking(listenset[i], False);
+       }
+
+       return num_sockets;
+}
+
+/* This function is responsible for opening (or retrieving) all the sockets we
+ * smbd will be listening on. It should apply all the configured socket options
+ * and return the number of valid sockets in listenset.
+ */
+int smbd_sockinit(const char *cmdline_ports, int listenset[FD_SETSIZE],
+                       struct timeval *idle)
+{
+       int num_sockets;
+       struct smb_launch_info linfo;
+
+       ZERO_STRUCTP(idle);
+
+       if (smb_launchd_checkin(&linfo)) {
+               /* We are running under launchd and launchd has
+                * opened some sockets for us.
+                */
+               num_sockets = init_sockets_launchd(&linfo,
+                                           cmdline_ports,
+                                           listenset);
+               idle->tv_sec = linfo.idle_timeout_secs;
+               smb_launchd_checkout(&linfo);
+       } else {
+               num_sockets = init_sockets_smbd(cmdline_ports,
+                                           listenset);
+       }
+
+       return num_sockets;
+}
+