r18918: - bail out with unsupported option to socket()
authorStefan Metzmacher <metze@samba.org>
Tue, 26 Sep 2006 13:15:31 +0000 (13:15 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:20:21 +0000 (14:20 -0500)
- don't reuse portnumbers in the autobind code
- use if (!...) return; logic instead of if (...) { do everything } return
  for swrap_close

metze
(This used to be commit 68a65aa4490c12ca70db335f928f3ac507902337)

source4/lib/socket_wrapper/socket_wrapper.c

index 6c23cebc813734e6925bbad63520e84cefccd2b8..224d521b30c089679166dcc6ed5791a3ae04e741 100644 (file)
@@ -470,7 +470,25 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
                errno = EAFNOSUPPORT;
                return -1;
        }
-       
+
+       switch (type) {
+       case SOCK_STREAM:
+               break;
+       case SOCK_DGRAM:
+               break;
+       default:
+               errno = EPROTONOSUPPORT;
+               return -1;
+       }
+
+       switch (protocol) {
+       case 0:
+               break;
+       default:
+               errno = EPROTONOSUPPORT;
+               return -1;
+       }
+
        fd = real_socket(AF_UNIX, type, 0);
 
        if (fd == -1) return -1;
@@ -557,6 +575,9 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
        return fd;
 }
 
+static int autobind_start_init;
+static int autobind_start;
+
 /* using sendto() or connect() on an unbound socket would give the
    recipient no way to reply, as unlike UDP and TCP, a unix domain
    socket can't auto-assign emphemeral port numbers, so we need to
@@ -570,7 +591,14 @@ static int swrap_auto_bind(struct socket_info *si)
        int ret;
        int port;
        struct stat st;
-       
+
+       if (autobind_start_init != 1) {
+               autobind_start_init = 1;
+               autobind_start = getpid();
+               autobind_start %= 50000;
+               autobind_start += 10000;
+       }
+
        un_addr.sun_family = AF_UNIX;
 
        switch (si->type) {
@@ -584,9 +612,13 @@ static int swrap_auto_bind(struct socket_info *si)
                errno = ESOCKTNOSUPPORT;
                return -1;
        }
-       
+
+       if (autobind_start > 60000) {
+               autobind_start = 10000;
+       }
+
        for (i=0;i<1000;i++) {
-               port = 10000 + i;
+               port = autobind_start + i;
                snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), 
                         "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
                         type, socket_wrapper_default_iface(), port);
@@ -597,13 +629,14 @@ static int swrap_auto_bind(struct socket_info *si)
 
                si->tmp_path = strdup(un_addr.sun_path);
                si->bound = 1;
+               autobind_start = port + 1;
                break;
        }
        if (i == 1000) {
                errno = ENFILE;
                return -1;
        }
-       
+
        memset(&in, 0, sizeof(in));
        in.sin_family = AF_INET;
        in.sin_port   = htons(port);
@@ -611,7 +644,6 @@ static int swrap_auto_bind(struct socket_info *si)
        
        si->myname_len = sizeof(in);
        si->myname = sockaddr_dup(&in, si->myname_len);
-       si->bound = 1;
        return 0;
 }
 
@@ -872,21 +904,24 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
 _PUBLIC_ int swrap_close(int fd)
 {
        struct socket_info *si = find_socket_info(fd);
+       int ret;
+
+       if (!si) {
+               return real_close(fd);
+       }
 
-       if (si) {
-               DLIST_REMOVE(sockets, si);
+       DLIST_REMOVE(sockets, si);
 
-               swrap_dump_packet(si, NULL, SWRAP_CLOSE, NULL, 0, 0);
+       ret = real_close(fd);
 
-               free(si->path);
-               free(si->myname);
-               free(si->peername);
-               if (si->tmp_path) {
-                       unlink(si->tmp_path);
-                       free(si->tmp_path);
-               }
-               free(si);
+       free(si->path);
+       free(si->myname);
+       free(si->peername);
+       if (si->tmp_path) {
+               unlink(si->tmp_path);
+               free(si->tmp_path);
        }
+       free(si);
 
-       return real_close(fd);
+       return ret;
 }