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]))
15static const int lookup_order_table[] = {
16#if defined(LOOKUP_ORDER_HACK_INET)
18#elif defined(LOOKUP_ORDER_HACK_INET6)
26ruby_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;
53#define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo((node),(serv),(hints),(res))
58ruby_getaddrinfo__aix(
const char *nodename,
const char *servname,
74#define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__aix((node),(serv),(hints),(res))
76ruby_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) {
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))
100static int str_is_number(
const char *);
102#if defined(__APPLE__)
104ruby_getaddrinfo__darwin(
const char *nodename,
const char *servname,
108 const char *tmp_servname;
112 tmp_servname = servname;
114 if (nodename && servname) {
115 if (str_is_number(tmp_servname) &&
atoi(servname) == 0) {
118 if (tmp_hints.ai_flags) tmp_hints.ai_flags &= ~AI_NUMERICSERV;
145#define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__darwin((node),(serv),(hints),(res))
150parse_numeric_port(
const char *service,
int *portp)
176#ifndef GETADDRINFO_EMU
186nogvl_getaddrinfo(
void *
arg)
198 return (
void *)(
VALUE)ret;
202#ifdef HAVE_GETADDRINFO_A
203struct gai_suspend_arg
210nogvl_gai_suspend(
void *
arg)
213 struct gai_suspend_arg *
ptr =
arg;
214 struct gaicb
const *wait_reqs[1];
216 wait_reqs[0] =
ptr->req;
217 ret = gai_suspend(wait_reqs, 1,
ptr->timeout);
219 return (
void *)(
VALUE)ret;
224numeric_getaddrinfo(
const char *node,
const char *service,
229# if defined __MINGW64__
230# define inet_pton(f,s,d) rb_w32_inet_pton(f,s,d)
235 if (node && parse_numeric_port(service, &port)) {
236 static const struct {
246 int hint_socktype = hints ? hints->
ai_socktype : 0;
247 int hint_protocol = hints ? hints->
ai_protocol : 0;
251 if ((hint_family ==
PF_UNSPEC || hint_family == PF_INET6) &&
252 strspn(node,
"0123456789abcdefABCDEF.:") ==
strlen(node) &&
253 inet_pton(AF_INET6, node, ipv6addr)) {
256 if ((hint_socktype == 0 || hint_socktype ==
list[
i].socktype) &&
257 (hint_protocol == 0 ||
list[
i].protocol == 0 || hint_protocol ==
list[
i].protocol)) {
259 struct sockaddr_in6 *sa =
xmalloc(
sizeof(
struct sockaddr_in6));
261 memcpy(&sa->sin6_addr, ipv6addr,
sizeof(ipv6addr));
262 sa->sin6_port = htons(port);
266 ai0->
ai_addrlen =
sizeof(
struct sockaddr_in6);
267 ai0->
ai_addr = (
struct sockaddr *)sa;
278 inet_pton(AF_INET, node, ipv4addr)) {
281 if ((hint_socktype == 0 || hint_socktype ==
list[
i].socktype) &&
282 (hint_protocol == 0 ||
list[
i].protocol == 0 || hint_protocol ==
list[
i].protocol)) {
284 struct sockaddr_in *sa =
xmalloc(
sizeof(
struct sockaddr_in));
286 memcpy(&sa->sin_addr, ipv4addr,
sizeof(ipv4addr));
287 sa->sin_port = htons(port);
292 ai0->
ai_addr = (
struct sockaddr *)sa;
315 int allocated_by_malloc = 0;
317 ret = numeric_getaddrinfo(node, service, hints, &ai);
319 allocated_by_malloc = 1;
321#ifdef GETADDRINFO_EMU
342#ifdef HAVE_GETADDRINFO_A
344rb_getaddrinfo_a(
const char *node,
const char *service,
350 int allocated_by_malloc = 0;
352 ret = numeric_getaddrinfo(node, service, hints, &ai);
354 allocated_by_malloc = 1;
356 struct gai_suspend_arg
arg;
357 struct gaicb *reqs[1];
361 req.ar_service = service;
362 req.ar_request = hints;
365 ret = getaddrinfo_a(GAI_NOWAIT, reqs, 1,
NULL);
369 arg.timeout = timeout;
382 ret = gai_error(reqs[0]);
383 ai = reqs[0]->ar_result;
398 if (!
ai->allocated_by_malloc)
413#ifndef GETADDRINFO_EMU
416 const struct sockaddr *
sa;
426nogvl_getnameinfo(
void *
arg)
441#ifdef GETADDRINFO_EMU
459make_ipaddr0(
struct sockaddr *addr,
socklen_t addrlen,
char *
buf,
size_t buflen)
474 make_ipaddr0(addr, addrlen, hbuf,
sizeof(hbuf));
479make_inetaddr(
unsigned int host,
char *
buf,
size_t buflen)
481 struct sockaddr_in
sin;
484 sin.sin_addr.s_addr = host;
485 make_ipaddr0((
struct sockaddr*)&
sin,
sizeof(
sin),
buf, buflen);
489str_is_number(
const char *p)
493 if (!p || *p ==
'\0')
497 if (ep && *ep ==
'\0')
503#define str_equal(ptr, len, name) \
504 ((ptr)[0] == name[0] && \
505 rb_strlen_lit(name) == (len) && memcmp(ptr, name, len) == 0)
508host_str(
VALUE host,
char *hbuf,
size_t hbuflen,
int *flags_ptr)
516 make_inetaddr(htonl(
i), hbuf, hbuflen);
534 else if (
len >= hbuflen) {
547port_str(
VALUE port,
char *pbuf,
size_t pbuflen,
int *flags_ptr)
565 if (
len >= pbuflen) {
582 int additional_flags = 0;
584 hostp = host_str(host, hbuf,
sizeof(hbuf), &additional_flags);
585 portp = port_str(port, pbuf,
sizeof(pbuf), &additional_flags);
587 if (socktype_hack && hints->
ai_socktype == 0 && str_is_number(portp)) {
590 hints->
ai_flags |= additional_flags;
594 if (hostp && hostp[
strlen(hostp)-1] ==
'\n') {
603#ifdef HAVE_GETADDRINFO_A
611 int additional_flags = 0;
613 hostp = host_str(host, hbuf,
sizeof(hbuf), &additional_flags);
614 portp = port_str(port, pbuf,
sizeof(pbuf), &additional_flags);
616 if (socktype_hack && hints->
ai_socktype == 0 && str_is_number(portp)) {
619 hints->
ai_flags |= additional_flags;
621 if (
NIL_P(timeout)) {
625 error = rb_getaddrinfo_a(hostp, portp, hints, &res, &_timeout);
629 if (hostp && hostp[
strlen(hostp)-1] ==
'\n') {
642 struct sockaddr sa = { 0 };
645 if (fd < 0 || getsockname(fd, &sa, &sa_len) != 0 ||
646 (
size_t)sa_len <
offsetof(
struct sockaddr, sa_family) +
sizeof(sa.sa_family)) {
667 VALUE family, port, addr1, addr2;
670 char hbuf[1024], pbuf[1024];
678 sprintf(pbuf,
"unknown:%d", sockaddr->sa_family);
707unixsocket_len(
const struct sockaddr_un *su,
socklen_t socklen)
709 const char *s = su->sun_path, *e = (
const char*)su + socklen;
710 while (s < e && *(e-1) ==
'\0')
716rsock_unixpath_str(
struct sockaddr_un *sockaddr,
socklen_t len)
718 long n = unixsocket_len(sockaddr,
len);
726rsock_unixaddr(
struct sockaddr_un *sockaddr,
socklen_t len)
729 rsock_unixpath_str(sockaddr,
len));
749 return (
socklen_t)
sizeof(
struct sockaddr_un);
763make_hostent_internal(
VALUE v)
782 hostp = host_str(host, hbuf,
sizeof(hbuf),
NULL);
789 if (
h->h_aliases !=
NULL) {
790 for (pch =
h->h_aliases; *pch; pch++) {
800 for (ai = addr; ai; ai = ai->
ai_next) {
838addrinfo_mark(
void *
ptr)
845#define addrinfo_free RUBY_TYPED_DEFAULT_FREE
848addrinfo_memsize(
const void *
ptr)
864#define IS_ADDRINFO(obj) rb_typeddata_is_kind_of((obj), &addrinfo_type)
866check_addrinfo(
VALUE self)
872get_addrinfo(
VALUE self)
894 int pfamily,
int socktype,
int protocol,
911 int family,
int socktype,
int protocol,
918 DATA_PTR(a) = rai = alloc_addrinfo();
919 init_addrinfo(rai, addr,
len, family, socktype, protocol, canonname, inspectname);
926 int socktype_hack,
VALUE timeout)
934 if (!
NIL_P(socktype)) {
937 if (!
NIL_P(protocol)) {
944#ifdef HAVE_GETADDRINFO_A
945 if (
NIL_P(timeout)) {
948 res = rsock_getaddrinfo_a(node, service, &hints, socktype_hack, timeout);
966 struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 1,
Qnil);
968 VALUE inspectname =
rb_str_equal(node, inspectnode) ?
Qnil : make_inspectname(inspectnode, inspectservice, res->
ai);
978 canonname, inspectname);
993 sizeof(hbuf), pbuf,
sizeof(pbuf),
1009 if (
NIL_P(inspectname))
1016 if (
NIL_P(inspectname))
1021 if (!
NIL_P(inspectname)) {
1034 struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0,
Qnil);
1036 inspectname = make_inspectname(node, service, res->
ai);
1047 canonname, inspectname);
1060 struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0, timeout);
1062 inspectname = make_inspectname(node, service, res->
ai);
1076 canonname, inspectname);
1090 struct sockaddr_un un;
1097 "too long unix socket path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
1100 INIT_SOCKADDR_UN(&un,
sizeof(
struct sockaddr_un));
1103 len = rsock_unix_sockaddr_len(
path);
1104 init_addrinfo(rai, (
struct sockaddr *)&un,
len,
1165 VALUE sockaddr_arg, sockaddr_ary, pfamily, socktype, protocol;
1166 int i_pfamily, i_socktype, i_protocol;
1167 struct sockaddr *sockaddr_ptr;
1171 if (check_addrinfo(
self))
1173 DATA_PTR(
self) = rai = alloc_addrinfo();
1182 if (!
NIL_P(sockaddr_ary)) {
1200 if (!
NIL_P(nodename))
1204#ifdef AI_NUMERICSERV
1208 init_addrinfo_getaddrinfo(rai, numericnode, service,
1220 init_unix_addrinfo(rai,
path, SOCK_STREAM);
1231 sockaddr_ptr = (
struct sockaddr *)
RSTRING_PTR(sockaddr_arg);
1233 init_addrinfo(rai, sockaddr_ptr, sockaddr_len,
1234 i_pfamily, i_socktype, i_protocol,
1235 canonname, inspectname);
1244 if ((
socklen_t)((
const char*)&addr->sa_family +
sizeof(addr->sa_family) - (
char*)addr) <=
len)
1245 return addr->sa_family;
1272 else if ((
long)socklen < ((
char*)&sockaddr->
addr.sa_family +
sizeof(sockaddr->
addr.sa_family)) - (
char*)sockaddr)
1275 switch (sockaddr->
addr.sa_family) {
1284 struct sockaddr_in *addr;
1286 addr = &sockaddr->
in;
1287 if ((
socklen_t)(((
char*)&addr->sin_addr)-(
char*)addr+0+1) <= socklen)
1288 rb_str_catf(ret,
"%d", ((
unsigned char*)&addr->sin_addr)[0]);
1291 if ((
socklen_t)(((
char*)&addr->sin_addr)-(
char*)addr+1+1) <= socklen)
1292 rb_str_catf(ret,
".%d", ((
unsigned char*)&addr->sin_addr)[1]);
1295 if ((
socklen_t)(((
char*)&addr->sin_addr)-(
char*)addr+2+1) <= socklen)
1296 rb_str_catf(ret,
".%d", ((
unsigned char*)&addr->sin_addr)[2]);
1299 if ((
socklen_t)(((
char*)&addr->sin_addr)-(
char*)addr+3+1) <= socklen)
1300 rb_str_catf(ret,
".%d", ((
unsigned char*)&addr->sin_addr)[3]);
1304 if ((
socklen_t)(((
char*)&addr->sin_port)-(
char*)addr+(
int)
sizeof(addr->sin_port)) < socklen) {
1305 port = ntohs(addr->sin_port);
1312 if ((
socklen_t)
sizeof(
struct sockaddr_in) != socklen)
1313 rb_str_catf(ret,
" (%d bytes for %d bytes sockaddr_in)",
1315 (
int)
sizeof(
struct sockaddr_in));
1322 struct sockaddr_in6 *addr;
1326 if (socklen < (
socklen_t)
sizeof(
struct sockaddr_in6)) {
1327 rb_str_catf(ret,
"too-short-AF_INET6-sockaddr %d bytes", (
int)socklen);
1330 addr = &sockaddr->in6;
1341 if (addr->sin6_port == 0) {
1345 port = ntohs(addr->sin6_port);
1348 if ((
socklen_t)
sizeof(
struct sockaddr_in6) < socklen)
1349 rb_str_catf(ret,
"(sockaddr %d bytes too long)", (
int)(socklen -
sizeof(
struct sockaddr_in6)));
1358 struct sockaddr_un *addr = &sockaddr->un;
1360 long len = unixsocket_len(addr, socklen);
1367 int printable_only = 1;
1374 if (printable_only) {
1389#if defined(AF_PACKET) && defined(__linux__)
1393 struct sockaddr_ll *addr;
1394 const char *sep =
"[";
1395#define CATSEP do { rb_str_cat2(ret, sep); sep = " "; } while (0);
1397 addr = (
struct sockaddr_ll *)sockaddr;
1401 if (
offsetof(
struct sockaddr_ll, sll_protocol) +
sizeof(addr->sll_protocol) <= (
size_t)socklen) {
1403 rb_str_catf(ret,
"protocol=%d", ntohs(addr->sll_protocol));
1405 if (
offsetof(
struct sockaddr_ll, sll_ifindex) +
sizeof(addr->sll_ifindex) <= (
size_t)socklen) {
1408 if (if_indextoname(addr->sll_ifindex,
buf) ==
NULL)
1409 rb_str_catf(ret,
"ifindex=%d", addr->sll_ifindex);
1413 if (
offsetof(
struct sockaddr_ll, sll_hatype) +
sizeof(addr->sll_hatype) <= (
size_t)socklen) {
1417 if (
offsetof(
struct sockaddr_ll, sll_pkttype) +
sizeof(addr->sll_pkttype) <= (
size_t)socklen) {
1419 if (addr->sll_pkttype == PACKET_HOST)
1421 else if (addr->sll_pkttype == PACKET_BROADCAST)
1423 else if (addr->sll_pkttype == PACKET_MULTICAST)
1425 else if (addr->sll_pkttype == PACKET_OTHERHOST)
1427 else if (addr->sll_pkttype == PACKET_OUTGOING)
1430 rb_str_catf(ret,
"pkttype=%d", addr->sll_pkttype);
1432 if (socklen != (
socklen_t)(
offsetof(
struct sockaddr_ll, sll_addr) + addr->sll_halen)) {
1434 if (
offsetof(
struct sockaddr_ll, sll_halen) +
sizeof(addr->sll_halen) <= (
size_t)socklen) {
1438 if (
offsetof(
struct sockaddr_ll, sll_addr) < (
size_t)socklen) {
1442 len = addr->sll_halen;
1443 if ((
size_t)socklen <
offsetof(
struct sockaddr_ll, sll_addr) +
len)
1444 len = socklen -
offsetof(
struct sockaddr_ll, sll_addr);
1445 for (
i = 0;
i <
len;
i++) {
1451 if (socklen < (
socklen_t)(
offsetof(
struct sockaddr_ll, sll_halen) +
sizeof(addr->sll_halen)) ||
1452 (
socklen_t)(
offsetof(
struct sockaddr_ll, sll_addr) + addr->sll_halen) != socklen) {
1454 rb_str_catf(ret,
"(%d bytes for %d bytes sockaddr_ll)",
1455 (
int)socklen, (
int)
sizeof(
struct sockaddr_ll));
1465#if defined(AF_LINK) && defined(HAVE_TYPE_STRUCT_SOCKADDR_DL)
1480 struct sockaddr_dl *addr = &sockaddr->dl;
1481 char *np =
NULL, *ap =
NULL, *endp;
1482 int nlen = 0, alen = 0;
1484 const char *sep =
"[";
1485#define CATSEP do { rb_str_cat2(ret, sep); sep = " "; } while (0);
1489 endp = ((
char *)addr) + socklen;
1491 if (
offsetof(
struct sockaddr_dl, sdl_data) < socklen) {
1492 np = addr->sdl_data;
1493 nlen = addr->sdl_nlen;
1494 if (endp - np < nlen)
1495 nlen = (
int)(endp - np);
1497 off = addr->sdl_nlen;
1499 if (
offsetof(
struct sockaddr_dl, sdl_data) + off < socklen) {
1500 ap = addr->sdl_data + off;
1501 alen = addr->sdl_alen;
1502 if (endp - ap < alen)
1503 alen = (
int)(endp - ap);
1512 if (ap && 0 < alen) {
1514 for (
i = 0;
i < alen;
i++)
1515 rb_str_catf(ret,
"%s%02x",
i == 0 ?
"" :
":", (
unsigned char)ap[
i]);
1518 if (socklen < (
socklen_t)(
offsetof(
struct sockaddr_dl, sdl_nlen) +
sizeof(addr->sdl_nlen)) ||
1519 socklen < (
socklen_t)(
offsetof(
struct sockaddr_dl, sdl_alen) +
sizeof(addr->sdl_alen)) ||
1520 socklen < (
socklen_t)(
offsetof(
struct sockaddr_dl, sdl_slen) +
sizeof(addr->sdl_slen)) ||
1523 socklen < (
socklen_t)(
offsetof(
struct sockaddr_dl, sdl_data) + addr->sdl_nlen + addr->sdl_alen + addr->sdl_slen)) {
1525 rb_str_catf(ret,
"(%d bytes for %d bytes sockaddr_dl)",
1526 (
int)socklen, (
int)
sizeof(
struct sockaddr_dl));
1539 rb_str_catf(ret,
"unknown address family %d", sockaddr->
addr.sa_family);
1561addrinfo_inspect(
VALUE self)
1569 inspect_sockaddr(
self, ret);
1581 internet_p = internet_p || rai->
pfamily == PF_INET6;
1583 if (internet_p && rai->
socktype == SOCK_STREAM &&
1587 else if (internet_p && rai->
socktype == SOCK_DGRAM &&
1606 goto unknown_protocol;
1643 return inspect_sockaddr(
self,
rb_str_new(
"", 0));
1648addrinfo_mdump(
VALUE self)
1651 VALUE sockaddr, afamily, pfamily, socktype, protocol, canonname, inspectname;
1652 int afamily_int = ai_get_afamily(rai);
1690 switch(afamily_int) {
1694 sockaddr =
rb_str_new(rai->
addr.un.sun_path, rai_unixsocket_len(rai));
1714 return rb_ary_new3(7, afamily, sockaddr, pfamily, socktype, protocol, canonname, inspectname);
1722 VALUE canonname, inspectname;
1723 int afamily, pfamily, socktype, protocol;
1728 if (check_addrinfo(
self))
1787 struct sockaddr_un uaddr;
1788 INIT_SOCKADDR_UN(&uaddr,
sizeof(
struct sockaddr_un));
1793 "too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
1807#ifdef AI_NUMERICSERV
1821 DATA_PTR(
self) = rai = alloc_addrinfo();
1822 init_addrinfo(rai, &ss.
addr,
len,
1823 pfamily, socktype, protocol,
1824 canonname, inspectname);
1838addrinfo_afamily(
VALUE self)
1841 return INT2NUM(ai_get_afamily(rai));
1854addrinfo_pfamily(
VALUE self)
1870addrinfo_socktype(
VALUE self)
1886addrinfo_protocol(
VALUE self)
1904addrinfo_to_sockaddr(
VALUE self)
1928addrinfo_canonname(
VALUE self)
1947addrinfo_ip_p(
VALUE self)
1950 int family = ai_get_afamily(rai);
1967addrinfo_ipv4_p(
VALUE self)
1970 return ai_get_afamily(rai) == AF_INET ?
Qtrue :
Qfalse;
1986addrinfo_ipv6_p(
VALUE self)
1990 return ai_get_afamily(rai) == AF_INET6 ?
Qtrue :
Qfalse;
2009addrinfo_unix_p(
VALUE self)
2013 return ai_get_afamily(rai) == AF_UNIX ?
Qtrue :
Qfalse;
2039 char hbuf[1024], pbuf[1024];
2069addrinfo_ip_unpack(
VALUE self)
2072 int family = ai_get_afamily(rai);
2080 ret = addrinfo_getnameinfo(1, &vflags,
self);
2096addrinfo_ip_address(
VALUE self)
2099 int family = ai_get_afamily(rai);
2107 ret = addrinfo_getnameinfo(1, &vflags,
self);
2121addrinfo_ip_port(
VALUE self)
2124 int family = ai_get_afamily(rai);
2140 port = ntohs(rai->
addr.
in.sin_port);
2147 port = ntohs(rai->
addr.in6.sin6_port);
2162 int family = ai_get_afamily(rai);
2163 if (family != AF_INET)
return 0;
2164 *addrp = ntohl(rai->
addr.
in.sin_addr.s_addr);
2173addrinfo_ipv4_private_p(
VALUE self)
2176 if (!extract_in_addr(
self, &a))
return Qfalse;
2177 if ((a & 0xff000000) == 0x0a000000 ||
2178 (a & 0xfff00000) == 0xac100000 ||
2179 (a & 0xffff0000) == 0xc0a80000)
2189addrinfo_ipv4_loopback_p(
VALUE self)
2192 if (!extract_in_addr(
self, &a))
return Qfalse;
2193 if ((a & 0xff000000) == 0x7f000000)
2203addrinfo_ipv4_multicast_p(
VALUE self)
2206 if (!extract_in_addr(
self, &a))
return Qfalse;
2207 if ((a & 0xf0000000) == 0xe0000000)
2214static struct in6_addr *
2215extract_in6_addr(
VALUE self)
2218 int family = ai_get_afamily(rai);
2219 if (family != AF_INET6)
return NULL;
2220 return &rai->
addr.in6.sin6_addr;
2228addrinfo_ipv6_unspecified_p(
VALUE self)
2230 struct in6_addr *addr = extract_in6_addr(
self);
2231 if (addr && IN6_IS_ADDR_UNSPECIFIED(addr))
return Qtrue;
2240addrinfo_ipv6_loopback_p(
VALUE self)
2242 struct in6_addr *addr = extract_in6_addr(
self);
2243 if (addr && IN6_IS_ADDR_LOOPBACK(addr))
return Qtrue;
2252addrinfo_ipv6_multicast_p(
VALUE self)
2254 struct in6_addr *addr = extract_in6_addr(
self);
2255 if (addr && IN6_IS_ADDR_MULTICAST(addr))
return Qtrue;
2264addrinfo_ipv6_linklocal_p(
VALUE self)
2266 struct in6_addr *addr = extract_in6_addr(
self);
2267 if (addr && IN6_IS_ADDR_LINKLOCAL(addr))
return Qtrue;
2276addrinfo_ipv6_sitelocal_p(
VALUE self)
2278 struct in6_addr *addr = extract_in6_addr(
self);
2279 if (addr && IN6_IS_ADDR_SITELOCAL(addr))
return Qtrue;
2288addrinfo_ipv6_unique_local_p(
VALUE self)
2290 struct in6_addr *addr = extract_in6_addr(
self);
2300addrinfo_ipv6_v4mapped_p(
VALUE self)
2302 struct in6_addr *addr = extract_in6_addr(
self);
2303 if (addr && IN6_IS_ADDR_V4MAPPED(addr))
return Qtrue;
2312addrinfo_ipv6_v4compat_p(
VALUE self)
2314 struct in6_addr *addr = extract_in6_addr(
self);
2315 if (addr && IN6_IS_ADDR_V4COMPAT(addr))
return Qtrue;
2324addrinfo_ipv6_mc_nodelocal_p(
VALUE self)
2326 struct in6_addr *addr = extract_in6_addr(
self);
2327 if (addr && IN6_IS_ADDR_MC_NODELOCAL(addr))
return Qtrue;
2336addrinfo_ipv6_mc_linklocal_p(
VALUE self)
2338 struct in6_addr *addr = extract_in6_addr(
self);
2339 if (addr && IN6_IS_ADDR_MC_LINKLOCAL(addr))
return Qtrue;
2348addrinfo_ipv6_mc_sitelocal_p(
VALUE self)
2350 struct in6_addr *addr = extract_in6_addr(
self);
2351 if (addr && IN6_IS_ADDR_MC_SITELOCAL(addr))
return Qtrue;
2360addrinfo_ipv6_mc_orglocal_p(
VALUE self)
2362 struct in6_addr *addr = extract_in6_addr(
self);
2363 if (addr && IN6_IS_ADDR_MC_ORGLOCAL(addr))
return Qtrue;
2372addrinfo_ipv6_mc_global_p(
VALUE self)
2374 struct in6_addr *addr = extract_in6_addr(
self);
2375 if (addr && IN6_IS_ADDR_MC_GLOBAL(addr))
return Qtrue;
2390addrinfo_ipv6_to_ipv4(
VALUE self)
2393 struct in6_addr *addr;
2394 int family = ai_get_afamily(rai);
2395 if (family != AF_INET6)
return Qnil;
2396 addr = &rai->
addr.in6.sin6_addr;
2397 if (IN6_IS_ADDR_V4MAPPED(addr) || IN6_IS_ADDR_V4COMPAT(addr)) {
2398 struct sockaddr_in sin4;
2400 memcpy(&sin4.sin_addr, (
char*)addr +
sizeof(*addr) -
sizeof(sin4.sin_addr),
sizeof(sin4.sin_addr));
2422addrinfo_unix_path(
VALUE self)
2425 int family = ai_get_afamily(rai);
2426 struct sockaddr_un *addr;
2429 if (family != AF_UNIX)
2432 addr = &rai->
addr.un;
2434 n = rai_unixsocket_len(rai);
2438 if ((
long)
sizeof(addr->sun_path) <
n)
2440 "too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
2441 (
size_t)
n,
sizeof(addr->sun_path));
2446static ID id_timeout;
2494 VALUE node, service, family, socktype, protocol, flags, opts, timeout;
2497 &protocol, &flags, &opts);
2501 return addrinfo_list_new(node, service, family, socktype, protocol, flags, timeout);
2520 ret = addrinfo_firstonly_new(host,
Qnil,
2522 rai = get_addrinfo(ret);
2539 return addrinfo_firstonly_new(host, port,
2554 return addrinfo_firstonly_new(host, port,
2581 if (
NIL_P(vsocktype))
2582 socktype = SOCK_STREAM;
2587 DATA_PTR(addr) = rai = alloc_addrinfo();
2588 init_unix_addrinfo(rai,
path, socktype);
2599 *
v = addrinfo_to_sockaddr(val);
2611 *
v = addrinfo_to_sockaddr(val);
2629 return addrinfo_to_sockaddr(val);
2642 family = get_afamily(addr,
len);
2644 ret = getsockopt(fd, SOL_SOCKET, SO_TYPE, (
void*)&socktype, &optlen);
int rsock_family_arg(VALUE domain)
int rsock_socktype_arg(VALUE type)
int rsock_family_to_int(const char *str, long len, int *valp)
int rsock_socktype_to_int(const char *str, long len, int *valp)
ID rsock_intern_family(int val)
ID rsock_intern_socktype(int val)
int rsock_ipproto_to_int(const char *str, long len, int *valp)
ID rsock_intern_ipproto(int val)
ID rsock_intern_protocol_family(int val)
struct rb_encoding_entry * list
void freeaddrinfo(struct addrinfo *ai)
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
VALUE rb_define_class(const char *, VALUE)
Defines a top-level class.
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *)
VALUE rb_cData
Data class.
void rb_raise(VALUE exc, const char *fmt,...)
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
VALUE rb_ensure(VALUE(*)(VALUE), VALUE, VALUE(*)(VALUE), VALUE)
An equivalent to ensure clause.
void rb_sys_fail(const char *mesg)
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Converts an object into another type.
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
#define GetOpenFile(obj, fp)
unsigned char buf[MIME_BUF_SIZE]
void rb_freeaddrinfo(struct rb_addrinfo *ai)
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname)
VALUE rsock_sockaddr_string_value(volatile VALUE *v)
VALUE rsock_freeaddrinfo(VALUE arg)
void rsock_init_addrinfo(void)
char * rsock_sockaddr_string_value_ptr(volatile VALUE *v)
struct rb_addrinfo * rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack)
VALUE rsock_make_hostent(VALUE host, struct rb_addrinfo *addr, VALUE(*ipaddr)(struct sockaddr *, socklen_t))
VALUE rsock_make_ipaddr(struct sockaddr *addr, socklen_t addrlen)
VALUE rsock_addrinfo_inspect_sockaddr(VALUE self)
#define str_equal(ptr, len, name)
VALUE rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE ret)
VALUE rb_check_sockaddr_string_type(VALUE val)
VALUE rsock_sockaddr_string_value_with_addrinfo(volatile VALUE *v, VALUE *rai_ret)
int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct rb_addrinfo **res)
struct rb_addrinfo * rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags)
VALUE rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup)
int rsock_fd_family(int fd)
int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len)
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
#define IN6_IS_ADDR_UNIQUE_LOCAL(a)
void rsock_raise_socket_error(const char *reason, int error)
#define INIT_SOCKADDR_IN(addr, len)
#define INIT_SOCKADDR_IN6(addr, len)
struct sockaddr * ai_addr
struct addrinfo * ai_next
const struct addrinfo * hints
const struct sockaddr * sa
VALUE(* ipaddr)(struct sockaddr *, socklen_t)
struct rb_addrinfo * addr
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)