13 #if defined(INET6) && (defined(LOOKUP_ORDER_HACK_INET) || defined(LOOKUP_ORDER_HACK_INET6))
14 #define LOOKUP_ORDERS (sizeof(lookup_order_table) / sizeof(lookup_order_table[0]))
15 static const int lookup_order_table[] = {
16 #if defined(LOOKUP_ORDER_HACK_INET)
18 #elif defined(LOOKUP_ORDER_HACK_INET6)
26 ruby_getaddrinfo(
const char *nodename,
const char *servname,
36 for (i = 0; i < LOOKUP_ORDERS; i++) {
37 af = lookup_order_table[
i];
39 tmp_hints.ai_family = af;
40 error =
getaddrinfo(nodename, servname, &tmp_hints, res);
53 #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo((node),(serv),(hints),(res))
58 ruby_getaddrinfo__aix(
const char *nodename,
const char *servname,
61 int error =
getaddrinfo(nodename, servname, hints, res);
74 #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__aix((node),(serv),(hints),(res))
76 ruby_getnameinfo__aix(
const struct sockaddr *sa,
size_t salen,
77 char *host,
size_t hostlen,
78 char *serv,
size_t servlen,
int flags)
80 struct sockaddr_in6 *sa6;
83 if (sa->sa_family == AF_INET6) {
84 sa6 = (
struct sockaddr_in6 *)sa;
85 a6 = sa6->sin6_addr.u6_addr.u6_addr32;
87 if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) {
88 strncpy(host,
"::", hostlen);
89 snprintf(serv, servlen,
"%d", sa6->sin6_port);
93 return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
96 #define getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) \
97 ruby_getnameinfo__aix((sa), (salen), (host), (hostlen), (serv), (servlen), (flags))
102 #if defined(__APPLE__)
104 ruby_getaddrinfo__darwin(
const char *nodename,
const char *servname,
108 const char *tmp_servname;
112 tmp_servname = servname;
114 if (nodename && servname) {
117 #ifdef AI_NUMERICSERV
123 error =
getaddrinfo(nodename, tmp_servname, &tmp_hints, res);
145 #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__darwin((node),(serv),(hints),(res))
148 #ifndef GETADDRINFO_EMU
179 #ifdef GETADDRINFO_EMU
194 #ifndef GETADDRINFO_EMU
197 const struct sockaddr *
sa;
219 char *host,
size_t hostlen,
220 char *serv,
size_t servlen,
int flags)
222 #ifdef GETADDRINFO_EMU
223 return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
262 struct sockaddr_in sin;
264 MEMZERO(&sin,
struct sockaddr_in, 1);
265 sin.sin_family = AF_INET;
267 sin.sin_addr.s_addr = host;
276 if (!p || *p ==
'\0')
280 if (ep && *ep ==
'\0')
304 if (!name || *name == 0 || (name[0] ==
'<' && strcmp(name,
"<any>") == 0)) {
308 else if (name[0] ==
'<' && strcmp(name,
"<broadcast>") == 0) {
312 else if (
strlen(name) >= len) {
331 #ifdef AI_NUMERICSERV
341 if (
strlen(serv) >= len) {
357 int additional_flags = 0;
359 hostp =
host_str(host, hbuf,
sizeof(hbuf), &additional_flags);
360 portp =
port_str(port, pbuf,
sizeof(pbuf), &additional_flags);
365 hints->
ai_flags |= additional_flags;
369 if (hostp && hostp[
strlen(hostp)-1] ==
'\n') {
393 VALUE family, port, addr1, addr2;
396 char hbuf[1024], pbuf[1024];
399 id = rsock_intern_family(sockaddr->sa_family);
404 sprintf(pbuf,
"unknown:%d", sockaddr->sa_family);
433 rsock_unixpath_str(
struct sockaddr_un *sockaddr, socklen_t
len)
436 s = sockaddr->sun_path;
437 e = (
char *)sockaddr + len;
438 while (s < e && *(e-1) ==
'\0')
447 rsock_unixaddr(
struct sockaddr_un *sockaddr, socklen_t len)
450 rsock_unixpath_str(sockaddr, len));
454 rsock_unix_sockaddr_len(
VALUE path)
459 return (socklen_t)
sizeof(sa_family_t);
463 return (socklen_t)
offsetof(
struct sockaddr_un, sun_path) +
468 return (socklen_t)
sizeof(
struct sockaddr_un);
486 VALUE (*ipaddr)(
struct sockaddr*, size_t) = arg->
ipaddr;
506 if (h->h_aliases !=
NULL) {
507 for (pch = h->h_aliases; *pch; pch++) {
517 for (ai = addr; ai; ai = ai->
ai_next) {
518 rb_ary_push(ary, (*ipaddr)(ai->ai_addr, ai->ai_addrlen));
563 #define addrinfo_free RUBY_TYPED_DEFAULT_FREE
582 #define IS_ADDRINFO(obj) rb_typeddata_is_kind_of((obj), &addrinfo_type)
613 int pfamily,
int socktype,
int protocol,
616 if ((socklen_t)
sizeof(rai->
addr) < len)
618 memcpy((
void *)&rai->
addr, (
void *)sa, len);
630 int family,
int socktype,
int protocol,
638 init_addrinfo(rai, addr, len, family, socktype, protocol, canonname, inspectname);
652 if (!
NIL_P(socktype)) {
655 if (!
NIL_P(protocol)) {
687 canonname, inspectname);
701 sizeof(hbuf), pbuf,
sizeof(pbuf),
717 if (
NIL_P(inspectname))
724 if (
NIL_P(inspectname))
729 if (!
NIL_P(inspectname)) {
756 canonname, inspectname);
774 for (r = res; r; r = r->
ai_next) {
785 canonname, inspectname);
799 struct sockaddr_un un;
804 if (
sizeof(un.sun_path) < (
size_t)
RSTRING_LEN(path))
806 "too long unix socket path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
809 MEMZERO(&un,
struct sockaddr_un, 1);
811 un.sun_family = AF_UNIX;
814 len = rsock_unix_sockaddr_len(path);
870 VALUE sockaddr_arg, sockaddr_ary, pfamily, socktype, protocol;
871 int i_pfamily, i_socktype, i_protocol;
872 struct sockaddr *sockaddr_ptr;
873 socklen_t sockaddr_len;
880 rb_scan_args(argc, argv,
"13", &sockaddr_arg, &pfamily, &socktype, &protocol);
887 if (!
NIL_P(sockaddr_ary)) {
905 if (!
NIL_P(nodename))
909 #ifdef AI_NUMERICSERV
925 init_unix_addrinfo(rai, path, SOCK_STREAM);
936 sockaddr_ptr = (
struct sockaddr *)
RSTRING_PTR(sockaddr_arg);
939 i_pfamily, i_socktype, i_protocol,
940 canonname, inspectname);
949 if ((socklen_t)((
char*)&addr->sa_family +
sizeof(addr->sa_family) - (
char*)addr) <= len)
950 return addr->sa_family;
975 struct sockaddr_in *addr;
977 if (rai->
sockaddr_len < (socklen_t)
sizeof(
struct sockaddr_in)) {
981 addr = (
struct sockaddr_in *)&rai->
addr;
983 ((
unsigned char*)&addr->sin_addr)[0],
984 ((
unsigned char*)&addr->sin_addr)[1],
985 ((
unsigned char*)&addr->sin_addr)[2],
986 ((
unsigned char*)&addr->sin_addr)[3]);
987 port = ntohs(addr->sin_port);
990 if ((socklen_t)
sizeof(
struct sockaddr_in) < rai->
sockaddr_len)
999 struct sockaddr_in6 *addr;
1003 if (rai->
sockaddr_len < (socklen_t)
sizeof(
struct sockaddr_in6)) {
1007 addr = (
struct sockaddr_in6 *)&rai->
addr;
1013 hbuf, (socklen_t)
sizeof(hbuf),
NULL, 0,
1018 if (addr->sin6_port == 0) {
1022 port = ntohs(addr->sin6_port);
1025 if ((socklen_t)
sizeof(
struct sockaddr_in6) < rai->
sockaddr_len)
1032 #ifdef HAVE_SYS_UN_H
1035 struct sockaddr_un *addr = (
struct sockaddr_un *)&rai->
addr;
1039 while (s < e && *(e-1) ==
'\0')
1046 int printable_only = 1;
1052 if (printable_only) {
1062 if (addr->sun_path +
sizeof(addr->sun_path) < (
char*)&rai->
addr + rai->
sockaddr_len)
1064 (
int)(rai->
sockaddr_len - (addr->sun_path +
sizeof(addr->sun_path) - (
char*)&rai->
addr)));
1107 ID id = rsock_intern_protocol_family(rai->
pfamily);
1116 internet_p = internet_p || rai->
pfamily == PF_INET6;
1118 if (internet_p && rai->
socktype == SOCK_STREAM &&
1122 else if (internet_p && rai->
socktype == SOCK_DGRAM &&
1128 ID id = rsock_intern_socktype(rai->
socktype);
1141 goto unknown_protocol;
1186 VALUE sockaddr, afamily, pfamily, socktype, protocol, canonname, inspectname;
1190 id = rsock_intern_protocol_family(rai->
pfamily);
1198 id = rsock_intern_socktype(rai->
socktype);
1207 id = rsock_intern_ipproto(rai->
protocol);
1220 id = rsock_intern_family(afamily_int);
1225 switch(afamily_int) {
1226 #ifdef HAVE_SYS_UN_H
1229 struct sockaddr_un *su = (
struct sockaddr_un *)&rai->
addr;
1233 while (s < e && *(e-1) ==
'\0')
1245 hbuf, (socklen_t)
sizeof(hbuf), pbuf, (socklen_t)
sizeof(pbuf),
1255 return rb_ary_new3(7, afamily, sockaddr, pfamily, socktype, protocol, canonname, inspectname);
1263 VALUE canonname, inspectname;
1264 int afamily, pfamily, socktype, protocol;
1325 #ifdef HAVE_SYS_UN_H
1328 struct sockaddr_un uaddr;
1329 MEMZERO(&uaddr,
struct sockaddr_un, 1);
1330 uaddr.sun_family = AF_UNIX;
1333 if (
sizeof(uaddr.sun_path) < (
size_t)
RSTRING_LEN(v))
1335 "too long AF_UNIX path (%"PRIuSIZE
" bytes given but %"PRIuSIZE
" bytes max)",
1338 len = (socklen_t)
sizeof(uaddr);
1339 memcpy(&ss, &uaddr, len);
1349 #ifdef AI_NUMERICSERV
1364 pfamily, socktype, protocol,
1365 canonname, inspectname);
1581 char hbuf[1024], pbuf[1024];
1592 hbuf, (socklen_t)
sizeof(hbuf), pbuf, (socklen_t)
sizeof(pbuf),
1682 port = ntohs(((
struct sockaddr_in *)&rai->
addr)->sin_port);
1689 port = ntohs(((
struct sockaddr_in6 *)&rai->
addr)->sin6_port);
1705 if (family != AF_INET)
return 0;
1706 *addrp = ntohl(((
struct sockaddr_in *)&rai->
addr)->sin_addr.s_addr);
1719 if ((a & 0xff000000) == 0x0a000000 ||
1720 (a & 0xfff00000) == 0xac100000 ||
1721 (a & 0xffff0000) == 0xc0a80000)
1735 if ((a & 0xff000000) == 0x7f000000)
1749 if ((a & 0xf0000000) == 0xe0000000)
1756 static struct in6_addr *
1757 extract_in6_addr(
VALUE self)
1761 if (family != AF_INET6)
return NULL;
1762 return &((
struct sockaddr_in6 *)&rai->
addr)->sin6_addr;
1770 addrinfo_ipv6_unspecified_p(
VALUE self)
1772 struct in6_addr *addr = extract_in6_addr(
self);
1773 if (addr && IN6_IS_ADDR_UNSPECIFIED(addr))
return Qtrue;
1782 addrinfo_ipv6_loopback_p(
VALUE self)
1784 struct in6_addr *addr = extract_in6_addr(
self);
1785 if (addr && IN6_IS_ADDR_LOOPBACK(addr))
return Qtrue;
1794 addrinfo_ipv6_multicast_p(
VALUE self)
1796 struct in6_addr *addr = extract_in6_addr(
self);
1797 if (addr && IN6_IS_ADDR_MULTICAST(addr))
return Qtrue;
1806 addrinfo_ipv6_linklocal_p(
VALUE self)
1808 struct in6_addr *addr = extract_in6_addr(
self);
1809 if (addr && IN6_IS_ADDR_LINKLOCAL(addr))
return Qtrue;
1818 addrinfo_ipv6_sitelocal_p(
VALUE self)
1820 struct in6_addr *addr = extract_in6_addr(
self);
1821 if (addr && IN6_IS_ADDR_SITELOCAL(addr))
return Qtrue;
1830 addrinfo_ipv6_v4mapped_p(
VALUE self)
1832 struct in6_addr *addr = extract_in6_addr(
self);
1833 if (addr && IN6_IS_ADDR_V4MAPPED(addr))
return Qtrue;
1842 addrinfo_ipv6_v4compat_p(
VALUE self)
1844 struct in6_addr *addr = extract_in6_addr(
self);
1845 if (addr && IN6_IS_ADDR_V4COMPAT(addr))
return Qtrue;
1854 addrinfo_ipv6_mc_nodelocal_p(
VALUE self)
1856 struct in6_addr *addr = extract_in6_addr(
self);
1857 if (addr && IN6_IS_ADDR_MC_NODELOCAL(addr))
return Qtrue;
1866 addrinfo_ipv6_mc_linklocal_p(
VALUE self)
1868 struct in6_addr *addr = extract_in6_addr(
self);
1869 if (addr && IN6_IS_ADDR_MC_LINKLOCAL(addr))
return Qtrue;
1878 addrinfo_ipv6_mc_sitelocal_p(
VALUE self)
1880 struct in6_addr *addr = extract_in6_addr(
self);
1881 if (addr && IN6_IS_ADDR_MC_SITELOCAL(addr))
return Qtrue;
1890 addrinfo_ipv6_mc_orglocal_p(
VALUE self)
1892 struct in6_addr *addr = extract_in6_addr(
self);
1893 if (addr && IN6_IS_ADDR_MC_ORGLOCAL(addr))
return Qtrue;
1902 addrinfo_ipv6_mc_global_p(
VALUE self)
1904 struct in6_addr *addr = extract_in6_addr(
self);
1905 if (addr && IN6_IS_ADDR_MC_GLOBAL(addr))
return Qtrue;
1920 addrinfo_ipv6_to_ipv4(
VALUE self)
1923 struct in6_addr *addr;
1925 if (family != AF_INET6)
return Qnil;
1926 addr = &((
struct sockaddr_in6 *)&rai->
addr)->sin6_addr;
1927 if (IN6_IS_ADDR_V4MAPPED(addr) || IN6_IS_ADDR_V4COMPAT(addr)) {
1928 struct sockaddr_in sin4;
1929 MEMZERO(&sin4,
struct sockaddr_in, 1);
1930 sin4.sin_family = AF_INET;
1932 memcpy(&sin4.sin_addr, (
char*)addr +
sizeof(*addr) -
sizeof(sin4.sin_addr),
sizeof(sin4.sin_addr));
1944 #ifdef HAVE_SYS_UN_H
1954 addrinfo_unix_path(
VALUE self)
1958 struct sockaddr_un *addr;
1961 if (family != AF_UNIX)
1964 addr = (
struct sockaddr_un *)&rai->
addr;
1970 if (addr->sun_path +
sizeof(addr->sun_path) < e)
1972 while (s < e && *(e-1) ==
'\0')
2015 VALUE node, service, family, socktype, protocol, flags;
2017 rb_scan_args(argc, argv,
"24", &node, &service, &family, &socktype, &protocol, &flags);
2075 #ifdef HAVE_SYS_UN_H
2092 VALUE path, vsocktype, addr;
2098 if (
NIL_P(vsocktype))
2099 socktype = SOCK_STREAM;
2105 init_unix_addrinfo(rai, path, socktype);
2144 socklen_t optlen = (socklen_t)
sizeof(socktype);
2149 ret = getsockopt(fd, SOL_SOCKET, SO_TYPE, (
void*)&socktype, &optlen);
2197 #ifdef HAVE_SYS_UN_H
2237 #ifdef HAVE_SYS_UN_H