summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJames Peach <jpeach@samba.org>2007-04-23 22:17:06 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:19:39 -0500
commitc620832983d99205576b7885568221a1a576febe (patch)
treeebf3005a77aa9e85274b4ad9bb09b86084f7819b /source3/smbd
parent0845fa40853040c3ddb9d7a56fd756924f3369eb (diff)
downloadsamba-c620832983d99205576b7885568221a1a576febe.tar.gz
samba-c620832983d99205576b7885568221a1a576febe.tar.bz2
samba-c620832983d99205576b7885568221a1a576febe.zip
r22495: Create wrapper to hide the details of obtaining a set of sockets
to listen on. (This used to be commit 29a16b2acb8da604776d48c6a1e6163c9e868d12)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/server.c169
-rw-r--r--source3/smbd/sockinit.c201
2 files changed, 203 insertions, 167 deletions
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 78f9779cfc..ee5d219b97 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -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/source3/smbd/sockinit.c b/source3/smbd/sockinit.c
new file mode 100644
index 0000000000..a4b9d63810
--- /dev/null
+++ b/source3/smbd/sockinit.c
@@ -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;
+}
+