147 rb_scan_args(argc, argv,
"21", &domain, &type, &protocol);
159 #if defined HAVE_SOCKETPAIR
173 pair_yield(
VALUE pair)
179 #if defined HAVE_SOCKETPAIR
182 rsock_socketpair0(
int domain,
int type,
int protocol,
int sv[2])
187 static int try_sock_cloexec = 1;
188 if (try_sock_cloexec) {
189 ret =
socketpair(domain, type|SOCK_CLOEXEC, protocol, sv);
190 if (ret == -1 && errno == EINVAL) {
198 try_sock_cloexec = 0;
220 rsock_socketpair(
int domain,
int type,
int protocol,
int sv[2])
224 ret = rsock_socketpair0(domain, type, protocol, sv);
225 if (ret < 0 && (errno == EMFILE || errno == ENFILE)) {
227 ret = rsock_socketpair0(domain, type, protocol, sv);
270 rb_scan_args(argc, argv,
"21", &domain, &type, &protocol);
276 ret = rsock_socketpair(d, t, p, sp);
292 #define rsock_sock_s_socketpair rb_f_notimplement
666 if (listen(fptr->
fd, backlog) < 0)
995 #ifdef HAVE_GETHOSTNAME
1010 #ifndef HOST_NAME_MAX
1011 # define HOST_NAME_MAX 1024
1013 char buf[HOST_NAME_MAX+1];
1016 if (gethostname(buf, (
int)
sizeof buf - 1) < 0)
1019 buf[
sizeof buf - 1] =
'\0';
1025 #include <sys/utsname.h>
1037 #define sock_gethostname rb_f_notimplement
1051 for (res = res0->
ai; res; res = res->
ai_next) {
1069 switch (addr->sa_family) {
1071 ptr = (
char*)&((
struct sockaddr_in*)addr)->sin_addr.s_addr;
1072 len = (
socklen_t)
sizeof(((
struct sockaddr_in*)addr)->sin_addr.s_addr);
1076 ptr = (
char*)&((
struct sockaddr_in6*)addr)->sin6_addr.s6_addr;
1077 len = (
socklen_t)
sizeof(((
struct sockaddr_in6*)addr)->sin6_addr.s6_addr);
1123 if (!
NIL_P(family)) {
1133 #ifdef HAVE_HSTRERROR
1144 if (h->h_aliases !=
NULL) {
1145 for (pch = h->h_aliases; *pch; pch++) {
1151 for (pch = h->h_addr_list; *pch; pch++) {
1180 const char *servicename, *protoname =
"tcp";
1187 sp = getservbyname(servicename, protoname);
1189 port = ntohs(sp->s_port);
1194 port =
STRTOUL(servicename, &end, 0);
1221 const char *protoname =
"tcp";
1225 if (portnum != (uint16_t)portnum) {
1226 const char *s = portnum > 0 ?
"big" :
"small";
1231 sp = getservbyport((
int)htons((uint16_t)portnum), protoname);
1273 VALUE host, port, family, socktype, protocol, flags, ret, revlookup;
1278 rb_scan_args(argc, argv,
"25", &host, &port, &family, &socktype, &protocol, &flags, &revlookup);
1283 if (!
NIL_P(socktype)) {
1286 if (!
NIL_P(protocol)) {
1289 if (!
NIL_P(flags)) {
1329 char hbuf[1024], pbuf[1024];
1333 int error, saved_errno;
1335 struct sockaddr *sap;
1342 if (!
NIL_P(flags)) {
1380 #ifdef AI_NUMERICHOST
1395 hbuf[
sizeof(hbuf) - 1] =
'\0';
1409 pbuf[
sizeof(pbuf) - 1] =
'\0';
1416 if (error)
goto error_exit_addr;
1426 pbuf,
sizeof(pbuf), fl);
1427 if (error)
goto error_exit_name;
1430 char hbuf2[1024], pbuf2[1024];
1435 pbuf2,
sizeof(pbuf2), fl);
1436 if (error)
goto error_exit_name;
1437 if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
1447 saved_errno =
errno;
1449 errno = saved_errno;
1453 saved_errno =
errno;
1455 errno = saved_errno;
1504 struct sockaddr_in * sockaddr;
1509 (
char*)&((
struct sockaddr *)sockaddr)->sa_family +
1510 sizeof(((
struct sockaddr *)sockaddr)->sa_family) -
1513 if (((
struct sockaddr *)sockaddr)->sa_family != AF_INET
1515 && ((
struct sockaddr *)sockaddr)->sa_family != AF_INET6
1529 #ifdef HAVE_SYS_UN_H
1542 sock_s_pack_sockaddr_un(
VALUE self,
VALUE path)
1544 struct sockaddr_un sockaddr;
1548 INIT_SOCKADDR_UN(&sockaddr,
sizeof(
struct sockaddr_un));
1549 if (
sizeof(sockaddr.sun_path) < (
size_t)
RSTRING_LEN(path)) {
1550 rb_raise(
rb_eArgError,
"too long unix socket path (%"PRIuSIZE
" bytes given but %"PRIuSIZE
" bytes max)",
1551 (
size_t)
RSTRING_LEN(path),
sizeof(sockaddr.sun_path));
1554 addr =
rb_str_new((
char*)&sockaddr, rsock_unix_sockaddr_len(path));
1573 sock_s_unpack_sockaddr_un(
VALUE self,
VALUE addr)
1575 struct sockaddr_un * sockaddr;
1580 (
char*)&((
struct sockaddr *)sockaddr)->sa_family +
1581 sizeof(((
struct sockaddr *)sockaddr)->sa_family) -
1584 if (((
struct sockaddr *)sockaddr)->sa_family != AF_UNIX) {
1587 if (
sizeof(
struct sockaddr_un) < (
size_t)
RSTRING_LEN(addr)) {
1589 RSTRING_LEN(addr), (
int)
sizeof(
struct sockaddr_un));
1597 #if defined(HAVE_GETIFADDRS) || defined(SIOCGLIFCONF) || defined(SIOCGIFCONF) || defined(_WIN32)
1600 sockaddr_len(
struct sockaddr *addr)
1605 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1606 if (addr->sa_len != 0)
1607 return addr->sa_len;
1610 switch (addr->sa_family) {
1612 return (
socklen_t)
sizeof(
struct sockaddr_in);
1616 return (
socklen_t)
sizeof(
struct sockaddr_in6);
1619 #ifdef HAVE_SYS_UN_H
1621 return (
socklen_t)
sizeof(
struct sockaddr_un);
1626 return (
socklen_t)(
offsetof(
struct sockaddr_ll, sll_addr) + ((
struct sockaddr_ll *)addr)->sll_halen);
1630 return (
socklen_t)(
offsetof(
struct sockaddr, sa_family) +
sizeof(addr->sa_family));
1637 return sockaddr_len(addr);
1641 sockaddr_obj(
struct sockaddr *addr,
socklen_t len)
1643 #if defined(AF_INET6) && defined(__KAME__)
1644 struct sockaddr_in6 addr6;
1650 len = sockaddr_len(addr);
1652 #if defined(__KAME__) && defined(AF_INET6)
1653 if (addr->sa_family == AF_INET6) {
1657 len = (
socklen_t)
sizeof(
struct sockaddr_in6);
1658 memcpy(&addr6, addr, len);
1659 addr = (
struct sockaddr *)&addr6;
1660 if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
1661 addr6.sin6_scope_id == 0 &&
1662 (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) {
1663 addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3];
1664 addr6.sin6_addr.s6_addr[2] = 0;
1665 addr6.sin6_addr.s6_addr[3] = 0;
1676 return sockaddr_obj(addr, len);
1681 #if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)) || defined(SIOCGIFCONF) || defined(_WIN32)
1700 #if defined(HAVE_GETIFADDRS)
1712 for (p = ifp; p; p = p->
ifa_next) {
1714 struct sockaddr *addr = p->
ifa_addr;
1715 #if defined(AF_INET6) && defined(__sun)
1721 struct sockaddr_in6 addr6;
1722 if (addr->sa_family == AF_INET6) {
1724 memcpy(&addr6, addr, len);
1725 addr = (
struct sockaddr *)&addr6;
1726 if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
1727 addr6.sin6_scope_id == 0) {
1728 unsigned int ifindex = if_nametoindex(p->
ifa_name);
1730 addr6.sin6_scope_id = ifindex;
1735 rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr)));
1742 #elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)
1749 char *reason =
NULL;
1756 fd = socket(AF_INET, SOCK_DGRAM, 0);
1760 memset(&ln, 0,
sizeof(ln));
1763 ret =
ioctl(fd, SIOCGLIFNUM, &ln);
1765 reason =
"SIOCGLIFNUM";
1769 memset(&lc, 0,
sizeof(lc));
1772 lc.lifc_len =
sizeof(
struct lifreq) * ln.lifn_count;
1773 lc.lifc_req =
xmalloc(lc.lifc_len);
1775 ret =
ioctl(fd, SIOCGLIFCONF, &lc);
1777 reason =
"SIOCGLIFCONF";
1782 for (i = 0; i < ln.lifn_count; i++) {
1783 struct lifreq *req = &lc.lifc_req[i];
1785 if (req->lifr_addr.ss_family == AF_INET6 &&
1786 IN6_IS_ADDR_LINKLOCAL(&((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) &&
1787 ((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id == 0) {
1789 memcpy(req2.lifr_name, req->lifr_name, LIFNAMSIZ);
1790 ret =
ioctl(fd, SIOCGLIFINDEX, &req2);
1792 reason =
"SIOCGLIFINDEX";
1795 ((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id = req2.lifr_index;
1797 rb_ary_push(list, sockaddr_obj((
struct sockaddr *)&req->lifr_addr, req->lifr_addrlen));
1803 if (lc.lifc_buf !=
NULL)
1813 #elif defined(SIOCGIFCONF)
1816 #define EXTRA_SPACE ((int)(sizeof(struct ifconf) + sizeof(union_sockaddr)))
1817 char initbuf[4096+EXTRA_SPACE];
1818 char *buf = initbuf;
1823 const char *reason =
NULL;
1826 fd = socket(AF_INET, SOCK_DGRAM, 0);
1830 bufsize =
sizeof(initbuf);
1834 conf.ifc_len = bufsize;
1835 conf.ifc_req = (
struct ifreq *)buf;
1839 ret =
ioctl(fd, SIOCGIFCONF, &conf);
1841 reason =
"SIOCGIFCONF";
1847 if (bufsize - EXTRA_SPACE < conf.ifc_len) {
1848 if (bufsize < conf.ifc_len) {
1850 bufsize = conf.ifc_len + EXTRA_SPACE;
1853 bufsize = bufsize << 1;
1866 while ((
char*)req < (
char*)conf.ifc_req + conf.ifc_len) {
1867 struct sockaddr *addr = &req->ifr_addr;
1869 rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr)));
1871 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1872 # ifndef _SIZEOF_ADDR_IFREQ
1873 # define _SIZEOF_ADDR_IFREQ(r) \
1874 (sizeof(struct ifreq) + \
1875 (sizeof(struct sockaddr) < (r).ifr_addr.sa_len ? \
1876 (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \
1879 req = (
struct ifreq *)((
char*)req + _SIZEOF_ADDR_IFREQ(*req));
1881 req = (
struct ifreq *)((
char*)req +
sizeof(
struct ifreq));
1899 #elif defined(_WIN32)
1900 typedef struct ip_adapter_unicast_address_st {
1901 unsigned LONG_LONG dummy0;
1902 struct ip_adapter_unicast_address_st *
Next;
1904 struct sockaddr *lpSockaddr;
1905 int iSockaddrLength;
1913 } ip_adapter_unicast_address_t;
1914 typedef struct ip_adapter_anycast_address_st {
1915 unsigned LONG_LONG dummy0;
1916 struct ip_adapter_anycast_address_st *
Next;
1918 struct sockaddr *lpSockaddr;
1919 int iSockaddrLength;
1921 } ip_adapter_anycast_address_t;
1922 typedef struct ip_adapter_addresses_st {
1923 unsigned LONG_LONG dummy0;
1924 struct ip_adapter_addresses_st *
Next;
1926 ip_adapter_unicast_address_t *FirstUnicastAddress;
1927 ip_adapter_anycast_address_t *FirstAnycastAddress;
1942 } ip_adapter_addresses_t;
1943 typedef ULONG (WINAPI *GetAdaptersAddresses_t)(
ULONG,
ULONG, PVOID, ip_adapter_addresses_t *, PULONG);
1945 GetAdaptersAddresses_t pGetAdaptersAddresses;
1948 ip_adapter_addresses_t *adapters;
1951 h = LoadLibrary(
"iphlpapi.dll");
1954 pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(h,
"GetAdaptersAddresses");
1955 if (!pGetAdaptersAddresses) {
1961 if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) {
1966 adapters = (ip_adapter_addresses_t *)
ALLOCA_N(BYTE, len);
1967 ret = pGetAdaptersAddresses(
AF_UNSPEC, 0,
NULL, adapters, &len);
1968 if (ret != ERROR_SUCCESS) {
1975 for (; adapters; adapters = adapters->Next) {
1976 ip_adapter_unicast_address_t *uni;
1977 ip_adapter_anycast_address_t *any;
1978 if (adapters->OperStatus != 1)
1980 for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) {
1982 if (uni->Address.lpSockaddr->sa_family == AF_INET)
1986 rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr, uni->Address.iSockaddrLength));
1988 for (any = adapters->FirstAnycastAddress; any; any = any->Next) {
1990 if (any->Address.lpSockaddr->sa_family == AF_INET)
1994 rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr, any->Address.iSockaddrLength));
2003 #define socket_s_ip_address_list rb_f_notimplement
2154 #ifdef HAVE_SYS_UN_H