The branch, master has been updated
       via  3679e8243459f928b1a4d0998d47c6efdedd0301 (commit)
       via  f9156f6c77d9e87edc153b024a1d564b44eedd8f (commit)
       via  81e2633e41e9c8c1dddff7cc1122c7d6f28626bd (commit)
      from  dea9621680062b3726ad15cbec4a9d2cf7ce824e (commit)

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


- Log -----------------------------------------------------------------
commit 3679e8243459f928b1a4d0998d47c6efdedd0301
Author: Stefan Metzmacher <[email protected]>
Date:   Sun Mar 8 17:20:18 2009 +0100

    socket_wrapper: downgrade ipv6 sockets to ipv4 is in connect() if the dest 
is ipv4
    
    We only do this if the socket isn't explicit bound yet.
    
    metze

commit f9156f6c77d9e87edc153b024a1d564b44eedd8f
Author: Stefan Metzmacher <[email protected]>
Date:   Sun Mar 8 17:19:50 2009 +0100

    socket_wrapper: correctly handle connected dgram sockets
    
    metze

commit 81e2633e41e9c8c1dddff7cc1122c7d6f28626bd
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Mar 3 19:40:57 2009 +0100

    socket_wrapper: make it possible to bind to '::'
    
    metze

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

Summary of changes:
 lib/socket_wrapper/socket_wrapper.c |   48 ++++++++++++++++++++++++++++++----
 1 files changed, 42 insertions(+), 6 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/socket_wrapper/socket_wrapper.c 
b/lib/socket_wrapper/socket_wrapper.c
index 8ad9e1d..733a332 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -202,6 +202,7 @@ struct socket_info
        int bound;
        int bcast;
        int is_server;
+       int connected;
 
        char *path;
        char *tmp_path;
@@ -510,7 +511,9 @@ static int convert_in_un_alloc(struct socket_info *si, 
const struct sockaddr *in
 
                cmp = in->sin6_addr;
                cmp.s6_addr[15] = 0;
-               if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) {
+               if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
+                       iface = socket_wrapper_default_iface();
+               } else if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) {
                        iface = in->sin6_addr.s6_addr[15];
                } else {
                        errno = EADDRNOTAVAIL;
@@ -1485,6 +1488,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, 
socklen_t *addrlen)
        child_si->protocol = parent_si->protocol;
        child_si->bound = 1;
        child_si->is_server = 1;
+       child_si->connected = 1;
 
        child_si->peername_len = len;
        child_si->peername = sockaddr_dup(my_addr, len);
@@ -1532,8 +1536,10 @@ 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
-   assign it here */
-static int swrap_auto_bind(struct socket_info *si)
+   assign it here.
+   Note: this might change the family from ipv6 to ipv4
+*/
+static int swrap_auto_bind(struct socket_info *si, int family)
 {
        struct sockaddr_un un_addr;
        int i;
@@ -1551,7 +1557,7 @@ static int swrap_auto_bind(struct socket_info *si)
 
        un_addr.sun_family = AF_UNIX;
 
-       switch (si->family) {
+       switch (family) {
        case AF_INET: {
                struct sockaddr_in in;
 
@@ -1580,6 +1586,11 @@ static int swrap_auto_bind(struct socket_info *si)
        case AF_INET6: {
                struct sockaddr_in6 in6;
 
+               if (si->family != family) {
+                       errno = ENETUNREACH;
+                       return -1;
+               }
+
                switch (si->type) {
                case SOCK_STREAM:
                        type = SOCKET_TYPE_CHAR_TCP_V6;
@@ -1630,6 +1641,7 @@ static int swrap_auto_bind(struct socket_info *si)
                return -1;
        }
 
+       si->family = family;
        set_port(si->family, port, si->myname);
 
        return 0;
@@ -1647,7 +1659,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr 
*serv_addr, socklen_t ad
        }
 
        if (si->bound == 0) {
-               ret = swrap_auto_bind(si);
+               ret = swrap_auto_bind(si, serv_addr->sa_family);
                if (ret == -1) return -1;
        }
 
@@ -1672,7 +1684,14 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr 
*serv_addr, socklen_t ad
        if (ret == 0) {
                si->peername_len = addrlen;
                si->peername = sockaddr_dup(serv_addr, addrlen);
+               si->connected = 1;
+       }
 
+       if (si->type != SOCK_STREAM) {
+               return ret;
+       }
+
+       if (ret == 0) {
                swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
                swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
        } else {
@@ -1801,11 +1820,18 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, 
size_t len, int flags, struct
        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 (!from) {
+               from = (struct sockaddr *)&ss;
+               fromlen = &ss_len;
+       }
+
        len = MIN(len, 1500);
 
        /* irix 6.4 forgets to null terminate the sun_path string :-( */
@@ -1836,6 +1862,16 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, 
size_t len, int flags, con
                return real_sendto(s, buf, len, flags, to, tolen);
        }
 
+       if (si->connected) {
+               if (to) {
+                       errno = EISCONN;
+                       return -1;
+               }
+
+               to = si->peername;
+               tolen = si->peername_len;
+       }
+
        len = MIN(len, 1500);
 
        switch (si->type) {
@@ -1844,7 +1880,7 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, 
size_t len, int flags, con
                break;
        case SOCK_DGRAM:
                if (si->bound == 0) {
-                       ret = swrap_auto_bind(si);
+                       ret = swrap_auto_bind(si, si->family);
                        if (ret == -1) return -1;
                }
                


-- 
Samba Shared Repository

Reply via email to