Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
1 deleted
4 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/lib/socket_wrapper/socket_wrapper.c

    r414 r745  
    297297        case SOCKET_TYPE_CHAR_TCP:
    298298        case SOCKET_TYPE_CHAR_UDP: {
    299                 struct sockaddr_in *in2 = (struct sockaddr_in *)in;
    300                
     299                struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
     300
    301301                if ((*len) < sizeof(*in2)) {
    302302                    errno = EINVAL;
     
    315315        case SOCKET_TYPE_CHAR_TCP_V6:
    316316        case SOCKET_TYPE_CHAR_UDP_V6: {
    317                 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in;
    318                
     317                struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
     318
    319319                if ((*len) < sizeof(*in2)) {
    320320                        errno = EINVAL;
     
    353353        case AF_INET: {
    354354                const struct sockaddr_in *in =
    355                     (const struct sockaddr_in *)inaddr;
     355                    (const struct sockaddr_in *)(const void *)inaddr;
    356356                unsigned int addr = ntohl(in->sin_addr.s_addr);
    357357                char u_type = '\0';
     
    396396        case AF_INET6: {
    397397                const struct sockaddr_in6 *in =
    398                     (const struct sockaddr_in6 *)inaddr;
    399                 struct in6_addr cmp;
     398                    (const struct sockaddr_in6 *)(const void *)inaddr;
     399                struct in6_addr cmp1, cmp2;
    400400
    401401                switch (si->type) {
     
    412412                prt = ntohs(in->sin6_port);
    413413
    414                 cmp = in->sin6_addr;
    415                 cmp.s6_addr[15] = 0;
    416                 if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
     414                cmp1 = *swrap_ipv6();
     415                cmp2 = in->sin6_addr;
     416                cmp2.s6_addr[15] = 0;
     417                if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
    417418                        iface = in->sin6_addr.s6_addr[15];
    418419                } else {
     
    461462        case AF_INET: {
    462463                const struct sockaddr_in *in =
    463                     (const struct sockaddr_in *)inaddr;
     464                    (const struct sockaddr_in *)(const void *)inaddr;
    464465                unsigned int addr = ntohl(in->sin_addr.s_addr);
    465466                char u_type = '\0';
     
    512513        case AF_INET6: {
    513514                const struct sockaddr_in6 *in =
    514                     (const struct sockaddr_in6 *)inaddr;
    515                 struct in6_addr cmp;
     515                    (const struct sockaddr_in6 *)(const void *)inaddr;
     516                struct in6_addr cmp1, cmp2;
    516517
    517518                switch (si->type) {
     
    528529                prt = ntohs(in->sin6_port);
    529530
    530                 cmp = in->sin6_addr;
    531                 cmp.s6_addr[15] = 0;
     531                cmp1 = *swrap_ipv6();
     532                cmp2 = in->sin6_addr;
     533                cmp2.s6_addr[15] = 0;
    532534                if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
    533535                        iface = socket_wrapper_default_iface();
    534                 } else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
     536                } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
    535537                        iface = in->sin6_addr.s6_addr[15];
    536538                } else {
     
    585587                                  struct sockaddr_un *out_addr, int alloc_sock, int *bcast)
    586588{
     589        struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
    587590        if (!out_addr)
    588591                return 0;
    589592
    590         out_addr->sun_family = AF_UNIX;
     593        out->sa_family = AF_UNIX;
     594#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
     595        out->sa_len = sizeof(*out_addr);
     596#endif
    591597
    592598        switch (in_addr->sa_family) {
     
    611617                break;
    612618        }
    613        
     619
    614620        errno = EAFNOSUPPORT;
    615621        return -1;
     
    623629                                    socklen_t *out_addrlen)
    624630{
     631        int ret;
     632
    625633        if (out_addr == NULL || out_addrlen == NULL)
    626634                return 0;
     
    644652                        return -1;
    645653                }
    646                 return convert_un_in(in_addr, out_addr, out_addrlen);
     654                ret = convert_un_in(in_addr, out_addr, out_addrlen);
     655#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
     656                out_addr->sa_len = *out_addrlen;
     657#endif
     658                return ret;
    647659        default:
    648660                break;
     
    960972                ip->v6.flow_label_high  = 0x00;
    961973                ip->v6.flow_label_low   = 0x0000;
    962                 ip->v6.payload_length   = htons(wire_len - icmp_truncate_len);//TODO
     974                ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
    963975                ip->v6.next_header      = protocol;
    964976                memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
     
    10101022                        ip->v6.flow_label_high  = 0x00;
    10111023                        ip->v6.flow_label_low   = 0x0000;
    1012                         ip->v6.payload_length   = htons(wire_len - icmp_truncate_len);//TODO
     1024                        ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
    10131025                        ip->v6.next_header      = protocol;
    10141026                        memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
     
    14951507        memset(&un_my_addr, 0, sizeof(un_my_addr));
    14961508
    1497         ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
     1509        ret = real_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
    14981510        if (ret == -1) {
    14991511                free(my_addr);
     
    15271539
    15281540        if (addr != NULL && addrlen != NULL) {
    1529             *addrlen = len;
    1530             if (*addrlen >= len)
    1531                 memcpy(addr, my_addr, len);
    1532             *addrlen = 0;
    1533         }
    1534 
    1535         ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
     1541                size_t copy_len = MIN(*addrlen, len);
     1542                if (copy_len > 0) {
     1543                        memcpy(addr, my_addr, copy_len);
     1544                }
     1545                *addrlen = len;
     1546        }
     1547
     1548        ret = real_getsockname(fd, (struct sockaddr *)(void *)&un_my_addr,
     1549                               &un_my_addrlen);
    15361550        if (ret == -1) {
    15371551                free(child_si);
     
    16601674                         type, socket_wrapper_default_iface(), port);
    16611675                if (stat(un_addr.sun_path, &st) == 0) continue;
    1662                
    1663                 ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr));
     1676
     1677                ret = real_bind(si->fd, (struct sockaddr *)(void *)&un_addr,
     1678                                sizeof(un_addr));
    16641679                if (ret == -1) return ret;
    16651680
     
    16861701        struct sockaddr_un un_addr;
    16871702        struct socket_info *si = find_socket_info(s);
     1703        int bcast = 0;
    16881704
    16891705        if (!si) {
     
    17011717        }
    17021718
    1703         ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL);
     1719        ret = sockaddr_convert_to_un(si, serv_addr,
     1720                                     addrlen, &un_addr, 0, &bcast);
    17041721        if (ret == -1) return -1;
     1722
     1723        if (bcast) {
     1724                errno = ENETUNREACH;
     1725                return -1;
     1726        }
    17051727
    17061728        if (si->type == SOCK_DGRAM) {
     
    17101732                swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
    17111733
    1712                 ret = real_connect(s, (struct sockaddr *)&un_addr,
     1734                ret = real_connect(s, (struct sockaddr *)(void *)&un_addr,
    17131735                                   sizeof(struct sockaddr_un));
    17141736        }
     
    17461768        si->myname = sockaddr_dup(myaddr, addrlen);
    17471769
    1748         ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast);
     1770        ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
    17491771        if (ret == -1) return -1;
    17501772
    17511773        unlink(un_addr.sun_path);
    17521774
    1753         ret = real_bind(s, (struct sockaddr *)&un_addr,
     1775        ret = real_bind(s, (struct sockaddr *)(void *)&un_addr,
    17541776                        sizeof(struct sockaddr_un));
    17551777
     
    18481870                return -1;
    18491871        }
    1850 }
    1851 
    1852 _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
    1853 {
    1854         struct sockaddr_un un_addr;
    1855         socklen_t un_addrlen = sizeof(un_addr);
    1856         int ret;
    1857         struct socket_info *si = find_socket_info(s);
    1858         struct sockaddr_storage ss;
    1859         socklen_t ss_len = sizeof(ss);
    1860 
    1861         if (!si) {
    1862                 return real_recvfrom(s, buf, len, flags, from, fromlen);
    1863         }
    1864 
    1865         if (!from) {
    1866                 from = (struct sockaddr *)&ss;
    1867                 fromlen = &ss_len;
    1868         }
    1869 
    1870         if (si->type == SOCK_STREAM) {
    1871                 /* cut down to 1500 byte packets for stream sockets,
    1872                  * which makes it easier to format PCAP capture files
    1873                  * (as the caller will simply continue from here) */
    1874                 len = MIN(len, 1500);
    1875         }
    1876 
    1877         /* irix 6.4 forgets to null terminate the sun_path string :-( */
    1878         memset(&un_addr, 0, sizeof(un_addr));
    1879         ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen);
    1880         if (ret == -1)
    1881                 return ret;
    1882 
    1883         if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
    1884                                      si->family, from, fromlen) == -1) {
    1885                 return -1;
    1886         }
    1887 
    1888         swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
    1889 
    1890         return ret;
    1891 }
    1892 
    1893 
    1894 _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
    1895 {
    1896         struct sockaddr_un un_addr;
    1897         int ret;
    1898         struct socket_info *si = find_socket_info(s);
    1899         int bcast = 0;
    1900 
    1901         if (!si) {
    1902                 return real_sendto(s, buf, len, flags, to, tolen);
    1903         }
    1904 
    1905         if (si->connected) {
    1906                 if (to) {
    1907                         errno = EISCONN;
    1908                         return -1;
    1909                 }
    1910 
    1911                 to = si->peername;
    1912                 tolen = si->peername_len;
    1913         }
    1914 
    1915         switch (si->type) {
    1916         case SOCK_STREAM:
    1917                 /* cut down to 1500 byte packets for stream sockets,
    1918                  * which makes it easier to format PCAP capture files
    1919                  * (as the caller will simply continue from here) */
    1920                 len = MIN(len, 1500);
    1921        
    1922                 ret = real_send(s, buf, len, flags);
    1923                 break;
    1924         case SOCK_DGRAM:
    1925                 if (si->bound == 0) {
    1926                         ret = swrap_auto_bind(si, si->family);
    1927                         if (ret == -1) return -1;
    1928                 }
    1929                
    1930                 ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast);
    1931                 if (ret == -1) return -1;
    1932                
    1933                 if (bcast) {
    1934                         struct stat st;
    1935                         unsigned int iface;
    1936                         unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
    1937                         char type;
    1938                        
    1939                         type = SOCKET_TYPE_CHAR_UDP;
    1940                        
    1941                         for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
    1942                                 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
    1943                                          socket_wrapper_dir(), type, iface, prt);
    1944                                 if (stat(un_addr.sun_path, &st) != 0) continue;
    1945                                
    1946                                 /* ignore the any errors in broadcast sends */
    1947                                 real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
    1948                         }
    1949                        
    1950                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
    1951                        
    1952                         return len;
    1953                 }
    1954 
    1955                 if (si->defer_connect) {
    1956                         ret = real_connect(s, (struct sockaddr *)&un_addr,
    1957                                            sizeof(un_addr));
    1958 
    1959                         /* to give better errors */
    1960                         if (ret == -1 && errno == ENOENT) {
    1961                                 errno = EHOSTUNREACH;
    1962                         }
    1963 
    1964                         if (ret == -1) {
    1965                                 return ret;
    1966                         }
    1967                         si->defer_connect = 0;
    1968                 }
    1969 
    1970                 ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
    1971                 break;
    1972         default:
    1973                 ret = -1;
    1974                 errno = EHOSTUNREACH;
    1975                 break;
    1976         }
    1977                
    1978         /* to give better errors */
    1979         if (ret == -1 && errno == ENOENT) {
    1980                 errno = EHOSTUNREACH;
    1981         }
    1982 
    1983         if (ret == -1) {
    1984                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
    1985                 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
    1986         } else {
    1987                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret);
    1988         }
    1989 
    1990         return ret;
    19911872}
    19921873
     
    20171898}
    20181899
     1900static ssize_t swrap_sendmsg_before(struct socket_info *si,
     1901                                    struct msghdr *msg,
     1902                                    struct iovec *tmp_iov,
     1903                                    struct sockaddr_un *tmp_un,
     1904                                    const struct sockaddr_un **to_un,
     1905                                    const struct sockaddr **to,
     1906                                    int *bcast)
     1907{
     1908        size_t i, len = 0;
     1909        ssize_t ret;
     1910
     1911        if (to_un) {
     1912                *to_un = NULL;
     1913        }
     1914        if (to) {
     1915                *to = NULL;
     1916        }
     1917        if (bcast) {
     1918                *bcast = 0;
     1919        }
     1920
     1921        switch (si->type) {
     1922        case SOCK_STREAM:
     1923                if (!si->connected) {
     1924                        errno = ENOTCONN;
     1925                        return -1;
     1926                }
     1927
     1928                if (msg->msg_iovlen == 0) {
     1929                        break;
     1930                }
     1931
     1932                /*
     1933                 * cut down to 1500 byte packets for stream sockets,
     1934                 * which makes it easier to format PCAP capture files
     1935                 * (as the caller will simply continue from here)
     1936                 */
     1937
     1938                for (i=0; i < msg->msg_iovlen; i++) {
     1939                        size_t nlen;
     1940                        nlen = len + msg->msg_iov[i].iov_len;
     1941                        if (nlen > 1500) {
     1942                                break;
     1943                        }
     1944                }
     1945                msg->msg_iovlen = i;
     1946                if (msg->msg_iovlen == 0) {
     1947                        *tmp_iov = msg->msg_iov[0];
     1948                        tmp_iov->iov_len = MIN(tmp_iov->iov_len, 1500);
     1949                        msg->msg_iov = tmp_iov;
     1950                        msg->msg_iovlen = 1;
     1951                }
     1952                break;
     1953
     1954        case SOCK_DGRAM:
     1955                if (si->connected) {
     1956                        if (msg->msg_name) {
     1957                                errno = EISCONN;
     1958                                return -1;
     1959                        }
     1960                } else {
     1961                        const struct sockaddr *msg_name;
     1962                        msg_name = (const struct sockaddr *)msg->msg_name;
     1963
     1964                        if (msg_name == NULL) {
     1965                                errno = ENOTCONN;
     1966                                return -1;
     1967                        }
     1968
     1969
     1970                        ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
     1971                                                     tmp_un, 0, bcast);
     1972                        if (ret == -1) return -1;
     1973
     1974                        if (to_un) {
     1975                                *to_un = tmp_un;
     1976                        }
     1977                        if (to) {
     1978                                *to = msg_name;
     1979                        }
     1980                        msg->msg_name = tmp_un;
     1981                        msg->msg_namelen = sizeof(*tmp_un);
     1982                }
     1983
     1984                if (si->bound == 0) {
     1985                        ret = swrap_auto_bind(si, si->family);
     1986                        if (ret == -1) return -1;
     1987                }
     1988
     1989                if (!si->defer_connect) {
     1990                        break;
     1991                }
     1992
     1993                ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
     1994                                             tmp_un, 0, NULL);
     1995                if (ret == -1) return -1;
     1996
     1997                ret = real_connect(si->fd, (struct sockaddr *)(void *)tmp_un,
     1998                                   sizeof(*tmp_un));
     1999
     2000                /* to give better errors */
     2001                if (ret == -1 && errno == ENOENT) {
     2002                        errno = EHOSTUNREACH;
     2003                }
     2004
     2005                if (ret == -1) {
     2006                        return ret;
     2007                }
     2008
     2009                si->defer_connect = 0;
     2010                break;
     2011        default:
     2012                errno = EHOSTUNREACH;
     2013                return -1;
     2014        }
     2015
     2016        return 0;
     2017}
     2018
     2019static void swrap_sendmsg_after(struct socket_info *si,
     2020                                struct msghdr *msg,
     2021                                const struct sockaddr *to,
     2022                                ssize_t ret)
     2023{
     2024        int saved_errno = errno;
     2025        size_t i, len = 0;
     2026        uint8_t *buf;
     2027        off_t ofs = 0;
     2028        size_t avail = 0;
     2029        size_t remain;
     2030
     2031        /* to give better errors */
     2032        if (ret == -1 && saved_errno == ENOENT) {
     2033                saved_errno = EHOSTUNREACH;
     2034        }
     2035
     2036        for (i=0; i < msg->msg_iovlen; i++) {
     2037                avail += msg->msg_iov[i].iov_len;
     2038        }
     2039
     2040        if (ret == -1) {
     2041                remain = MIN(80, avail);
     2042        } else {
     2043                remain = ret;
     2044        }
     2045
     2046        /* we capture it as one single packet */
     2047        buf = (uint8_t *)malloc(remain);
     2048        if (!buf) {
     2049                /* we just not capture the packet */
     2050                errno = saved_errno;
     2051                return;
     2052        }
     2053
     2054        for (i=0; i < msg->msg_iovlen; i++) {
     2055                size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
     2056                memcpy(buf + ofs,
     2057                       msg->msg_iov[i].iov_base,
     2058                       this_time);
     2059                ofs += this_time;
     2060                remain -= this_time;
     2061        }
     2062        len = ofs;
     2063
     2064        switch (si->type) {
     2065        case SOCK_STREAM:
     2066                if (ret == -1) {
     2067                        swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
     2068                        swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
     2069                } else {
     2070                        swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
     2071                }
     2072                break;
     2073
     2074        case SOCK_DGRAM:
     2075                if (si->connected) {
     2076                        to = si->peername;
     2077                }
     2078                if (ret == -1) {
     2079                        swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
     2080                        swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
     2081                } else {
     2082                        swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
     2083                }
     2084                break;
     2085        }
     2086
     2087        free(buf);
     2088        errno = saved_errno;
     2089}
     2090
     2091_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
     2092{
     2093        struct sockaddr_un un_addr;
     2094        socklen_t un_addrlen = sizeof(un_addr);
     2095        int ret;
     2096        struct socket_info *si = find_socket_info(s);
     2097        struct sockaddr_storage ss;
     2098        socklen_t ss_len = sizeof(ss);
     2099
     2100        if (!si) {
     2101                return real_recvfrom(s, buf, len, flags, from, fromlen);
     2102        }
     2103
     2104        if (!from) {
     2105                from = (struct sockaddr *)(void *)&ss;
     2106                fromlen = &ss_len;
     2107        }
     2108
     2109        if (si->type == SOCK_STREAM) {
     2110                /* cut down to 1500 byte packets for stream sockets,
     2111                 * which makes it easier to format PCAP capture files
     2112                 * (as the caller will simply continue from here) */
     2113                len = MIN(len, 1500);
     2114        }
     2115
     2116        /* irix 6.4 forgets to null terminate the sun_path string :-( */
     2117        memset(&un_addr, 0, sizeof(un_addr));
     2118        ret = real_recvfrom(s, buf, len, flags,
     2119                            (struct sockaddr *)(void *)&un_addr, &un_addrlen);
     2120        if (ret == -1)
     2121                return ret;
     2122
     2123        if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
     2124                                     si->family, from, fromlen) == -1) {
     2125                return -1;
     2126        }
     2127
     2128        swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
     2129
     2130        return ret;
     2131}
     2132
     2133
     2134_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
     2135{
     2136        struct msghdr msg;
     2137        struct iovec tmp;
     2138        struct sockaddr_un un_addr;
     2139        const struct sockaddr_un *to_un = NULL;
     2140        ssize_t ret;
     2141        struct socket_info *si = find_socket_info(s);
     2142        int bcast = 0;
     2143
     2144        if (!si) {
     2145                return real_sendto(s, buf, len, flags, to, tolen);
     2146        }
     2147
     2148        tmp.iov_base = discard_const_p(char, buf);
     2149        tmp.iov_len = len;
     2150
     2151        ZERO_STRUCT(msg);
     2152        msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
     2153        msg.msg_namelen = tolen;       /* size of address */
     2154        msg.msg_iov = &tmp;            /* scatter/gather array */
     2155        msg.msg_iovlen = 1;            /* # elements in msg_iov */
     2156#if 0 /* not available on solaris */
     2157        msg.msg_control = NULL;        /* ancillary data, see below */
     2158        msg.msg_controllen = 0;        /* ancillary data buffer len */
     2159        msg.msg_flags = 0;             /* flags on received message */
     2160#endif
     2161
     2162        ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
     2163        if (ret == -1) return -1;
     2164
     2165        buf = msg.msg_iov[0].iov_base;
     2166        len = msg.msg_iov[0].iov_len;
     2167
     2168        if (bcast) {
     2169                struct stat st;
     2170                unsigned int iface;
     2171                unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
     2172                char type;
     2173
     2174                type = SOCKET_TYPE_CHAR_UDP;
     2175
     2176                for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
     2177                        snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
     2178                                 socket_wrapper_dir(), type, iface, prt);
     2179                        if (stat(un_addr.sun_path, &st) != 0) continue;
     2180
     2181                        /* ignore the any errors in broadcast sends */
     2182                        real_sendto(s, buf, len, flags,
     2183                                    (struct sockaddr *)(void *)&un_addr,
     2184                                    sizeof(un_addr));
     2185                }
     2186
     2187                swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
     2188
     2189                return len;
     2190        }
     2191
     2192        ret = real_sendto(s, buf, len, flags, msg.msg_name, msg.msg_namelen);
     2193
     2194        swrap_sendmsg_after(si, &msg, to, ret);
     2195
     2196        return ret;
     2197}
     2198
    20192199_PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
    20202200{
     
    20762256_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
    20772257{
    2078         int ret;
     2258        struct msghdr msg;
     2259        struct iovec tmp;
     2260        struct sockaddr_un un_addr;
     2261        ssize_t ret;
    20792262        struct socket_info *si = find_socket_info(s);
    20802263
     
    20832266        }
    20842267
    2085         if (si->type == SOCK_STREAM) {
    2086                 /* cut down to 1500 byte packets for stream sockets,
    2087                  * which makes it easier to format PCAP capture files
    2088                  * (as the caller will simply continue from here) */
    2089                 len = MIN(len, 1500);
    2090         }
    2091 
    2092         if (si->defer_connect) {
    2093                 struct sockaddr_un un_addr;
    2094                 int bcast = 0;
    2095 
    2096                 if (si->bound == 0) {
    2097                         ret = swrap_auto_bind(si, si->family);
    2098                         if (ret == -1) return -1;
    2099                 }
    2100 
    2101                 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
    2102                                              &un_addr, 0, &bcast);
    2103                 if (ret == -1) return -1;
    2104 
    2105                 ret = real_connect(s, (struct sockaddr *)&un_addr,
    2106                                    sizeof(un_addr));
    2107 
    2108                 /* to give better errors */
    2109                 if (ret == -1 && errno == ENOENT) {
    2110                         errno = EHOSTUNREACH;
    2111                 }
    2112 
    2113                 if (ret == -1) {
    2114                         return ret;
    2115                 }
    2116                 si->defer_connect = 0;
    2117         }
     2268        tmp.iov_base = discard_const_p(char, buf);
     2269        tmp.iov_len = len;
     2270
     2271        ZERO_STRUCT(msg);
     2272        msg.msg_name = NULL;           /* optional address */
     2273        msg.msg_namelen = 0;           /* size of address */
     2274        msg.msg_iov = &tmp;            /* scatter/gather array */
     2275        msg.msg_iovlen = 1;            /* # elements in msg_iov */
     2276#if 0 /* not available on solaris */
     2277        msg.msg_control = NULL;        /* ancillary data, see below */
     2278        msg.msg_controllen = 0;        /* ancillary data buffer len */
     2279        msg.msg_flags = 0;             /* flags on received message */
     2280#endif
     2281
     2282        ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
     2283        if (ret == -1) return -1;
     2284
     2285        buf = msg.msg_iov[0].iov_base;
     2286        len = msg.msg_iov[0].iov_len;
    21182287
    21192288        ret = real_send(s, buf, len, flags);
    21202289
    2121         if (ret == -1) {
    2122                 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
    2123                 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
    2124         } else {
    2125                 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
    2126         }
     2290        swrap_sendmsg_after(si, &msg, NULL, ret);
    21272291
    21282292        return ret;
    21292293}
    21302294
    2131 _PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags)
    2132 {
    2133         int ret;
    2134         uint8_t *buf;
    2135         off_t ofs = 0;
    2136         size_t i;
    2137         size_t remain;
    2138        
     2295_PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
     2296{
     2297        struct msghdr msg;
     2298        struct iovec tmp;
     2299        struct sockaddr_un un_addr;
     2300        const struct sockaddr_un *to_un = NULL;
     2301        const struct sockaddr *to = NULL;
     2302        ssize_t ret;
    21392303        struct socket_info *si = find_socket_info(s);
     2304        int bcast = 0;
    21402305
    21412306        if (!si) {
    2142                 return real_sendmsg(s, msg, flags);
    2143         }
    2144 
    2145         if (si->defer_connect) {
    2146                 struct sockaddr_un un_addr;
    2147                 int bcast = 0;
    2148 
    2149                 if (si->bound == 0) {
    2150                         ret = swrap_auto_bind(si, si->family);
    2151                         if (ret == -1) return -1;
    2152                 }
    2153 
    2154                 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
    2155                                              &un_addr, 0, &bcast);
    2156                 if (ret == -1) return -1;
    2157 
    2158                 ret = real_connect(s, (struct sockaddr *)&un_addr,
    2159                                    sizeof(un_addr));
    2160 
    2161                 /* to give better errors */
    2162                 if (ret == -1 && errno == ENOENT) {
    2163                         errno = EHOSTUNREACH;
    2164                 }
    2165 
    2166                 if (ret == -1) {
    2167                         return ret;
    2168                 }
    2169                 si->defer_connect = 0;
    2170         }
    2171 
    2172         ret = real_sendmsg(s, msg, flags);
    2173         remain = ret;
    2174                
    2175         /* we capture it as one single packet */
    2176         buf = (uint8_t *)malloc(ret);
    2177         if (!buf) {
    2178                 /* we just not capture the packet */
    2179                 errno = 0;
    2180                 return ret;
    2181         }
    2182        
    2183         for (i=0; i < msg->msg_iovlen; i++) {
    2184                 size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
    2185                 memcpy(buf + ofs,
    2186                        msg->msg_iov[i].iov_base,
    2187                        this_time);
    2188                 ofs += this_time;
    2189                 remain -= this_time;
    2190         }
    2191        
    2192         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
    2193         free(buf);
    2194         if (ret == -1) {
    2195                 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
    2196         }
     2307                return real_sendmsg(s, omsg, flags);
     2308        }
     2309
     2310        tmp.iov_base = NULL;
     2311        tmp.iov_len = 0;
     2312
     2313        msg = *omsg;
     2314#if 0
     2315        msg.msg_name = omsg->msg_name;             /* optional address */
     2316        msg.msg_namelen = omsg->msg_namelen;       /* size of address */
     2317        msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
     2318        msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
     2319        /* the following is not available on solaris */
     2320        msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
     2321        msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
     2322        msg.msg_flags = omsg->msg_flags;           /* flags on received message */
     2323#endif
     2324
     2325        ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
     2326        if (ret == -1) return -1;
     2327
     2328        if (bcast) {
     2329                struct stat st;
     2330                unsigned int iface;
     2331                unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
     2332                char type;
     2333                size_t i, len = 0;
     2334                uint8_t *buf;
     2335                off_t ofs = 0;
     2336                size_t avail = 0;
     2337                size_t remain;
     2338
     2339                for (i=0; i < msg.msg_iovlen; i++) {
     2340                        avail += msg.msg_iov[i].iov_len;
     2341                }
     2342
     2343                len = avail;
     2344                remain = avail;
     2345
     2346                /* we capture it as one single packet */
     2347                buf = (uint8_t *)malloc(remain);
     2348                if (!buf) {
     2349                        return -1;
     2350                }
     2351
     2352                for (i=0; i < msg.msg_iovlen; i++) {
     2353                        size_t this_time = MIN(remain, msg.msg_iov[i].iov_len);
     2354                        memcpy(buf + ofs,
     2355                               msg.msg_iov[i].iov_base,
     2356                               this_time);
     2357                        ofs += this_time;
     2358                        remain -= this_time;
     2359                }
     2360
     2361                type = SOCKET_TYPE_CHAR_UDP;
     2362
     2363                for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
     2364                        snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
     2365                                 socket_wrapper_dir(), type, iface, prt);
     2366                        if (stat(un_addr.sun_path, &st) != 0) continue;
     2367
     2368                        msg.msg_name = &un_addr;           /* optional address */
     2369                        msg.msg_namelen = sizeof(un_addr); /* size of address */
     2370
     2371                        /* ignore the any errors in broadcast sends */
     2372                        real_sendmsg(s, &msg, flags);
     2373                }
     2374
     2375                swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
     2376                free(buf);
     2377
     2378                return len;
     2379        }
     2380
     2381        ret = real_sendmsg(s, &msg, flags);
     2382
     2383        swrap_sendmsg_after(si, &msg, to, ret);
    21972384
    21982385        return ret;
     
    22072394        if (!si) {
    22082395                return real_readv(s, vector, count);
     2396        }
     2397
     2398        if (!si->connected) {
     2399                errno = ENOTCONN;
     2400                return -1;
    22092401        }
    22102402
     
    22142406                 * (as the caller will simply continue from here) */
    22152407                size_t i, len = 0;
    2216                
     2408
    22172409                for (i=0; i < count; i++) {
    22182410                        size_t nlen;
     
    22682460int swrap_writev(int s, const struct iovec *vector, size_t count)
    22692461{
    2270         int ret;
     2462        struct msghdr msg;
     2463        struct iovec tmp;
     2464        struct sockaddr_un un_addr;
     2465        ssize_t ret;
    22712466        struct socket_info *si = find_socket_info(s);
    2272         struct iovec v;
    22732467
    22742468        if (!si) {
     
    22762470        }
    22772471
    2278         if (si->type == SOCK_STREAM && count > 0) {
    2279                 /* cut down to 1500 byte packets for stream sockets,
    2280                  * which makes it easier to format PCAP capture files
    2281                  * (as the caller will simply continue from here) */
    2282                 size_t i, len = 0;
    2283 
    2284                 for (i=0; i < count; i++) {
    2285                         size_t nlen;
    2286                         nlen = len + vector[i].iov_len;
    2287                         if (nlen > 1500) {
    2288                                 break;
    2289                         }
    2290                 }
    2291                 count = i;
    2292                 if (count == 0) {
    2293                         v = vector[0];
    2294                         v.iov_len = MIN(v.iov_len, 1500);
    2295                         vector = &v;
    2296                         count = 1;
    2297                 }
    2298         }
    2299 
    2300         ret = real_writev(s, vector, count);
    2301         if (ret == -1) {
    2302                 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
    2303         } else {
    2304                 uint8_t *buf;
    2305                 off_t ofs = 0;
    2306                 size_t i;
    2307                 size_t remain = ret;
    2308 
    2309                 /* we capture it as one single packet */
    2310                 buf = (uint8_t *)malloc(ret);
    2311                 if (!buf) {
    2312                         /* we just not capture the packet */
    2313                         errno = 0;
    2314                         return ret;
    2315                 }
    2316 
    2317                 for (i=0; i < count; i++) {
    2318                         size_t this_time = MIN(remain, vector[i].iov_len);
    2319                         memcpy(buf + ofs,
    2320                                vector[i].iov_base,
    2321                                this_time);
    2322                         ofs += this_time;
    2323                         remain -= this_time;
    2324                 }
    2325 
    2326                 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
    2327                 free(buf);
    2328         }
     2472        tmp.iov_base = NULL;
     2473        tmp.iov_len = 0;
     2474
     2475        ZERO_STRUCT(msg);
     2476        msg.msg_name = NULL;           /* optional address */
     2477        msg.msg_namelen = 0;           /* size of address */
     2478        msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
     2479        msg.msg_iovlen = count;        /* # elements in msg_iov */
     2480#if 0 /* not available on solaris */
     2481        msg.msg_control = NULL;        /* ancillary data, see below */
     2482        msg.msg_controllen = 0;        /* ancillary data buffer len */
     2483        msg.msg_flags = 0;             /* flags on received message */
     2484#endif
     2485
     2486        ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
     2487        if (ret == -1) return -1;
     2488
     2489        ret = real_writev(s, msg.msg_iov, msg.msg_iovlen);
     2490
     2491        swrap_sendmsg_after(si, &msg, NULL, ret);
    23292492
    23302493        return ret;
  • trunk/server/lib/socket_wrapper/socket_wrapper.h

    r414 r745  
    5151ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
    5252ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags);
     53ssize_t swrap_recvmsg(int s, struct msghdr *msg, int flags);
    5354int swrap_ioctl(int s, int req, void *ptr);
    5455ssize_t swrap_recv(int s, void *buf, size_t len, int flags);
     
    116117#define sendmsg(s,msg,flags)            swrap_sendmsg(s,msg,flags)
    117118
     119#ifdef recvmsg
     120#undef recvmsg
     121#endif
     122#define recvmsg(s,msg,flags)            swrap_recvmsg(s,msg,flags)
     123
    118124#ifdef ioctl
    119125#undef ioctl
  • trunk/server/lib/socket_wrapper/testsuite.c

    r414 r745  
    9696{
    9797        struct torture_suite *suite = torture_suite_create(mem_ctx,
    98                                                                                                            "SOCKET-WRAPPER");
     98                                                                                                           "socket-wrapper");
    9999
    100100        torture_suite_add_simple_test(suite, "socket_wrapper_dir", test_socket_wrapper_dir);
Note: See TracChangeset for help on using the changeset viewer.