The branch, master has been updated
       via  a5d5457 socket_wrapper: use swrap_sendmsg_before()/after() in 
swrap_writev()
       via  e831376 socket_wrapper: use swrap_sendmsg_before()/after() in 
swrap_sendmsg()
       via  4a736f0 socket_wrapper: use swrap_sendmsg_before()/after() in 
swrap_send()
       via  a2db6b4 socket_wrapper: use swrap_sendmsg_before()/after() in 
swrap_sendto()
       via  8c6d7d7 socket_wrapper: add swrap_sendmsg_before/after helper 
functions
       via  c9ae810 socket_wrapper: replace recvmsg() correctly
       via  ec028b5 socket_wrapper: readv() should only work on connected 
sockets
       via  7bdc3db socket_wrapper: move swrap_ioctl() above the send*/recv* 
functions
       via  0ad8d45 socket_wrapper: fix compiler warnings
       via  e3c0d66 socket_wrapper: don't allow connect() to the broadcast 
address
      from  7b139a4 s3: Use dom_sid_string_buf in sid_to_fstring

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit a5d54579ea949f4cd7c975c3f5d0006a90777735
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Oct 30 16:23:49 2010 +0200

    socket_wrapper: use swrap_sendmsg_before()/after() in swrap_writev()
    
    metze
    
    Autobuild-User: Stefan Metzmacher <[email protected]>
    Autobuild-Date: Thu Mar  3 23:43:39 CET 2011 on sn-devel-104

commit e831376f914d729b9ff3f39c5841846359c712aa
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Oct 30 16:23:49 2010 +0200

    socket_wrapper: use swrap_sendmsg_before()/after() in swrap_sendmsg()
    
    This also adds the same logic for broadcast as in swrap_sendto()
    for SOCK_DGRAM.
    
    metze

commit 4a736f0fbe58fabf6c0a0650cbc38882cb0446ab
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Oct 30 16:23:49 2010 +0200

    socket_wrapper: use swrap_sendmsg_before()/after() in swrap_send()
    
    metze

commit a2db6b4dba2650c582aa4572276d96dac521a3d8
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Oct 30 16:23:49 2010 +0200

    socket_wrapper: use swrap_sendmsg_before()/after() in swrap_sendto()
    
    metze

commit 8c6d7d7b2797c051885e12e3cdf3da158cf4fe25
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Oct 30 16:08:49 2010 +0200

    socket_wrapper: add swrap_sendmsg_before/after helper functions
    
    Currently have almost the same logic in swrap_send(), swrap_sendto(),
    swrap_writev() and swrap_sendmsg(), this helper functions
    let combine all the logic in 2 places.
    
    metze

commit c9ae8102099ed66c776c79e88f1a582f3e213fbc
Author: Stefan Metzmacher <[email protected]>
Date:   Thu Mar 3 15:37:17 2011 +0100

    socket_wrapper: replace recvmsg() correctly
    
    metze

commit ec028b555bbca84e1f949c6632099f8407c0d695
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Oct 30 16:28:23 2010 +0200

    socket_wrapper: readv() should only work on connected sockets
    
    metze

commit 7bdc3db9ea5380eeee8d975b3579dcf673a0eafa
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Oct 30 16:19:33 2010 +0200

    socket_wrapper: move swrap_ioctl() above the send*/recv* functions
    
    metze

commit 0ad8d459c6f47a0d70c8af2b19e6585a38f34cb4
Author: Stefan Metzmacher <[email protected]>
Date:   Wed Mar 2 20:46:45 2011 +0100

    socket_wrapper: fix compiler warnings
    
    metze

commit e3c0d6611087184b37399df2bf04053c60c9f043
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Oct 30 16:07:31 2010 +0200

    socket_wrapper: don't allow connect() to the broadcast address
    
    This will simplify other code later.
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 lib/socket_wrapper/socket_wrapper.c |  655 +++++++++++++++++++++--------------
 lib/socket_wrapper/socket_wrapper.h |    6 +
 2 files changed, 398 insertions(+), 263 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/socket_wrapper/socket_wrapper.c 
b/lib/socket_wrapper/socket_wrapper.c
index 563c3a8..02cce3f 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -296,7 +296,7 @@ static int convert_un_in(const struct sockaddr_un *un, 
struct sockaddr *in, sock
        switch(type) {
        case SOCKET_TYPE_CHAR_TCP:
        case SOCKET_TYPE_CHAR_UDP: {
-               struct sockaddr_in *in2 = (struct sockaddr_in *)in;
+               struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
 
                if ((*len) < sizeof(*in2)) {
                    errno = EINVAL;
@@ -314,7 +314,7 @@ static int convert_un_in(const struct sockaddr_un *un, 
struct sockaddr *in, sock
 #ifdef HAVE_IPV6
        case SOCKET_TYPE_CHAR_TCP_V6:
        case SOCKET_TYPE_CHAR_UDP_V6: {
-               struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in;
+               struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
 
                if ((*len) < sizeof(*in2)) {
                        errno = EINVAL;
@@ -352,7 +352,7 @@ static int convert_in_un_remote(struct socket_info *si, 
const struct sockaddr *i
        switch (inaddr->sa_family) {
        case AF_INET: {
                const struct sockaddr_in *in = 
-                   (const struct sockaddr_in *)inaddr;
+                   (const struct sockaddr_in *)(const void *)inaddr;
                unsigned int addr = ntohl(in->sin_addr.s_addr);
                char u_type = '\0';
                char b_type = '\0';
@@ -395,8 +395,8 @@ static int convert_in_un_remote(struct socket_info *si, 
const struct sockaddr *i
 #ifdef HAVE_IPV6
        case AF_INET6: {
                const struct sockaddr_in6 *in = 
-                   (const struct sockaddr_in6 *)inaddr;
-               struct in6_addr cmp;
+                   (const struct sockaddr_in6 *)(const void *)inaddr;
+               struct in6_addr cmp1, cmp2;
 
                switch (si->type) {
                case SOCK_STREAM:
@@ -411,9 +411,10 @@ static int convert_in_un_remote(struct socket_info *si, 
const struct sockaddr *i
 
                prt = ntohs(in->sin6_port);
 
-               cmp = in->sin6_addr;
-               cmp.s6_addr[15] = 0;
-               if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
+               cmp1 = *swrap_ipv6();
+               cmp2 = in->sin6_addr;
+               cmp2.s6_addr[15] = 0;
+               if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
                        iface = in->sin6_addr.s6_addr[15];
                } else {
                        errno = ENETUNREACH;
@@ -460,7 +461,7 @@ static int convert_in_un_alloc(struct socket_info *si, 
const struct sockaddr *in
        switch (si->family) {
        case AF_INET: {
                const struct sockaddr_in *in = 
-                   (const struct sockaddr_in *)inaddr;
+                   (const struct sockaddr_in *)(const void *)inaddr;
                unsigned int addr = ntohl(in->sin_addr.s_addr);
                char u_type = '\0';
                char d_type = '\0';
@@ -511,8 +512,8 @@ static int convert_in_un_alloc(struct socket_info *si, 
const struct sockaddr *in
 #ifdef HAVE_IPV6
        case AF_INET6: {
                const struct sockaddr_in6 *in = 
-                   (const struct sockaddr_in6 *)inaddr;
-               struct in6_addr cmp;
+                   (const struct sockaddr_in6 *)(const void *)inaddr;
+               struct in6_addr cmp1, cmp2;
 
                switch (si->type) {
                case SOCK_STREAM:
@@ -527,11 +528,12 @@ static int convert_in_un_alloc(struct socket_info *si, 
const struct sockaddr *in
 
                prt = ntohs(in->sin6_port);
 
-               cmp = in->sin6_addr;
-               cmp.s6_addr[15] = 0;
+               cmp1 = *swrap_ipv6();
+               cmp2 = in->sin6_addr;
+               cmp2.s6_addr[15] = 0;
                if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
                        iface = socket_wrapper_default_iface();
-               } else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
+               } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
                        iface = in->sin6_addr.s6_addr[15];
                } else {
                        errno = EADDRNOTAVAIL;
@@ -1504,7 +1506,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, 
socklen_t *addrlen)
        memset(&un_addr, 0, sizeof(un_addr));
        memset(&un_my_addr, 0, sizeof(un_my_addr));
 
-       ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
+       ret = real_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
        if (ret == -1) {
                free(my_addr);
                return ret;
@@ -1542,7 +1544,8 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, 
socklen_t *addrlen)
            *addrlen = 0;
        }
 
-       ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, 
&un_my_addrlen);
+       ret = real_getsockname(fd, (struct sockaddr *)(void *)&un_my_addr,
+                              &un_my_addrlen);
        if (ret == -1) {
                free(child_si);
                close(fd);
@@ -1670,7 +1673,8 @@ static int swrap_auto_bind(struct socket_info *si, int 
family)
                         type, socket_wrapper_default_iface(), port);
                if (stat(un_addr.sun_path, &st) == 0) continue;
 
-               ret = real_bind(si->fd, (struct sockaddr *)&un_addr, 
sizeof(un_addr));
+               ret = real_bind(si->fd, (struct sockaddr *)(void *)&un_addr,
+                               sizeof(un_addr));
                if (ret == -1) return ret;
 
                si->tmp_path = strdup(un_addr.sun_path);
@@ -1695,6 +1699,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr 
*serv_addr, socklen_t ad
        int ret;
        struct sockaddr_un un_addr;
        struct socket_info *si = find_socket_info(s);
+       int bcast = 0;
 
        if (!si) {
                return real_connect(s, serv_addr, addrlen);
@@ -1710,16 +1715,22 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr 
*serv_addr, socklen_t ad
                return -1;
        }
 
-       ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, 
addrlen, &un_addr, 0, NULL);
+       ret = sockaddr_convert_to_un(si, serv_addr,
+                                    addrlen, &un_addr, 0, &bcast);
        if (ret == -1) return -1;
 
+       if (bcast) {
+               errno = ENETUNREACH;
+               return -1;
+       }
+
        if (si->type == SOCK_DGRAM) {
                si->defer_connect = 1;
                ret = 0;
        } else {
                swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
 
-               ret = real_connect(s, (struct sockaddr *)&un_addr,
+               ret = real_connect(s, (struct sockaddr *)(void *)&un_addr,
                                   sizeof(struct sockaddr_un));
        }
 
@@ -1755,12 +1766,12 @@ _PUBLIC_ int swrap_bind(int s, const struct sockaddr 
*myaddr, socklen_t addrlen)
        si->myname_len = addrlen;
        si->myname = sockaddr_dup(myaddr, addrlen);
 
-       ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, 
addrlen, &un_addr, 1, &si->bcast);
+       ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, 
&si->bcast);
        if (ret == -1) return -1;
 
        unlink(un_addr.sun_path);
 
-       ret = real_bind(s, (struct sockaddr *)&un_addr,
+       ret = real_bind(s, (struct sockaddr *)(void *)&un_addr,
                        sizeof(struct sockaddr_un));
 
        if (ret == 0) {
@@ -1859,180 +1870,325 @@ _PUBLIC_ int swrap_setsockopt(int s, int  level,  int 
 optname,  const  void  *o
        }
 }
 
-_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, 
struct sockaddr *from, socklen_t *fromlen)
+_PUBLIC_ int swrap_ioctl(int s, int r, void *p)
 {
-       struct sockaddr_un un_addr;
-       socklen_t un_addrlen = sizeof(un_addr);
        int ret;
        struct socket_info *si = find_socket_info(s);
-       struct sockaddr_storage ss;
-       socklen_t ss_len = sizeof(ss);
+       int value;
 
        if (!si) {
-               return real_recvfrom(s, buf, len, flags, from, fromlen);
-       }
-
-       if (!from) {
-               from = (struct sockaddr *)&ss;
-               fromlen = &ss_len;
-       }
-
-       if (si->type == SOCK_STREAM) {
-               /* cut down to 1500 byte packets for stream sockets,
-                * which makes it easier to format PCAP capture files
-                * (as the caller will simply continue from here) */
-               len = MIN(len, 1500);
+               return real_ioctl(s, r, p);
        }
 
-       /* irix 6.4 forgets to null terminate the sun_path string :-( */
-       memset(&un_addr, 0, sizeof(un_addr));
-       ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, 
&un_addrlen);
-       if (ret == -1) 
-               return ret;
+       ret = real_ioctl(s, r, p);
 
-       if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
-                                    si->family, from, fromlen) == -1) {
-               return -1;
+       switch (r) {
+       case FIONREAD:
+               value = *((int *)p);
+               if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
+                       swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
+               } else if (value == 0) { /* END OF FILE */
+                       swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
+               }
+               break;
        }
 
-       swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
-
        return ret;
 }
 
-
-_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, 
const struct sockaddr *to, socklen_t tolen)
+static ssize_t swrap_sendmsg_before(struct socket_info *si,
+                                   struct msghdr *msg,
+                                   struct iovec *tmp_iov,
+                                   struct sockaddr_un *tmp_un,
+                                   const struct sockaddr_un **to_un,
+                                   const struct sockaddr **to,
+                                   int *bcast)
 {
-       struct sockaddr_un un_addr;
-       int ret;
-       struct socket_info *si = find_socket_info(s);
-       int bcast = 0;
+       size_t i, len = 0;
+       ssize_t ret;
 
-       if (!si) {
-               return real_sendto(s, buf, len, flags, to, tolen);
+       if (to_un) {
+               *to_un = NULL;
+       }
+       if (to) {
+               *to = NULL;
+       }
+       if (bcast) {
+               *bcast = 0;
        }
 
-       if (si->connected) {
-               if (to) {
-                       errno = EISCONN;
+       switch (si->type) {
+       case SOCK_STREAM:
+               if (!si->connected) {
+                       errno = ENOTCONN;
                        return -1;
                }
 
-               to = si->peername;
-               tolen = si->peername_len;
-       }
+               if (msg->msg_iovlen == 0) {
+                       break;
+               }
 
-       switch (si->type) {
-       case SOCK_STREAM:
-               /* cut down to 1500 byte packets for stream sockets,
+               /*
+                * cut down to 1500 byte packets for stream sockets,
                 * which makes it easier to format PCAP capture files
-                * (as the caller will simply continue from here) */
-               len = MIN(len, 1500);
+                * (as the caller will simply continue from here)
+                */
 
-               ret = real_send(s, buf, len, flags);
+               for (i=0; i < msg->msg_iovlen; i++) {
+                       size_t nlen;
+                       nlen = len + msg->msg_iov[i].iov_len;
+                       if (nlen > 1500) {
+                               break;
+                       }
+               }
+               msg->msg_iovlen = i;
+               if (msg->msg_iovlen == 0) {
+                       *tmp_iov = msg->msg_iov[0];
+                       tmp_iov->iov_len = MIN(tmp_iov->iov_len, 1500);
+                       msg->msg_iov = tmp_iov;
+                       msg->msg_iovlen = 1;
+               }
                break;
+
        case SOCK_DGRAM:
+               if (si->connected) {
+                       if (msg->msg_name) {
+                               errno = EISCONN;
+                               return -1;
+                       }
+               } else {
+                       const struct sockaddr *msg_name;
+                       msg_name = (const struct sockaddr *)msg->msg_name;
+
+                       if (msg_name == NULL) {
+                               errno = ENOTCONN;
+                               return -1;
+                       }
+
+
+                       ret = sockaddr_convert_to_un(si, msg_name, 
msg->msg_namelen,
+                                                    tmp_un, 0, bcast);
+                       if (ret == -1) return -1;
+
+                       if (to_un) {
+                               *to_un = tmp_un;
+                       }
+                       if (to) {
+                               *to = msg_name;
+                       }
+                       msg->msg_name = tmp_un;
+                       msg->msg_namelen = sizeof(*tmp_un);
+               }
+
                if (si->bound == 0) {
                        ret = swrap_auto_bind(si, si->family);
                        if (ret == -1) return -1;
                }
 
-               ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, 
&bcast);
+               if (!si->defer_connect) {
+                       break;
+               }
+
+               ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
+                                            tmp_un, 0, NULL);
                if (ret == -1) return -1;
 
-               if (bcast) {
-                       struct stat st;
-                       unsigned int iface;
-                       unsigned int prt = ntohs(((const struct sockaddr_in 
*)to)->sin_port);
-                       char type;
+               ret = real_connect(si->fd, (struct sockaddr *)(void *)tmp_un,
+                                  sizeof(*tmp_un));
 
-                       type = SOCKET_TYPE_CHAR_UDP;
+               /* to give better errors */
+               if (ret == -1 && errno == ENOENT) {
+                       errno = EHOSTUNREACH;
+               }
 
-                       for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
-                               snprintf(un_addr.sun_path, 
sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, 
-                                        socket_wrapper_dir(), type, iface, 
prt);
-                               if (stat(un_addr.sun_path, &st) != 0) continue;
+               if (ret == -1) {
+                       return ret;
+               }
 
-                               /* ignore the any errors in broadcast sends */
-                               real_sendto(s, buf, len, flags, (struct 
sockaddr *)&un_addr, sizeof(un_addr));
-                       }
+               si->defer_connect = 0;
+               break;
+       default:
+               errno = EHOSTUNREACH;
+               return -1;
+       }
 
-                       swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
+       return 0;
+}
 
-                       return len;
-               }
+static void swrap_sendmsg_after(struct socket_info *si,
+                               struct msghdr *msg,
+                               const struct sockaddr *to,
+                               ssize_t ret)
+{
+       int saved_errno = errno;
+       size_t i, len = 0;
+       uint8_t *buf;
+       off_t ofs = 0;
+       size_t avail = 0;
+       size_t remain;
 
-               if (si->defer_connect) {
-                       ret = real_connect(s, (struct sockaddr *)&un_addr,
-                                          sizeof(un_addr));
+       /* to give better errors */
+       if (ret == -1 && saved_errno == ENOENT) {
+               saved_errno = EHOSTUNREACH;
+       }
 
-                       /* to give better errors */
-                       if (ret == -1 && errno == ENOENT) {
-                               errno = EHOSTUNREACH;
-                       }
+       for (i=0; i < msg->msg_iovlen; i++) {
+               avail += msg->msg_iov[i].iov_len;
+       }
 
-                       if (ret == -1) {
-                               return ret;
-                       }
-                       si->defer_connect = 0;
+       if (ret == -1) {
+               remain = MIN(80, avail);
+       } else {
+               remain = ret;
+       }
+
+       /* we capture it as one single packet */
+       buf = (uint8_t *)malloc(remain);
+       if (!buf) {
+               /* we just not capture the packet */
+               errno = saved_errno;
+               return;
+       }
+
+       for (i=0; i < msg->msg_iovlen; i++) {
+               size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
+               memcpy(buf + ofs,
+                      msg->msg_iov[i].iov_base,
+                      this_time);
+               ofs += this_time;
+               remain -= this_time;
+       }
+       len = ofs;
+
+       switch (si->type) {
+       case SOCK_STREAM:
+               if (ret == -1) {
+                       swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
+                       swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
+               } else {
+                       swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
                }
+               break;
 
-               /* Man page for Linux says:
-                * "the error EISONN may be returned when they are not NULL and 
0"
-                * But in practice it's not on x86/amd64, but on other unix it 
is
-                * (ie. freebsd)
-                * So if we are already connected we send NULL/0
-                */
+       case SOCK_DGRAM:
                if (si->connected) {
-                       ret = real_sendto(s, buf, len, flags, NULL, 0);
+                       to = si->peername;
+               }
+               if (ret == -1) {
+                       swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
+                       swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, 
len);
                } else {
-                       ret = real_sendto(s, buf, len, flags, (struct sockaddr 
*)&un_addr, sizeof(un_addr));
+                       swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
                }
                break;
-       default:
-               ret = -1;
-               errno = EHOSTUNREACH;
-               break;
        }
 
-       /* to give better errors */
-       if (ret == -1 && errno == ENOENT) {
-               errno = EHOSTUNREACH;
+       free(buf);
+       errno = saved_errno;
+}
+
+_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, 
struct sockaddr *from, socklen_t *fromlen)
+{
+       struct sockaddr_un un_addr;
+       socklen_t un_addrlen = sizeof(un_addr);
+       int ret;
+       struct socket_info *si = find_socket_info(s);
+       struct sockaddr_storage ss;
+       socklen_t ss_len = sizeof(ss);
+
+       if (!si) {
+               return real_recvfrom(s, buf, len, flags, from, fromlen);
        }
 
-       if (ret == -1) {
-               swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
-               swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
-       } else {
-               swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret);
+       if (!from) {


-- 
Samba Shared Repository

Reply via email to