Changeset 745 for trunk/server/lib/socket_wrapper
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 1 deleted
- 4 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/lib/socket_wrapper/socket_wrapper.c
r414 r745 297 297 case SOCKET_TYPE_CHAR_TCP: 298 298 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 301 301 if ((*len) < sizeof(*in2)) { 302 302 errno = EINVAL; … … 315 315 case SOCKET_TYPE_CHAR_TCP_V6: 316 316 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 319 319 if ((*len) < sizeof(*in2)) { 320 320 errno = EINVAL; … … 353 353 case AF_INET: { 354 354 const struct sockaddr_in *in = 355 (const struct sockaddr_in *) inaddr;355 (const struct sockaddr_in *)(const void *)inaddr; 356 356 unsigned int addr = ntohl(in->sin_addr.s_addr); 357 357 char u_type = '\0'; … … 396 396 case AF_INET6: { 397 397 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; 400 400 401 401 switch (si->type) { … … 412 412 prt = ntohs(in->sin6_port); 413 413 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)) { 417 418 iface = in->sin6_addr.s6_addr[15]; 418 419 } else { … … 461 462 case AF_INET: { 462 463 const struct sockaddr_in *in = 463 (const struct sockaddr_in *) inaddr;464 (const struct sockaddr_in *)(const void *)inaddr; 464 465 unsigned int addr = ntohl(in->sin_addr.s_addr); 465 466 char u_type = '\0'; … … 512 513 case AF_INET6: { 513 514 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; 516 517 517 518 switch (si->type) { … … 528 529 prt = ntohs(in->sin6_port); 529 530 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; 532 534 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) { 533 535 iface = socket_wrapper_default_iface(); 534 } else if (IN6_ARE_ADDR_EQUAL( swrap_ipv6(), &cmp)) {536 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) { 535 537 iface = in->sin6_addr.s6_addr[15]; 536 538 } else { … … 585 587 struct sockaddr_un *out_addr, int alloc_sock, int *bcast) 586 588 { 589 struct sockaddr *out = (struct sockaddr *)(void *)out_addr; 587 590 if (!out_addr) 588 591 return 0; 589 592 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 591 597 592 598 switch (in_addr->sa_family) { … … 611 617 break; 612 618 } 613 619 614 620 errno = EAFNOSUPPORT; 615 621 return -1; … … 623 629 socklen_t *out_addrlen) 624 630 { 631 int ret; 632 625 633 if (out_addr == NULL || out_addrlen == NULL) 626 634 return 0; … … 644 652 return -1; 645 653 } 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; 647 659 default: 648 660 break; … … 960 972 ip->v6.flow_label_high = 0x00; 961 973 ip->v6.flow_label_low = 0x0000; 962 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); //TODO974 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */ 963 975 ip->v6.next_header = protocol; 964 976 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16); … … 1010 1022 ip->v6.flow_label_high = 0x00; 1011 1023 ip->v6.flow_label_low = 0x0000; 1012 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); //TODO1024 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */ 1013 1025 ip->v6.next_header = protocol; 1014 1026 memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16); … … 1495 1507 memset(&un_my_addr, 0, sizeof(un_my_addr)); 1496 1508 1497 ret = real_accept(s, (struct sockaddr *) &un_addr, &un_addrlen);1509 ret = real_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen); 1498 1510 if (ret == -1) { 1499 1511 free(my_addr); … … 1527 1539 1528 1540 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); 1536 1550 if (ret == -1) { 1537 1551 free(child_si); … … 1660 1674 type, socket_wrapper_default_iface(), port); 1661 1675 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)); 1664 1679 if (ret == -1) return ret; 1665 1680 … … 1686 1701 struct sockaddr_un un_addr; 1687 1702 struct socket_info *si = find_socket_info(s); 1703 int bcast = 0; 1688 1704 1689 1705 if (!si) { … … 1701 1717 } 1702 1718 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); 1704 1721 if (ret == -1) return -1; 1722 1723 if (bcast) { 1724 errno = ENETUNREACH; 1725 return -1; 1726 } 1705 1727 1706 1728 if (si->type == SOCK_DGRAM) { … … 1710 1732 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); 1711 1733 1712 ret = real_connect(s, (struct sockaddr *) &un_addr,1734 ret = real_connect(s, (struct sockaddr *)(void *)&un_addr, 1713 1735 sizeof(struct sockaddr_un)); 1714 1736 } … … 1746 1768 si->myname = sockaddr_dup(myaddr, addrlen); 1747 1769 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); 1749 1771 if (ret == -1) return -1; 1750 1772 1751 1773 unlink(un_addr.sun_path); 1752 1774 1753 ret = real_bind(s, (struct sockaddr *) &un_addr,1775 ret = real_bind(s, (struct sockaddr *)(void *)&un_addr, 1754 1776 sizeof(struct sockaddr_un)); 1755 1777 … … 1848 1870 return -1; 1849 1871 } 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 files1873 * (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 files1919 * (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;1991 1872 } 1992 1873 … … 2017 1898 } 2018 1899 1900 static 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 2019 static 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 2019 2199 _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) 2020 2200 { … … 2076 2256 _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) 2077 2257 { 2078 int ret; 2258 struct msghdr msg; 2259 struct iovec tmp; 2260 struct sockaddr_un un_addr; 2261 ssize_t ret; 2079 2262 struct socket_info *si = find_socket_info(s); 2080 2263 … … 2083 2266 } 2084 2267 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; 2118 2287 2119 2288 ret = real_send(s, buf, len, flags); 2120 2289 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); 2127 2291 2128 2292 return ret; 2129 2293 } 2130 2294 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; 2139 2303 struct socket_info *si = find_socket_info(s); 2304 int bcast = 0; 2140 2305 2141 2306 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); 2197 2384 2198 2385 return ret; … … 2207 2394 if (!si) { 2208 2395 return real_readv(s, vector, count); 2396 } 2397 2398 if (!si->connected) { 2399 errno = ENOTCONN; 2400 return -1; 2209 2401 } 2210 2402 … … 2214 2406 * (as the caller will simply continue from here) */ 2215 2407 size_t i, len = 0; 2216 2408 2217 2409 for (i=0; i < count; i++) { 2218 2410 size_t nlen; … … 2268 2460 int swrap_writev(int s, const struct iovec *vector, size_t count) 2269 2461 { 2270 int ret; 2462 struct msghdr msg; 2463 struct iovec tmp; 2464 struct sockaddr_un un_addr; 2465 ssize_t ret; 2271 2466 struct socket_info *si = find_socket_info(s); 2272 struct iovec v;2273 2467 2274 2468 if (!si) { … … 2276 2470 } 2277 2471 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); 2329 2492 2330 2493 return ret; -
trunk/server/lib/socket_wrapper/socket_wrapper.h
r414 r745 51 51 ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); 52 52 ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags); 53 ssize_t swrap_recvmsg(int s, struct msghdr *msg, int flags); 53 54 int swrap_ioctl(int s, int req, void *ptr); 54 55 ssize_t swrap_recv(int s, void *buf, size_t len, int flags); … … 116 117 #define sendmsg(s,msg,flags) swrap_sendmsg(s,msg,flags) 117 118 119 #ifdef recvmsg 120 #undef recvmsg 121 #endif 122 #define recvmsg(s,msg,flags) swrap_recvmsg(s,msg,flags) 123 118 124 #ifdef ioctl 119 125 #undef ioctl -
trunk/server/lib/socket_wrapper/testsuite.c
r414 r745 96 96 { 97 97 struct torture_suite *suite = torture_suite_create(mem_ctx, 98 " SOCKET-WRAPPER");98 "socket-wrapper"); 99 99 100 100 torture_suite_add_simple_test(suite, "socket_wrapper_dir", test_socket_wrapper_dir);
Note:
See TracChangeset
for help on using the changeset viewer.