13 static VALUE sym_wait_writable;
143 setup_domain_and_type(domain, &d,
type, &t);
150 #if defined HAVE_SOCKETPAIR
152 io_call_close(
VALUE io)
160 return rb_rescue(io_call_close, io, 0, 0);
164 pair_yield(
VALUE pair)
170 #if defined HAVE_SOCKETPAIR
174 rsock_socketpair0(
int domain,
int type,
int protocol,
int sv[2])
177 static int cloexec_state = -1;
180 if (cloexec_state > 0) {
182 if (ret == 0 && (sv[0] <= 2 || sv[1] <= 2)) {
187 else if (cloexec_state < 0) {
191 if ((cloexec_state == 0) || (sv[0] <= 2 || sv[1] <= 2))
230 rsock_socketpair0(
int domain,
int type,
int protocol,
int sv[2])
248 rsock_socketpair(
int domain,
int type,
int protocol,
int sv[2])
252 ret = rsock_socketpair0(domain,
type, protocol, sv);
254 ret = rsock_socketpair0(domain,
type, protocol, sv);
301 setup_domain_and_type(domain, &d,
type, &t);
303 ret = rsock_socketpair(d, t, p, sp);
312 return rb_ensure(pair_yield, r, io_close, s1);
317 #define rsock_sock_s_socketpair rb_f_notimplement
467 return sym_wait_writable;
660 if (listen(fptr->
fd, backlog) < 0)
799 sock_accept(
VALUE sock)
819 struct sockaddr *addr = &
buf.addr;
869 sock_sysaccept(
VALUE sock)
882 #ifdef HAVE_GETHOSTNAME
897 #if defined(NI_MAXHOST)
898 # define RUBY_MAX_HOST_NAME_LEN NI_MAXHOST
899 #elif defined(HOST_NAME_MAX)
900 # define RUBY_MAX_HOST_NAME_LEN HOST_NAME_MAX
902 # define RUBY_MAX_HOST_NAME_LEN 1024
905 long len = RUBY_MAX_HOST_NAME_LEN;
930 #include <sys/utsname.h>
941 #define sock_gethostname rb_f_notimplement
946 make_addrinfo(
struct rb_addrinfo *res0,
int norevlookup)
955 for (res = res0->
ai; res; res = res->
ai_next) {
973 switch (addr->sa_family) {
975 ptr = (
char*)&((
struct sockaddr_in*)addr)->sin_addr.s_addr;
976 len = (
socklen_t)
sizeof(((
struct sockaddr_in*)addr)->sin_addr.s_addr);
980 ptr = (
char*)&((
struct sockaddr_in6*)addr)->sin6_addr.s6_addr;
981 len = (
socklen_t)
sizeof(((
struct sockaddr_in6*)addr)->sin6_addr.s6_addr);
1055 if (!
NIL_P(family)) {
1065 #ifdef HAVE_HSTRERROR
1076 if (
h->h_aliases !=
NULL) {
1077 for (pch =
h->h_aliases; *pch; pch++) {
1083 for (pch =
h->h_addr_list; *pch; pch++) {
1112 const char *servicename, *protoname =
"tcp";
1119 sp = getservbyname(servicename, protoname);
1121 port = ntohs(sp->s_port);
1126 port =
STRTOUL(servicename, &end, 0);
1153 const char *protoname =
"tcp";
1157 if (portnum != (
uint16_t)portnum) {
1158 const char *s = portnum > 0 ?
"big" :
"small";
1163 sp = getservbyport((
int)htons((
uint16_t)portnum), protoname);
1208 VALUE host, port, family, socktype, protocol, flags, ret, revlookup;
1213 rb_scan_args(
argc,
argv,
"25", &host, &port, &family, &socktype, &protocol, &flags, &revlookup);
1218 if (!
NIL_P(socktype)) {
1221 if (!
NIL_P(protocol)) {
1222 hints.ai_protocol =
NUM2INT(protocol);
1224 if (!
NIL_P(flags)) {
1225 hints.ai_flags =
NUM2INT(flags);
1232 ret = make_addrinfo(res, norevlookup);
1264 char hbuf[1024], pbuf[1024];
1268 int error, saved_errno;
1270 struct sockaddr *sap;
1277 if (!
NIL_P(flags)) {
1315 #ifdef AI_NUMERICHOST
1330 hbuf[
sizeof(hbuf) - 1] =
'\0';
1344 pbuf[
sizeof(pbuf) - 1] =
'\0';
1347 hints.ai_socktype = (fl &
NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
1351 if (
error)
goto error_exit_addr;
1361 pbuf,
sizeof(pbuf), fl);
1362 if (
error)
goto error_exit_name;
1365 char hbuf2[1024], pbuf2[1024];
1370 pbuf2,
sizeof(pbuf2), fl);
1371 if (
error)
goto error_exit_name;
1372 if (
strcmp(hbuf, hbuf2) != 0||
strcmp(pbuf, pbuf2) != 0) {
1382 saved_errno =
errno;
1384 errno = saved_errno;
1388 saved_errno =
errno;
1390 errno = saved_errno;
1435 sock_s_unpack_sockaddr_in(
VALUE self,
VALUE addr)
1437 struct sockaddr_in * sockaddr;
1442 (
char*)&((
struct sockaddr *)sockaddr)->sa_family +
1443 sizeof(((
struct sockaddr *)sockaddr)->sa_family) -
1446 if (((
struct sockaddr *)sockaddr)->sa_family != AF_INET
1448 && ((
struct sockaddr *)sockaddr)->sa_family != AF_INET6
1461 #ifdef HAVE_SYS_UN_H
1476 struct sockaddr_un sockaddr;
1480 INIT_SOCKADDR_UN(&sockaddr,
sizeof(
struct sockaddr_un));
1486 addr =
rb_str_new((
char*)&sockaddr, rsock_unix_sockaddr_len(
path));
1504 sock_s_unpack_sockaddr_un(
VALUE self,
VALUE addr)
1506 struct sockaddr_un * sockaddr;
1511 (
char*)&((
struct sockaddr *)sockaddr)->sa_family +
1512 sizeof(((
struct sockaddr *)sockaddr)->sa_family) -
1515 if (((
struct sockaddr *)sockaddr)->sa_family != AF_UNIX) {
1518 if (
sizeof(
struct sockaddr_un) < (
size_t)
RSTRING_LEN(addr)) {
1520 RSTRING_LEN(addr), (
int)
sizeof(
struct sockaddr_un));
1527 #if defined(HAVE_GETIFADDRS) || defined(SIOCGLIFCONF) || defined(SIOCGIFCONF) || defined(_WIN32)
1530 sockaddr_len(
struct sockaddr *addr)
1535 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1536 if (addr->sa_len != 0)
1537 return addr->sa_len;
1540 switch (addr->sa_family) {
1542 return (
socklen_t)
sizeof(
struct sockaddr_in);
1546 return (
socklen_t)
sizeof(
struct sockaddr_in6);
1549 #ifdef HAVE_SYS_UN_H
1551 return (
socklen_t)
sizeof(
struct sockaddr_un);
1556 return (
socklen_t)(
offsetof(
struct sockaddr_ll, sll_addr) + ((
struct sockaddr_ll *)addr)->sll_halen);
1560 return (
socklen_t)(
offsetof(
struct sockaddr, sa_family) +
sizeof(addr->sa_family));
1567 return sockaddr_len(addr);
1573 #if defined(AF_INET6) && defined(__KAME__)
1574 struct sockaddr_in6 addr6;
1580 len = sockaddr_len(addr);
1582 #if defined(__KAME__) && defined(AF_INET6)
1583 if (addr->sa_family == AF_INET6) {
1589 addr = (
struct sockaddr *)&addr6;
1590 if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
1591 addr6.sin6_scope_id == 0 &&
1592 (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) {
1593 addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3];
1594 addr6.sin6_addr.s6_addr[2] = 0;
1595 addr6.sin6_addr.s6_addr[3] = 0;
1606 return sockaddr_obj(addr,
len);
1611 #if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)) || defined(SIOCGIFCONF) || defined(_WIN32)
1630 #if defined(HAVE_GETIFADDRS)
1642 for (p = ifp; p; p = p->
ifa_next) {
1644 struct sockaddr *addr = p->
ifa_addr;
1645 #if defined(AF_INET6) && defined(__sun)
1651 struct sockaddr_in6 addr6;
1652 if (addr->sa_family == AF_INET6) {
1655 addr = (
struct sockaddr *)&addr6;
1656 if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
1657 addr6.sin6_scope_id == 0) {
1658 unsigned int ifindex = if_nametoindex(p->
ifa_name);
1660 addr6.sin6_scope_id = ifindex;
1672 #elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)
1679 const char *reason =
NULL;
1686 fd = socket(AF_INET, SOCK_DGRAM, 0);
1690 memset(&ln, 0,
sizeof(ln));
1693 ret =
ioctl(fd, SIOCGLIFNUM, &ln);
1695 reason =
"SIOCGLIFNUM";
1699 memset(&lc, 0,
sizeof(lc));
1702 lc.lifc_len =
sizeof(
struct lifreq) * ln.lifn_count;
1703 lc.lifc_req =
xmalloc(lc.lifc_len);
1705 ret =
ioctl(fd, SIOCGLIFCONF, &lc);
1707 reason =
"SIOCGLIFCONF";
1712 for (
i = 0;
i < ln.lifn_count;
i++) {
1713 struct lifreq *req = &lc.lifc_req[
i];
1715 if (req->lifr_addr.ss_family == AF_INET6 &&
1716 IN6_IS_ADDR_LINKLOCAL(&((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) &&
1717 ((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id == 0) {
1719 memcpy(req2.lifr_name, req->lifr_name, LIFNAMSIZ);
1720 ret =
ioctl(fd, SIOCGLIFINDEX, &req2);
1722 reason =
"SIOCGLIFINDEX";
1725 ((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id = req2.lifr_index;
1727 rb_ary_push(
list, sockaddr_obj((
struct sockaddr *)&req->lifr_addr, req->lifr_addrlen));
1733 if (lc.lifc_buf !=
NULL)
1743 #elif defined(SIOCGIFCONF)
1746 #define EXTRA_SPACE ((int)(sizeof(struct ifconf) + sizeof(union_sockaddr)))
1747 char initbuf[4096+EXTRA_SPACE];
1748 char *
buf = initbuf;
1753 const char *reason =
NULL;
1756 fd = socket(AF_INET, SOCK_DGRAM, 0);
1760 bufsize =
sizeof(initbuf);
1764 conf.ifc_len = bufsize;
1765 conf.ifc_req = (
struct ifreq *)
buf;
1769 ret =
ioctl(fd, SIOCGIFCONF, &conf);
1771 reason =
"SIOCGIFCONF";
1777 if (bufsize - EXTRA_SPACE < conf.ifc_len) {
1778 if (bufsize < conf.ifc_len) {
1780 bufsize = conf.ifc_len + EXTRA_SPACE;
1783 bufsize = bufsize << 1;
1796 while ((
char*)req < (
char*)conf.ifc_req + conf.ifc_len) {
1797 struct sockaddr *addr = &req->ifr_addr;
1801 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1802 # ifndef _SIZEOF_ADDR_IFREQ
1803 # define _SIZEOF_ADDR_IFREQ(r) \
1804 (sizeof(struct ifreq) + \
1805 (sizeof(struct sockaddr) < (r).ifr_addr.sa_len ? \
1806 (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \
1809 req = (
struct ifreq *)((
char*)req + _SIZEOF_ADDR_IFREQ(*req));
1811 req = (
struct ifreq *)((
char*)req +
sizeof(
struct ifreq));
1829 #elif defined(_WIN32)
1830 typedef struct ip_adapter_unicast_address_st {
1832 struct ip_adapter_unicast_address_st *
Next;
1834 struct sockaddr *lpSockaddr;
1835 int iSockaddrLength;
1843 } ip_adapter_unicast_address_t;
1844 typedef struct ip_adapter_anycast_address_st {
1846 struct ip_adapter_anycast_address_st *
Next;
1848 struct sockaddr *lpSockaddr;
1849 int iSockaddrLength;
1851 } ip_adapter_anycast_address_t;
1852 typedef struct ip_adapter_addresses_st {
1854 struct ip_adapter_addresses_st *
Next;
1856 ip_adapter_unicast_address_t *FirstUnicastAddress;
1857 ip_adapter_anycast_address_t *FirstAnycastAddress;
1872 } ip_adapter_addresses_t;
1873 typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG, ULONG, PVOID, ip_adapter_addresses_t *, PULONG);
1875 GetAdaptersAddresses_t pGetAdaptersAddresses;
1878 ip_adapter_addresses_t *adapters;
1881 h = LoadLibrary(
"iphlpapi.dll");
1884 pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(
h,
"GetAdaptersAddresses");
1885 if (!pGetAdaptersAddresses) {
1891 if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) {
1896 adapters = (ip_adapter_addresses_t *)
ALLOCA_N(BYTE,
len);
1898 if (ret != ERROR_SUCCESS) {
1905 for (; adapters; adapters = adapters->Next) {
1906 ip_adapter_unicast_address_t *uni;
1907 ip_adapter_anycast_address_t *any;
1908 if (adapters->OperStatus != 1)
1910 for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) {
1912 if (uni->Address.lpSockaddr->sa_family == AF_INET)
1916 rb_ary_push(
list, sockaddr_obj(uni->Address.lpSockaddr, uni->Address.iSockaddrLength));
1918 for (any = adapters->FirstAnycastAddress; any; any = any->Next) {
1920 if (any->Address.lpSockaddr->sa_family == AF_INET)
1924 rb_ary_push(
list, sockaddr_obj(any->Address.lpSockaddr, any->Address.iSockaddrLength));
1933 #define socket_s_ip_address_list rb_f_notimplement
2067 "__connect_nonblock", sock_connect_nonblock, 2);
2075 "__accept_nonblock", sock_accept_nonblock, 1);
2083 "__recvfrom_nonblock", sock_recvfrom_nonblock, 4);
2097 #ifdef HAVE_SYS_UN_H