Ruby  2.0.0p353(2013-11-22revision43784)
raddrinfo.c
Go to the documentation of this file.
1 /************************************************
2 
3  ainfo.c -
4 
5  created at: Thu Mar 31 12:21:29 JST 1994
6 
7  Copyright (C) 1993-2007 Yukihiro Matsumoto
8 
9 ************************************************/
10 
11 #include "rubysocket.h"
12 
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)
17  PF_INET, PF_INET6, PF_UNSPEC,
18 #elif defined(LOOKUP_ORDER_HACK_INET6)
19  PF_INET6, PF_INET, PF_UNSPEC,
20 #else
21  /* should not happen */
22 #endif
23 };
24 
25 static int
26 ruby_getaddrinfo(const char *nodename, const char *servname,
27  const struct addrinfo *hints, struct addrinfo **res)
28 {
29  struct addrinfo tmp_hints;
30  int i, af, error;
31 
32  if (hints->ai_family != PF_UNSPEC) {
33  return getaddrinfo(nodename, servname, hints, res);
34  }
35 
36  for (i = 0; i < LOOKUP_ORDERS; i++) {
37  af = lookup_order_table[i];
38  MEMCPY(&tmp_hints, hints, struct addrinfo, 1);
39  tmp_hints.ai_family = af;
40  error = getaddrinfo(nodename, servname, &tmp_hints, res);
41  if (error) {
42  if (tmp_hints.ai_family == PF_UNSPEC) {
43  break;
44  }
45  }
46  else {
47  break;
48  }
49  }
50 
51  return error;
52 }
53 #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo((node),(serv),(hints),(res))
54 #endif
55 
56 #if defined(_AIX)
57 static int
58 ruby_getaddrinfo__aix(const char *nodename, const char *servname,
59  const struct addrinfo *hints, struct addrinfo **res)
60 {
61  int error = getaddrinfo(nodename, servname, hints, res);
62  struct addrinfo *r;
63  if (error)
64  return error;
65  for (r = *res; r != NULL; r = r->ai_next) {
66  if (r->ai_addr->sa_family == 0)
67  r->ai_addr->sa_family = r->ai_family;
68  if (r->ai_addr->sa_len == 0)
69  r->ai_addr->sa_len = r->ai_addrlen;
70  }
71  return 0;
72 }
73 #undef getaddrinfo
74 #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__aix((node),(serv),(hints),(res))
75 static int
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)
79 {
80  struct sockaddr_in6 *sa6;
81  u_int32_t *a6;
82 
83  if (sa->sa_family == AF_INET6) {
84  sa6 = (struct sockaddr_in6 *)sa;
85  a6 = sa6->sin6_addr.u6_addr.u6_addr32;
86 
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);
90  return 0;
91  }
92  }
93  return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
94 }
95 #undef getnameinfo
96 #define getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) \
97  ruby_getnameinfo__aix((sa), (salen), (host), (hostlen), (serv), (servlen), (flags))
98 #endif
99 
100 static int str_is_number(const char *);
101 
102 #if defined(__APPLE__)
103 static int
104 ruby_getaddrinfo__darwin(const char *nodename, const char *servname,
105  const struct addrinfo *hints, struct addrinfo **res)
106 {
107  /* fix [ruby-core:29427] */
108  const char *tmp_servname;
109  struct addrinfo tmp_hints;
110  int error;
111 
112  tmp_servname = servname;
113  MEMCPY(&tmp_hints, hints, struct addrinfo, 1);
114  if (nodename && servname) {
115  if (str_is_number(tmp_servname) && atoi(servname) == 0) {
116  tmp_servname = NULL;
117 #ifdef AI_NUMERICSERV
118  if (tmp_hints.ai_flags) tmp_hints.ai_flags &= ~AI_NUMERICSERV;
119 #endif
120  }
121  }
122 
123  error = getaddrinfo(nodename, tmp_servname, &tmp_hints, res);
124  if (error == 0) {
125  /* [ruby-dev:23164] */
126  struct addrinfo *r;
127  r = *res;
128  while (r) {
129  if (! r->ai_socktype) r->ai_socktype = hints->ai_socktype;
130  if (! r->ai_protocol) {
131  if (r->ai_socktype == SOCK_DGRAM) {
133  }
134  else if (r->ai_socktype == SOCK_STREAM) {
136  }
137  }
138  r = r->ai_next;
139  }
140  }
141 
142  return error;
143 }
144 #undef getaddrinfo
145 #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__darwin((node),(serv),(hints),(res))
146 #endif
147 
148 #ifndef GETADDRINFO_EMU
150 {
151  const char *node;
152  const char *service;
153  const struct addrinfo *hints;
154  struct addrinfo **res;
155 };
156 
157 static void *
159 {
160  struct getaddrinfo_arg *ptr = arg;
161  return (void *)(VALUE)getaddrinfo(ptr->node, ptr->service,
162  ptr->hints, ptr->res);
163 }
164 #endif
165 
166 int
167 rb_getaddrinfo(const char *node, const char *service,
168  const struct addrinfo *hints,
169  struct addrinfo **res)
170 {
171 #ifdef GETADDRINFO_EMU
172  return getaddrinfo(node, service, hints, res);
173 #else
174  struct getaddrinfo_arg arg;
175  int ret;
176  MEMZERO(&arg, sizeof arg, 1);
177  arg.node = node;
178  arg.service = service;
179  arg.hints = hints;
180  arg.res = res;
182  return ret;
183 #endif
184 }
185 
186 #ifndef GETADDRINFO_EMU
188 {
189  const struct sockaddr *sa;
190  socklen_t salen;
191  char *host;
192  size_t hostlen;
193  char *serv;
194  size_t servlen;
195  int flags;
196 };
197 
198 static void *
200 {
201  struct getnameinfo_arg *ptr = arg;
202  return (void *)(VALUE)getnameinfo(ptr->sa, ptr->salen,
203  ptr->host, (socklen_t)ptr->hostlen,
204  ptr->serv, (socklen_t)ptr->servlen,
205  ptr->flags);
206 }
207 #endif
208 
209 int
210 rb_getnameinfo(const struct sockaddr *sa, socklen_t salen,
211  char *host, size_t hostlen,
212  char *serv, size_t servlen, int flags)
213 {
214 #ifdef GETADDRINFO_EMU
215  return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
216 #else
217  struct getnameinfo_arg arg;
218  int ret;
219  arg.sa = sa;
220  arg.salen = salen;
221  arg.host = host;
222  arg.hostlen = hostlen;
223  arg.serv = serv;
224  arg.servlen = servlen;
225  arg.flags = flags;
227  return ret;
228 #endif
229 }
230 
231 static void
232 make_ipaddr0(struct sockaddr *addr, char *buf, size_t len)
233 {
234  int error;
235 
236  error = rb_getnameinfo(addr, SA_LEN(addr), buf, len, NULL, 0, NI_NUMERICHOST);
237  if (error) {
238  rsock_raise_socket_error("getnameinfo", error);
239  }
240 }
241 
242 VALUE
243 rsock_make_ipaddr(struct sockaddr *addr)
244 {
245  char hbuf[1024];
246 
247  make_ipaddr0(addr, hbuf, sizeof(hbuf));
248  return rb_str_new2(hbuf);
249 }
250 
251 static void
252 make_inetaddr(unsigned int host, char *buf, size_t len)
253 {
254  struct sockaddr_in sin;
255 
256  MEMZERO(&sin, struct sockaddr_in, 1);
257  sin.sin_family = AF_INET;
258  SET_SIN_LEN(&sin, sizeof(sin));
259  sin.sin_addr.s_addr = host;
260  make_ipaddr0((struct sockaddr*)&sin, buf, len);
261 }
262 
263 static int
264 str_is_number(const char *p)
265 {
266  char *ep;
267 
268  if (!p || *p == '\0')
269  return 0;
270  ep = NULL;
271  (void)STRTOUL(p, &ep, 10);
272  if (ep && *ep == '\0')
273  return 1;
274  else
275  return 0;
276 }
277 
278 static char*
279 host_str(VALUE host, char *hbuf, size_t len, int *flags_ptr)
280 {
281  if (NIL_P(host)) {
282  return NULL;
283  }
284  else if (rb_obj_is_kind_of(host, rb_cInteger)) {
285  unsigned int i = NUM2UINT(host);
286 
287  make_inetaddr(htonl(i), hbuf, len);
288  if (flags_ptr) *flags_ptr |= AI_NUMERICHOST;
289  return hbuf;
290  }
291  else {
292  char *name;
293 
294  SafeStringValue(host);
295  name = RSTRING_PTR(host);
296  if (!name || *name == 0 || (name[0] == '<' && strcmp(name, "<any>") == 0)) {
297  make_inetaddr(INADDR_ANY, hbuf, len);
298  if (flags_ptr) *flags_ptr |= AI_NUMERICHOST;
299  }
300  else if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
301  make_inetaddr(INADDR_BROADCAST, hbuf, len);
302  if (flags_ptr) *flags_ptr |= AI_NUMERICHOST;
303  }
304  else if (strlen(name) >= len) {
305  rb_raise(rb_eArgError, "hostname too long (%"PRIuSIZE")",
306  strlen(name));
307  }
308  else {
309  strcpy(hbuf, name);
310  }
311  return hbuf;
312  }
313 }
314 
315 static char*
316 port_str(VALUE port, char *pbuf, size_t len, int *flags_ptr)
317 {
318  if (NIL_P(port)) {
319  return 0;
320  }
321  else if (FIXNUM_P(port)) {
322  snprintf(pbuf, len, "%ld", FIX2LONG(port));
323 #ifdef AI_NUMERICSERV
324  if (flags_ptr) *flags_ptr |= AI_NUMERICSERV;
325 #endif
326  return pbuf;
327  }
328  else {
329  char *serv;
330 
331  SafeStringValue(port);
332  serv = RSTRING_PTR(port);
333  if (strlen(serv) >= len) {
334  rb_raise(rb_eArgError, "service name too long (%"PRIuSIZE")",
335  strlen(serv));
336  }
337  strcpy(pbuf, serv);
338  return pbuf;
339  }
340 }
341 
342 struct addrinfo*
343 rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack)
344 {
345  struct addrinfo* res = NULL;
346  char *hostp, *portp;
347  int error;
348  char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
349  int additional_flags = 0;
350 
351  hostp = host_str(host, hbuf, sizeof(hbuf), &additional_flags);
352  portp = port_str(port, pbuf, sizeof(pbuf), &additional_flags);
353 
354  if (socktype_hack && hints->ai_socktype == 0 && str_is_number(portp)) {
355  hints->ai_socktype = SOCK_DGRAM;
356  }
357  hints->ai_flags |= additional_flags;
358 
359  error = rb_getaddrinfo(hostp, portp, hints, &res);
360  if (error) {
361  if (hostp && hostp[strlen(hostp)-1] == '\n') {
362  rb_raise(rb_eSocket, "newline at the end of hostname");
363  }
364  rsock_raise_socket_error("getaddrinfo", error);
365  }
366 
367  return res;
368 }
369 
370 struct addrinfo*
371 rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags)
372 {
373  struct addrinfo hints;
374 
375  MEMZERO(&hints, struct addrinfo, 1);
376  hints.ai_family = AF_UNSPEC;
377  hints.ai_socktype = socktype;
378  hints.ai_flags = flags;
379  return rsock_getaddrinfo(host, port, &hints, 1);
380 }
381 
382 VALUE
383 rsock_ipaddr(struct sockaddr *sockaddr, int norevlookup)
384 {
385  VALUE family, port, addr1, addr2;
386  VALUE ary;
387  int error;
388  char hbuf[1024], pbuf[1024];
389  ID id;
390 
391  id = rsock_intern_family(sockaddr->sa_family);
392  if (id) {
393  family = rb_str_dup(rb_id2str(id));
394  }
395  else {
396  sprintf(pbuf, "unknown:%d", sockaddr->sa_family);
397  family = rb_str_new2(pbuf);
398  }
399 
400  addr1 = Qnil;
401  if (!norevlookup) {
402  error = rb_getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf),
403  NULL, 0, 0);
404  if (! error) {
405  addr1 = rb_str_new2(hbuf);
406  }
407  }
408  error = rb_getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf),
409  pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV);
410  if (error) {
411  rsock_raise_socket_error("getnameinfo", error);
412  }
413  addr2 = rb_str_new2(hbuf);
414  if (addr1 == Qnil) {
415  addr1 = addr2;
416  }
417  port = INT2FIX(atoi(pbuf));
418  ary = rb_ary_new3(4, family, port, addr1, addr2);
419 
420  return ary;
421 }
422 
423 #ifdef HAVE_SYS_UN_H
424 VALUE
425 rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len)
426 {
427  char *s, *e;
428  s = sockaddr->sun_path;
429  e = (char *)sockaddr + len;
430  while (s < e && *(e-1) == '\0')
431  e--;
432  if (s <= e)
433  return rb_str_new(s, e-s);
434  else
435  return rb_str_new2("");
436 }
437 
438 VALUE
439 rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len)
440 {
441  return rb_assoc_new(rb_str_new2("AF_UNIX"),
442  rsock_unixpath_str(sockaddr, len));
443 }
444 
445 socklen_t
446 rsock_unix_sockaddr_len(VALUE path)
447 {
448 #ifdef __linux__
449  if (RSTRING_LEN(path) == 0) {
450  /* autobind; see unix(7) for details. */
451  return (socklen_t) sizeof(sa_family_t);
452  }
453  else if (RSTRING_PTR(path)[0] == '\0') {
454  /* abstract namespace; see unix(7) for details. */
455  return (socklen_t) offsetof(struct sockaddr_un, sun_path) +
456  RSTRING_LEN(path);
457  }
458  else {
459 #endif
460  return (socklen_t) sizeof(struct sockaddr_un);
461 #ifdef __linux__
462  }
463 #endif
464 }
465 #endif
466 
467 struct hostent_arg {
469  struct addrinfo* addr;
470  VALUE (*ipaddr)(struct sockaddr*, size_t);
471 };
472 
473 static VALUE
475 {
476  VALUE host = arg->host;
477  struct addrinfo* addr = arg->addr;
478  VALUE (*ipaddr)(struct sockaddr*, size_t) = arg->ipaddr;
479 
480  struct addrinfo *ai;
481  struct hostent *h;
482  VALUE ary, names;
483  char **pch;
484  const char* hostp;
485  char hbuf[NI_MAXHOST];
486 
487  ary = rb_ary_new();
488  if (addr->ai_canonname) {
489  hostp = addr->ai_canonname;
490  }
491  else {
492  hostp = host_str(host, hbuf, sizeof(hbuf), NULL);
493  }
494  rb_ary_push(ary, rb_str_new2(hostp));
495 
496  if (addr->ai_canonname && (h = gethostbyname(addr->ai_canonname))) {
497  names = rb_ary_new();
498  if (h->h_aliases != NULL) {
499  for (pch = h->h_aliases; *pch; pch++) {
500  rb_ary_push(names, rb_str_new2(*pch));
501  }
502  }
503  }
504  else {
505  names = rb_ary_new2(0);
506  }
507  rb_ary_push(ary, names);
508  rb_ary_push(ary, INT2NUM(addr->ai_family));
509  for (ai = addr; ai; ai = ai->ai_next) {
510  rb_ary_push(ary, (*ipaddr)(ai->ai_addr, ai->ai_addrlen));
511  }
512 
513  return ary;
514 }
515 
516 VALUE
518 {
519  freeaddrinfo(addr);
520  return Qnil;
521 }
522 
523 VALUE
524 rsock_make_hostent(VALUE host, struct addrinfo *addr, VALUE (*ipaddr)(struct sockaddr *, size_t))
525 {
526  struct hostent_arg arg;
527 
528  arg.host = host;
529  arg.addr = addr;
530  arg.ipaddr = ipaddr;
531  return rb_ensure(make_hostent_internal, (VALUE)&arg,
532  rsock_freeaddrinfo, (VALUE)addr);
533 }
534 
535 typedef struct {
538  int pfamily;
539  int socktype;
540  int protocol;
541  socklen_t sockaddr_len;
542  struct sockaddr_storage addr;
543 } rb_addrinfo_t;
544 
545 static void
546 addrinfo_mark(void *ptr)
547 {
548  rb_addrinfo_t *rai = ptr;
549  if (rai) {
550  rb_gc_mark(rai->inspectname);
551  rb_gc_mark(rai->canonname);
552  }
553 }
554 
555 #define addrinfo_free RUBY_TYPED_DEFAULT_FREE
556 
557 static size_t
558 addrinfo_memsize(const void *ptr)
559 {
560  return ptr ? sizeof(rb_addrinfo_t) : 0;
561 }
562 
564  "socket/addrinfo",
566 };
567 
568 static VALUE
570 {
571  return TypedData_Wrap_Struct(klass, &addrinfo_type, 0);
572 }
573 
574 #define IS_ADDRINFO(obj) rb_typeddata_is_kind_of((obj), &addrinfo_type)
575 static inline rb_addrinfo_t *
577 {
578  return rb_check_typeddata(self, &addrinfo_type);
579 }
580 
581 static rb_addrinfo_t *
583 {
584  rb_addrinfo_t *rai = check_addrinfo(self);
585 
586  if (!rai) {
587  rb_raise(rb_eTypeError, "uninitialized socket address");
588  }
589  return rai;
590 }
591 
592 
593 static rb_addrinfo_t *
595 {
597  memset(rai, 0, sizeof(rb_addrinfo_t));
598  rai->inspectname = Qnil;
599  rai->canonname = Qnil;
600  return rai;
601 }
602 
603 static void
604 init_addrinfo(rb_addrinfo_t *rai, struct sockaddr *sa, socklen_t len,
605  int pfamily, int socktype, int protocol,
606  VALUE canonname, VALUE inspectname)
607 {
608  if ((socklen_t)sizeof(rai->addr) < len)
609  rb_raise(rb_eArgError, "sockaddr string too big");
610  memcpy((void *)&rai->addr, (void *)sa, len);
611  rai->sockaddr_len = len;
612 
613  rai->pfamily = pfamily;
614  rai->socktype = socktype;
615  rai->protocol = protocol;
616  rai->canonname = canonname;
617  rai->inspectname = inspectname;
618 }
619 
620 VALUE
621 rsock_addrinfo_new(struct sockaddr *addr, socklen_t len,
622  int family, int socktype, int protocol,
623  VALUE canonname, VALUE inspectname)
624 {
625  VALUE a;
626  rb_addrinfo_t *rai;
627 
629  DATA_PTR(a) = rai = alloc_addrinfo();
630  init_addrinfo(rai, addr, len, family, socktype, protocol, canonname, inspectname);
631  return a;
632 }
633 
634 static struct addrinfo *
636  VALUE family, VALUE socktype, VALUE protocol, VALUE flags,
637  int socktype_hack)
638 {
639  struct addrinfo hints, *res;
640 
641  MEMZERO(&hints, struct addrinfo, 1);
642  hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family);
643 
644  if (!NIL_P(socktype)) {
645  hints.ai_socktype = rsock_socktype_arg(socktype);
646  }
647  if (!NIL_P(protocol)) {
648  hints.ai_protocol = NUM2INT(protocol);
649  }
650  if (!NIL_P(flags)) {
651  hints.ai_flags = NUM2INT(flags);
652  }
653  res = rsock_getaddrinfo(node, service, &hints, socktype_hack);
654 
655  if (res == NULL)
656  rb_raise(rb_eSocket, "host not found");
657  return res;
658 }
659 
660 static VALUE make_inspectname(VALUE node, VALUE service, struct addrinfo *res);
661 
662 static void
664  VALUE family, VALUE socktype, VALUE protocol, VALUE flags,
665  VALUE inspectnode, VALUE inspectservice)
666 {
667  struct addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 1);
668  VALUE canonname;
669  VALUE inspectname = rb_str_equal(node, inspectnode) ? Qnil : make_inspectname(inspectnode, inspectservice, res);
670 
671  canonname = Qnil;
672  if (res->ai_canonname) {
673  canonname = rb_tainted_str_new_cstr(res->ai_canonname);
674  OBJ_FREEZE(canonname);
675  }
676 
677  init_addrinfo(rai, res->ai_addr, res->ai_addrlen,
678  NUM2INT(family), NUM2INT(socktype), NUM2INT(protocol),
679  canonname, inspectname);
680 
681  freeaddrinfo(res);
682 }
683 
684 static VALUE
685 make_inspectname(VALUE node, VALUE service, struct addrinfo *res)
686 {
687  VALUE inspectname = Qnil;
688 
689  if (res) {
690  /* drop redundant information which also shown in address:port part. */
691  char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
692  int ret;
693  ret = rb_getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
694  sizeof(hbuf), pbuf, sizeof(pbuf),
696  if (ret == 0) {
697  if (RB_TYPE_P(node, T_STRING) && strcmp(hbuf, RSTRING_PTR(node)) == 0)
698  node = Qnil;
699  if (RB_TYPE_P(service, T_STRING) && strcmp(pbuf, RSTRING_PTR(service)) == 0)
700  service = Qnil;
701  else if (RB_TYPE_P(service, T_FIXNUM) && atoi(pbuf) == FIX2INT(service))
702  service = Qnil;
703  }
704  }
705 
706  if (RB_TYPE_P(node, T_STRING)) {
707  inspectname = rb_str_dup(node);
708  }
709  if (RB_TYPE_P(service, T_STRING)) {
710  if (NIL_P(inspectname))
711  inspectname = rb_sprintf(":%s", StringValueCStr(service));
712  else
713  rb_str_catf(inspectname, ":%s", StringValueCStr(service));
714  }
715  else if (RB_TYPE_P(service, T_FIXNUM) && FIX2INT(service) != 0)
716  {
717  if (NIL_P(inspectname))
718  inspectname = rb_sprintf(":%d", FIX2INT(service));
719  else
720  rb_str_catf(inspectname, ":%d", FIX2INT(service));
721  }
722  if (!NIL_P(inspectname)) {
723  OBJ_INFECT(inspectname, node);
724  OBJ_INFECT(inspectname, service);
725  OBJ_FREEZE(inspectname);
726  }
727  return inspectname;
728 }
729 
730 static VALUE
731 addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags)
732 {
733  VALUE ret;
734  VALUE canonname;
735  VALUE inspectname;
736 
737  struct addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0);
738 
739  inspectname = make_inspectname(node, service, res);
740 
741  canonname = Qnil;
742  if (res->ai_canonname) {
743  canonname = rb_tainted_str_new_cstr(res->ai_canonname);
744  OBJ_FREEZE(canonname);
745  }
746 
747  ret = rsock_addrinfo_new(res->ai_addr, res->ai_addrlen,
748  res->ai_family, res->ai_socktype, res->ai_protocol,
749  canonname, inspectname);
750 
751  freeaddrinfo(res);
752  return ret;
753 }
754 
755 static VALUE
756 addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags)
757 {
758  VALUE ret;
759  struct addrinfo *r;
760  VALUE inspectname;
761 
762  struct addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0);
763 
764  inspectname = make_inspectname(node, service, res);
765 
766  ret = rb_ary_new();
767  for (r = res; r; r = r->ai_next) {
768  VALUE addr;
769  VALUE canonname = Qnil;
770 
771  if (r->ai_canonname) {
772  canonname = rb_tainted_str_new_cstr(r->ai_canonname);
773  OBJ_FREEZE(canonname);
774  }
775 
776  addr = rsock_addrinfo_new(r->ai_addr, r->ai_addrlen,
777  r->ai_family, r->ai_socktype, r->ai_protocol,
778  canonname, inspectname);
779 
780  rb_ary_push(ret, addr);
781  }
782 
783  freeaddrinfo(res);
784  return ret;
785 }
786 
787 
788 #ifdef HAVE_SYS_UN_H
789 static void
790 init_unix_addrinfo(rb_addrinfo_t *rai, VALUE path, int socktype)
791 {
792  struct sockaddr_un un;
793  socklen_t len;
794 
795  StringValue(path);
796 
797  if (sizeof(un.sun_path) < (size_t)RSTRING_LEN(path))
799  "too long unix socket path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
800  (size_t)RSTRING_LEN(path), sizeof(un.sun_path));
801 
802  MEMZERO(&un, struct sockaddr_un, 1);
803 
804  un.sun_family = AF_UNIX;
805  memcpy((void*)&un.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
806 
807  len = rsock_unix_sockaddr_len(path);
808  init_addrinfo(rai, (struct sockaddr *)&un, len,
809  PF_UNIX, socktype, 0, Qnil, Qnil);
810 }
811 #endif
812 
813 /*
814  * call-seq:
815  * Addrinfo.new(sockaddr) => addrinfo
816  * Addrinfo.new(sockaddr, family) => addrinfo
817  * Addrinfo.new(sockaddr, family, socktype) => addrinfo
818  * Addrinfo.new(sockaddr, family, socktype, protocol) => addrinfo
819  *
820  * returns a new instance of Addrinfo.
821  * The instance contains sockaddr, family, socktype, protocol.
822  * sockaddr means struct sockaddr which can be used for connect(2), etc.
823  * family, socktype and protocol are integers which is used for arguments of socket(2).
824  *
825  * sockaddr is specified as an array or a string.
826  * The array should be compatible to the value of IPSocket#addr or UNIXSocket#addr.
827  * The string should be struct sockaddr as generated by
828  * Socket.sockaddr_in or Socket.unpack_sockaddr_un.
829  *
830  * sockaddr examples:
831  * - ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"]
832  * - ["AF_INET6", 42304, "ip6-localhost", "::1"]
833  * - ["AF_UNIX", "/tmp/sock"]
834  * - Socket.sockaddr_in("smtp", "2001:DB8::1")
835  * - Socket.sockaddr_in(80, "172.18.22.42")
836  * - Socket.sockaddr_in(80, "www.ruby-lang.org")
837  * - Socket.sockaddr_un("/tmp/sock")
838  *
839  * In an AF_INET/AF_INET6 sockaddr array, the 4th element,
840  * numeric IP address, is used to construct socket address in the Addrinfo instance.
841  * If the 3rd element, textual host name, is non-nil, it is also recorded but used only for Addrinfo#inspect.
842  *
843  * family is specified as an integer to specify the protocol family such as Socket::PF_INET.
844  * It can be a symbol or a string which is the constant name
845  * with or without PF_ prefix such as :INET, :INET6, :UNIX, "PF_INET", etc.
846  * If omitted, PF_UNSPEC is assumed.
847  *
848  * socktype is specified as an integer to specify the socket type such as Socket::SOCK_STREAM.
849  * It can be a symbol or a string which is the constant name
850  * with or without SOCK_ prefix such as :STREAM, :DGRAM, :RAW, "SOCK_STREAM", etc.
851  * If omitted, 0 is assumed.
852  *
853  * protocol is specified as an integer to specify the protocol such as Socket::IPPROTO_TCP.
854  * It must be an integer, unlike family and socktype.
855  * If omitted, 0 is assumed.
856  * Note that 0 is reasonable value for most protocols, except raw socket.
857  *
858  */
859 static VALUE
861 {
862  rb_addrinfo_t *rai;
863  VALUE sockaddr_arg, sockaddr_ary, pfamily, socktype, protocol;
864  int i_pfamily, i_socktype, i_protocol;
865  struct sockaddr *sockaddr_ptr;
866  socklen_t sockaddr_len;
867  VALUE canonname = Qnil, inspectname = Qnil;
868 
869  if (check_addrinfo(self))
870  rb_raise(rb_eTypeError, "already initialized socket address");
871  DATA_PTR(self) = rai = alloc_addrinfo();
872 
873  rb_scan_args(argc, argv, "13", &sockaddr_arg, &pfamily, &socktype, &protocol);
874 
875  i_pfamily = NIL_P(pfamily) ? PF_UNSPEC : rsock_family_arg(pfamily);
876  i_socktype = NIL_P(socktype) ? 0 : rsock_socktype_arg(socktype);
877  i_protocol = NIL_P(protocol) ? 0 : NUM2INT(protocol);
878 
879  sockaddr_ary = rb_check_array_type(sockaddr_arg);
880  if (!NIL_P(sockaddr_ary)) {
881  VALUE afamily = rb_ary_entry(sockaddr_ary, 0);
882  int af;
883  StringValue(afamily);
884  if (rsock_family_to_int(RSTRING_PTR(afamily), RSTRING_LEN(afamily), &af) == -1)
885  rb_raise(rb_eSocket, "unknown address family: %s", StringValueCStr(afamily));
886  switch (af) {
887  case AF_INET: /* ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] */
888 #ifdef INET6
889  case AF_INET6: /* ["AF_INET6", 42304, "ip6-localhost", "::1"] */
890 #endif
891  {
892  VALUE service = rb_ary_entry(sockaddr_ary, 1);
893  VALUE nodename = rb_ary_entry(sockaddr_ary, 2);
894  VALUE numericnode = rb_ary_entry(sockaddr_ary, 3);
895  int flags;
896 
897  service = INT2NUM(NUM2INT(service));
898  if (!NIL_P(nodename))
899  StringValue(nodename);
900  StringValue(numericnode);
901  flags = AI_NUMERICHOST;
902 #ifdef AI_NUMERICSERV
903  flags |= AI_NUMERICSERV;
904 #endif
905 
906  init_addrinfo_getaddrinfo(rai, numericnode, service,
907  INT2NUM(i_pfamily ? i_pfamily : af), INT2NUM(i_socktype), INT2NUM(i_protocol),
908  INT2NUM(flags),
909  nodename, service);
910  break;
911  }
912 
913 #ifdef HAVE_SYS_UN_H
914  case AF_UNIX: /* ["AF_UNIX", "/tmp/sock"] */
915  {
916  VALUE path = rb_ary_entry(sockaddr_ary, 1);
917  StringValue(path);
918  init_unix_addrinfo(rai, path, SOCK_STREAM);
919  break;
920  }
921 #endif
922 
923  default:
924  rb_raise(rb_eSocket, "unexpected address family");
925  }
926  }
927  else {
928  StringValue(sockaddr_arg);
929  sockaddr_ptr = (struct sockaddr *)RSTRING_PTR(sockaddr_arg);
930  sockaddr_len = RSTRING_LENINT(sockaddr_arg);
931  init_addrinfo(rai, sockaddr_ptr, sockaddr_len,
932  i_pfamily, i_socktype, i_protocol,
933  canonname, inspectname);
934  }
935 
936  return self;
937 }
938 
939 static int
940 get_afamily(struct sockaddr *addr, socklen_t len)
941 {
942  if ((socklen_t)((char*)&addr->sa_family + sizeof(addr->sa_family) - (char*)addr) <= len)
943  return addr->sa_family;
944  else
945  return AF_UNSPEC;
946 }
947 
948 static int
950 {
951  return get_afamily((struct sockaddr *)&rai->addr, rai->sockaddr_len);
952 }
953 
954 static VALUE
956 {
957  rb_addrinfo_t *rai = get_addrinfo(addrinfo);
958 
959  if (rai->sockaddr_len == 0) {
960  rb_str_cat2(ret, "empty-sockaddr");
961  }
962  else if ((long)rai->sockaddr_len < ((char*)&rai->addr.ss_family + sizeof(rai->addr.ss_family)) - (char*)&rai->addr)
963  rb_str_cat2(ret, "too-short-sockaddr");
964  else {
965  switch (rai->addr.ss_family) {
966  case AF_INET:
967  {
968  struct sockaddr_in *addr;
969  int port;
970  if (rai->sockaddr_len < (socklen_t)sizeof(struct sockaddr_in)) {
971  rb_str_cat2(ret, "too-short-AF_INET-sockaddr");
972  }
973  else {
974  addr = (struct sockaddr_in *)&rai->addr;
975  rb_str_catf(ret, "%d.%d.%d.%d",
976  ((unsigned char*)&addr->sin_addr)[0],
977  ((unsigned char*)&addr->sin_addr)[1],
978  ((unsigned char*)&addr->sin_addr)[2],
979  ((unsigned char*)&addr->sin_addr)[3]);
980  port = ntohs(addr->sin_port);
981  if (port)
982  rb_str_catf(ret, ":%d", port);
983  if ((socklen_t)sizeof(struct sockaddr_in) < rai->sockaddr_len)
984  rb_str_catf(ret, "(sockaddr %d bytes too long)", (int)(rai->sockaddr_len - sizeof(struct sockaddr_in)));
985  }
986  break;
987  }
988 
989 #ifdef AF_INET6
990  case AF_INET6:
991  {
992  struct sockaddr_in6 *addr;
993  char hbuf[1024];
994  int port;
995  int error;
996  if (rai->sockaddr_len < (socklen_t)sizeof(struct sockaddr_in6)) {
997  rb_str_cat2(ret, "too-short-AF_INET6-sockaddr");
998  }
999  else {
1000  addr = (struct sockaddr_in6 *)&rai->addr;
1001  /* use getnameinfo for scope_id.
1002  * RFC 4007: IPv6 Scoped Address Architecture
1003  * draft-ietf-ipv6-scope-api-00.txt: Scoped Address Extensions to the IPv6 Basic Socket API
1004  */
1005  error = getnameinfo((struct sockaddr *)&rai->addr, rai->sockaddr_len,
1006  hbuf, (socklen_t)sizeof(hbuf), NULL, 0,
1008  if (error) {
1009  rsock_raise_socket_error("getnameinfo", error);
1010  }
1011  if (addr->sin6_port == 0) {
1012  rb_str_cat2(ret, hbuf);
1013  }
1014  else {
1015  port = ntohs(addr->sin6_port);
1016  rb_str_catf(ret, "[%s]:%d", hbuf, port);
1017  }
1018  if ((socklen_t)sizeof(struct sockaddr_in6) < rai->sockaddr_len)
1019  rb_str_catf(ret, "(sockaddr %d bytes too long)", (int)(rai->sockaddr_len - sizeof(struct sockaddr_in6)));
1020  }
1021  break;
1022  }
1023 #endif
1024 
1025 #ifdef HAVE_SYS_UN_H
1026  case AF_UNIX:
1027  {
1028  struct sockaddr_un *addr = (struct sockaddr_un *)&rai->addr;
1029  char *p, *s, *e;
1030  s = addr->sun_path;
1031  e = (char*)addr + rai->sockaddr_len;
1032  while (s < e && *(e-1) == '\0')
1033  e--;
1034  if (e < s)
1035  rb_str_cat2(ret, "too-short-AF_UNIX-sockaddr");
1036  else if (s == e)
1037  rb_str_cat2(ret, "empty-path-AF_UNIX-sockaddr");
1038  else {
1039  int printable_only = 1;
1040  p = s;
1041  while (p < e) {
1042  printable_only = printable_only && ISPRINT(*p) && !ISSPACE(*p);
1043  p++;
1044  }
1045  if (printable_only) { /* only printable, no space */
1046  if (s[0] != '/') /* relative path */
1047  rb_str_cat2(ret, "AF_UNIX ");
1048  rb_str_cat(ret, s, p - s);
1049  }
1050  else {
1051  rb_str_cat2(ret, "AF_UNIX");
1052  while (s < e)
1053  rb_str_catf(ret, ":%02x", (unsigned char)*s++);
1054  }
1055  if (addr->sun_path + sizeof(addr->sun_path) < (char*)&rai->addr + rai->sockaddr_len)
1056  rb_str_catf(ret, "(sockaddr %d bytes too long)",
1057  (int)(rai->sockaddr_len - (addr->sun_path + sizeof(addr->sun_path) - (char*)&rai->addr)));
1058  }
1059  break;
1060  }
1061 #endif
1062 
1063  default:
1064  {
1065  ID id = rsock_intern_family(rai->addr.ss_family);
1066  if (id == 0)
1067  rb_str_catf(ret, "unknown address family %d", rai->addr.ss_family);
1068  else
1069  rb_str_catf(ret, "%s address format unknown", rb_id2name(id));
1070  break;
1071  }
1072  }
1073  }
1074 
1075  return ret;
1076 }
1077 
1078 /*
1079  * call-seq:
1080  * addrinfo.inspect => string
1081  *
1082  * returns a string which shows addrinfo in human-readable form.
1083  *
1084  * Addrinfo.tcp("localhost", 80).inspect #=> "#<Addrinfo: 127.0.0.1:80 TCP (localhost)>"
1085  * Addrinfo.unix("/tmp/sock").inspect #=> "#<Addrinfo: /tmp/sock SOCK_STREAM>"
1086  *
1087  */
1088 static VALUE
1090 {
1091  rb_addrinfo_t *rai = get_addrinfo(self);
1092  int internet_p;
1093  VALUE ret;
1094 
1095  ret = rb_sprintf("#<%s: ", rb_obj_classname(self));
1096 
1097  inspect_sockaddr(self, ret);
1098 
1099  if (rai->pfamily && ai_get_afamily(rai) != rai->pfamily) {
1101  if (id)
1102  rb_str_catf(ret, " %s", rb_id2name(id));
1103  else
1104  rb_str_catf(ret, " PF_\?\?\?(%d)", rai->pfamily);
1105  }
1106 
1107  internet_p = rai->pfamily == PF_INET;
1108 #ifdef INET6
1109  internet_p = internet_p || rai->pfamily == PF_INET6;
1110 #endif
1111  if (internet_p && rai->socktype == SOCK_STREAM &&
1112  (rai->protocol == 0 || rai->protocol == IPPROTO_TCP)) {
1113  rb_str_cat2(ret, " TCP");
1114  }
1115  else if (internet_p && rai->socktype == SOCK_DGRAM &&
1116  (rai->protocol == 0 || rai->protocol == IPPROTO_UDP)) {
1117  rb_str_cat2(ret, " UDP");
1118  }
1119  else {
1120  if (rai->socktype) {
1121  ID id = rsock_intern_socktype(rai->socktype);
1122  if (id)
1123  rb_str_catf(ret, " %s", rb_id2name(id));
1124  else
1125  rb_str_catf(ret, " SOCK_\?\?\?(%d)", rai->socktype);
1126  }
1127 
1128  if (rai->protocol) {
1129  if (internet_p) {
1130  ID id = rsock_intern_ipproto(rai->protocol);
1131  if (id)
1132  rb_str_catf(ret, " %s", rb_id2name(id));
1133  else
1134  goto unknown_protocol;
1135  }
1136  else {
1137  unknown_protocol:
1138  rb_str_catf(ret, " UNKNOWN_PROTOCOL(%d)", rai->protocol);
1139  }
1140  }
1141  }
1142 
1143  if (!NIL_P(rai->canonname)) {
1144  VALUE name = rai->canonname;
1145  rb_str_catf(ret, " %s", StringValueCStr(name));
1146  }
1147 
1148  if (!NIL_P(rai->inspectname)) {
1149  VALUE name = rai->inspectname;
1150  rb_str_catf(ret, " (%s)", StringValueCStr(name));
1151  }
1152 
1153  rb_str_buf_cat2(ret, ">");
1154  return ret;
1155 }
1156 
1157 /*
1158  * call-seq:
1159  * addrinfo.inspect_sockaddr => string
1160  *
1161  * returns a string which shows the sockaddr in _addrinfo_ with human-readable form.
1162  *
1163  * Addrinfo.tcp("localhost", 80).inspect_sockaddr #=> "127.0.0.1:80"
1164  * Addrinfo.tcp("ip6-localhost", 80).inspect_sockaddr #=> "[::1]:80"
1165  * Addrinfo.unix("/tmp/sock").inspect_sockaddr #=> "/tmp/sock"
1166  *
1167  */
1168 static VALUE
1170 {
1171  return inspect_sockaddr(self, rb_str_new("", 0));
1172 }
1173 
1174 /* :nodoc: */
1175 static VALUE
1177 {
1178  rb_addrinfo_t *rai = get_addrinfo(self);
1179  VALUE sockaddr, afamily, pfamily, socktype, protocol, canonname, inspectname;
1180  int afamily_int = ai_get_afamily(rai);
1181  ID id;
1182 
1184  if (id == 0)
1185  rb_raise(rb_eSocket, "unknown protocol family: %d", rai->pfamily);
1186  pfamily = rb_id2str(id);
1187 
1188  if (rai->socktype == 0)
1189  socktype = INT2FIX(0);
1190  else {
1191  id = rsock_intern_socktype(rai->socktype);
1192  if (id == 0)
1193  rb_raise(rb_eSocket, "unknown socktype: %d", rai->socktype);
1194  socktype = rb_id2str(id);
1195  }
1196 
1197  if (rai->protocol == 0)
1198  protocol = INT2FIX(0);
1199  else if (IS_IP_FAMILY(afamily_int)) {
1200  id = rsock_intern_ipproto(rai->protocol);
1201  if (id == 0)
1202  rb_raise(rb_eSocket, "unknown IP protocol: %d", rai->protocol);
1203  protocol = rb_id2str(id);
1204  }
1205  else {
1206  rb_raise(rb_eSocket, "unknown protocol: %d", rai->protocol);
1207  }
1208 
1209  canonname = rai->canonname;
1210 
1211  inspectname = rai->inspectname;
1212 
1213  id = rsock_intern_family(afamily_int);
1214  if (id == 0)
1215  rb_raise(rb_eSocket, "unknown address family: %d", afamily_int);
1216  afamily = rb_id2str(id);
1217 
1218  switch(afamily_int) {
1219 #ifdef HAVE_SYS_UN_H
1220  case AF_UNIX:
1221  {
1222  struct sockaddr_un *su = (struct sockaddr_un *)&rai->addr;
1223  char *s, *e;
1224  s = su->sun_path;
1225  e = (char*)su + rai->sockaddr_len;
1226  while (s < e && *(e-1) == '\0')
1227  e--;
1228  sockaddr = rb_str_new(s, e-s);
1229  break;
1230  }
1231 #endif
1232 
1233  default:
1234  {
1235  char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
1236  int error;
1237  error = getnameinfo((struct sockaddr *)&rai->addr, rai->sockaddr_len,
1238  hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf),
1240  if (error) {
1241  rsock_raise_socket_error("getnameinfo", error);
1242  }
1243  sockaddr = rb_assoc_new(rb_str_new_cstr(hbuf), rb_str_new_cstr(pbuf));
1244  break;
1245  }
1246  }
1247 
1248  return rb_ary_new3(7, afamily, sockaddr, pfamily, socktype, protocol, canonname, inspectname);
1249 }
1250 
1251 /* :nodoc: */
1252 static VALUE
1254 {
1255  VALUE v;
1256  VALUE canonname, inspectname;
1257  int afamily, pfamily, socktype, protocol;
1258  struct sockaddr_storage ss;
1259  socklen_t len;
1260  rb_addrinfo_t *rai;
1261 
1262  if (check_addrinfo(self))
1263  rb_raise(rb_eTypeError, "already initialized socket address");
1264 
1265  ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
1266 
1267  v = rb_ary_entry(ary, 0);
1268  StringValue(v);
1269  if (rsock_family_to_int(RSTRING_PTR(v), RSTRING_LEN(v), &afamily) == -1)
1270  rb_raise(rb_eTypeError, "unexpected address family");
1271 
1272  v = rb_ary_entry(ary, 2);
1273  StringValue(v);
1274  if (rsock_family_to_int(RSTRING_PTR(v), RSTRING_LEN(v), &pfamily) == -1)
1275  rb_raise(rb_eTypeError, "unexpected protocol family");
1276 
1277  v = rb_ary_entry(ary, 3);
1278  if (v == INT2FIX(0))
1279  socktype = 0;
1280  else {
1281  StringValue(v);
1282  if (rsock_socktype_to_int(RSTRING_PTR(v), RSTRING_LEN(v), &socktype) == -1)
1283  rb_raise(rb_eTypeError, "unexpected socktype");
1284  }
1285 
1286  v = rb_ary_entry(ary, 4);
1287  if (v == INT2FIX(0))
1288  protocol = 0;
1289  else {
1290  StringValue(v);
1291  if (IS_IP_FAMILY(afamily)) {
1292  if (rsock_ipproto_to_int(RSTRING_PTR(v), RSTRING_LEN(v), &protocol) == -1)
1293  rb_raise(rb_eTypeError, "unexpected protocol");
1294  }
1295  else {
1296  rb_raise(rb_eTypeError, "unexpected protocol");
1297  }
1298  }
1299 
1300  v = rb_ary_entry(ary, 5);
1301  if (NIL_P(v))
1302  canonname = Qnil;
1303  else {
1304  StringValue(v);
1305  canonname = v;
1306  }
1307 
1308  v = rb_ary_entry(ary, 6);
1309  if (NIL_P(v))
1310  inspectname = Qnil;
1311  else {
1312  StringValue(v);
1313  inspectname = v;
1314  }
1315 
1316  v = rb_ary_entry(ary, 1);
1317  switch(afamily) {
1318 #ifdef HAVE_SYS_UN_H
1319  case AF_UNIX:
1320  {
1321  struct sockaddr_un uaddr;
1322  MEMZERO(&uaddr, struct sockaddr_un, 1);
1323  uaddr.sun_family = AF_UNIX;
1324 
1325  StringValue(v);
1326  if (sizeof(uaddr.sun_path) < (size_t)RSTRING_LEN(v))
1328  "too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
1329  (size_t)RSTRING_LEN(v), sizeof(uaddr.sun_path));
1330  memcpy(uaddr.sun_path, RSTRING_PTR(v), RSTRING_LEN(v));
1331  len = (socklen_t)sizeof(uaddr);
1332  memcpy(&ss, &uaddr, len);
1333  break;
1334  }
1335 #endif
1336 
1337  default:
1338  {
1339  VALUE pair = rb_convert_type(v, T_ARRAY, "Array", "to_ary");
1340  struct addrinfo *res;
1341  int flags = AI_NUMERICHOST;
1342 #ifdef AI_NUMERICSERV
1343  flags |= AI_NUMERICSERV;
1344 #endif
1345  res = call_getaddrinfo(rb_ary_entry(pair, 0), rb_ary_entry(pair, 1),
1346  INT2NUM(pfamily), INT2NUM(socktype), INT2NUM(protocol),
1347  INT2NUM(flags), 1);
1348 
1349  len = res->ai_addrlen;
1350  memcpy(&ss, res->ai_addr, res->ai_addrlen);
1351  break;
1352  }
1353  }
1354 
1355  DATA_PTR(self) = rai = alloc_addrinfo();
1356  init_addrinfo(rai, (struct sockaddr *)&ss, len,
1357  pfamily, socktype, protocol,
1358  canonname, inspectname);
1359  return self;
1360 }
1361 
1362 /*
1363  * call-seq:
1364  * addrinfo.afamily => integer
1365  *
1366  * returns the address family as an integer.
1367  *
1368  * Addrinfo.tcp("localhost", 80).afamily == Socket::AF_INET #=> true
1369  *
1370  */
1371 static VALUE
1373 {
1374  rb_addrinfo_t *rai = get_addrinfo(self);
1375  return INT2NUM(ai_get_afamily(rai));
1376 }
1377 
1378 /*
1379  * call-seq:
1380  * addrinfo.pfamily => integer
1381  *
1382  * returns the protocol family as an integer.
1383  *
1384  * Addrinfo.tcp("localhost", 80).pfamily == Socket::PF_INET #=> true
1385  *
1386  */
1387 static VALUE
1389 {
1390  rb_addrinfo_t *rai = get_addrinfo(self);
1391  return INT2NUM(rai->pfamily);
1392 }
1393 
1394 /*
1395  * call-seq:
1396  * addrinfo.socktype => integer
1397  *
1398  * returns the socket type as an integer.
1399  *
1400  * Addrinfo.tcp("localhost", 80).socktype == Socket::SOCK_STREAM #=> true
1401  *
1402  */
1403 static VALUE
1405 {
1406  rb_addrinfo_t *rai = get_addrinfo(self);
1407  return INT2NUM(rai->socktype);
1408 }
1409 
1410 /*
1411  * call-seq:
1412  * addrinfo.protocol => integer
1413  *
1414  * returns the socket type as an integer.
1415  *
1416  * Addrinfo.tcp("localhost", 80).protocol == Socket::IPPROTO_TCP #=> true
1417  *
1418  */
1419 static VALUE
1421 {
1422  rb_addrinfo_t *rai = get_addrinfo(self);
1423  return INT2NUM(rai->protocol);
1424 }
1425 
1426 /*
1427  * call-seq:
1428  * addrinfo.to_sockaddr => string
1429  * addrinfo.to_s => string
1430  *
1431  * returns the socket address as packed struct sockaddr string.
1432  *
1433  * Addrinfo.tcp("localhost", 80).to_sockaddr
1434  * #=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
1435  *
1436  */
1437 static VALUE
1439 {
1440  rb_addrinfo_t *rai = get_addrinfo(self);
1441  VALUE ret;
1442  ret = rb_str_new((char*)&rai->addr, rai->sockaddr_len);
1443  OBJ_INFECT(ret, self);
1444  return ret;
1445 }
1446 
1447 /*
1448  * call-seq:
1449  * addrinfo.canonname => string or nil
1450  *
1451  * returns the canonical name as an string.
1452  *
1453  * nil is returned if no canonical name.
1454  *
1455  * The canonical name is set by Addrinfo.getaddrinfo when AI_CANONNAME is specified.
1456  *
1457  * list = Addrinfo.getaddrinfo("www.ruby-lang.org", 80, :INET, :STREAM, nil, Socket::AI_CANONNAME)
1458  * p list[0] #=> #<Addrinfo: 221.186.184.68:80 TCP carbon.ruby-lang.org (www.ruby-lang.org)>
1459  * p list[0].canonname #=> "carbon.ruby-lang.org"
1460  *
1461  */
1462 static VALUE
1464 {
1465  rb_addrinfo_t *rai = get_addrinfo(self);
1466  return rai->canonname;
1467 }
1468 
1469 /*
1470  * call-seq:
1471  * addrinfo.ip? => true or false
1472  *
1473  * returns true if addrinfo is internet (IPv4/IPv6) address.
1474  * returns false otherwise.
1475  *
1476  * Addrinfo.tcp("127.0.0.1", 80).ip? #=> true
1477  * Addrinfo.tcp("::1", 80).ip? #=> true
1478  * Addrinfo.unix("/tmp/sock").ip? #=> false
1479  *
1480  */
1481 static VALUE
1483 {
1484  rb_addrinfo_t *rai = get_addrinfo(self);
1485  int family = ai_get_afamily(rai);
1486  return IS_IP_FAMILY(family) ? Qtrue : Qfalse;
1487 }
1488 
1489 /*
1490  * call-seq:
1491  * addrinfo.ipv4? => true or false
1492  *
1493  * returns true if addrinfo is IPv4 address.
1494  * returns false otherwise.
1495  *
1496  * Addrinfo.tcp("127.0.0.1", 80).ipv4? #=> true
1497  * Addrinfo.tcp("::1", 80).ipv4? #=> false
1498  * Addrinfo.unix("/tmp/sock").ipv4? #=> false
1499  *
1500  */
1501 static VALUE
1503 {
1504  rb_addrinfo_t *rai = get_addrinfo(self);
1505  return ai_get_afamily(rai) == AF_INET ? Qtrue : Qfalse;
1506 }
1507 
1508 /*
1509  * call-seq:
1510  * addrinfo.ipv6? => true or false
1511  *
1512  * returns true if addrinfo is IPv6 address.
1513  * returns false otherwise.
1514  *
1515  * Addrinfo.tcp("127.0.0.1", 80).ipv6? #=> false
1516  * Addrinfo.tcp("::1", 80).ipv6? #=> true
1517  * Addrinfo.unix("/tmp/sock").ipv6? #=> false
1518  *
1519  */
1520 static VALUE
1522 {
1523 #ifdef AF_INET6
1524  rb_addrinfo_t *rai = get_addrinfo(self);
1525  return ai_get_afamily(rai) == AF_INET6 ? Qtrue : Qfalse;
1526 #else
1527  return Qfalse;
1528 #endif
1529 }
1530 
1531 /*
1532  * call-seq:
1533  * addrinfo.unix? => true or false
1534  *
1535  * returns true if addrinfo is UNIX address.
1536  * returns false otherwise.
1537  *
1538  * Addrinfo.tcp("127.0.0.1", 80).unix? #=> false
1539  * Addrinfo.tcp("::1", 80).unix? #=> false
1540  * Addrinfo.unix("/tmp/sock").unix? #=> true
1541  *
1542  */
1543 static VALUE
1545 {
1546  rb_addrinfo_t *rai = get_addrinfo(self);
1547 #ifdef AF_UNIX
1548  return ai_get_afamily(rai) == AF_UNIX ? Qtrue : Qfalse;
1549 #else
1550  return Qfalse;
1551 #endif
1552 }
1553 
1554 /*
1555  * call-seq:
1556  * addrinfo.getnameinfo => [nodename, service]
1557  * addrinfo.getnameinfo(flags) => [nodename, service]
1558  *
1559  * returns nodename and service as a pair of strings.
1560  * This converts struct sockaddr in addrinfo to textual representation.
1561  *
1562  * flags should be bitwise OR of Socket::NI_??? constants.
1563  *
1564  * Addrinfo.tcp("127.0.0.1", 80).getnameinfo #=> ["localhost", "www"]
1565  *
1566  * Addrinfo.tcp("127.0.0.1", 80).getnameinfo(Socket::NI_NUMERICSERV)
1567  * #=> ["localhost", "80"]
1568  */
1569 static VALUE
1571 {
1572  rb_addrinfo_t *rai = get_addrinfo(self);
1573  VALUE vflags;
1574  char hbuf[1024], pbuf[1024];
1575  int flags, error;
1576 
1577  rb_scan_args(argc, argv, "01", &vflags);
1578 
1579  flags = NIL_P(vflags) ? 0 : NUM2INT(vflags);
1580 
1581  if (rai->socktype == SOCK_DGRAM)
1582  flags |= NI_DGRAM;
1583 
1584  error = getnameinfo((struct sockaddr *)&rai->addr, rai->sockaddr_len,
1585  hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf),
1586  flags);
1587  if (error) {
1588  rsock_raise_socket_error("getnameinfo", error);
1589  }
1590 
1591  return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf));
1592 }
1593 
1594 /*
1595  * call-seq:
1596  * addrinfo.ip_unpack => [addr, port]
1597  *
1598  * Returns the IP address and port number as 2-element array.
1599  *
1600  * Addrinfo.tcp("127.0.0.1", 80).ip_unpack #=> ["127.0.0.1", 80]
1601  * Addrinfo.tcp("::1", 80).ip_unpack #=> ["::1", 80]
1602  */
1603 static VALUE
1605 {
1606  rb_addrinfo_t *rai = get_addrinfo(self);
1607  int family = ai_get_afamily(rai);
1608  VALUE vflags;
1609  VALUE ret, portstr;
1610 
1611  if (!IS_IP_FAMILY(family))
1612  rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
1613 
1615  ret = addrinfo_getnameinfo(1, &vflags, self);
1616  portstr = rb_ary_entry(ret, 1);
1617  rb_ary_store(ret, 1, INT2NUM(atoi(StringValueCStr(portstr))));
1618  return ret;
1619 }
1620 
1621 /*
1622  * call-seq:
1623  * addrinfo.ip_address => string
1624  *
1625  * Returns the IP address as a string.
1626  *
1627  * Addrinfo.tcp("127.0.0.1", 80).ip_address #=> "127.0.0.1"
1628  * Addrinfo.tcp("::1", 80).ip_address #=> "::1"
1629  */
1630 static VALUE
1632 {
1633  rb_addrinfo_t *rai = get_addrinfo(self);
1634  int family = ai_get_afamily(rai);
1635  VALUE vflags;
1636  VALUE ret;
1637 
1638  if (!IS_IP_FAMILY(family))
1639  rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
1640 
1642  ret = addrinfo_getnameinfo(1, &vflags, self);
1643  return rb_ary_entry(ret, 0);
1644 }
1645 
1646 /*
1647  * call-seq:
1648  * addrinfo.ip_port => port
1649  *
1650  * Returns the port number as an integer.
1651  *
1652  * Addrinfo.tcp("127.0.0.1", 80).ip_port #=> 80
1653  * Addrinfo.tcp("::1", 80).ip_port #=> 80
1654  */
1655 static VALUE
1657 {
1658  rb_addrinfo_t *rai = get_addrinfo(self);
1659  int family = ai_get_afamily(rai);
1660  int port;
1661 
1662  if (!IS_IP_FAMILY(family)) {
1663  bad_family:
1664 #ifdef AF_INET6
1665  rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
1666 #else
1667  rb_raise(rb_eSocket, "need IPv4 address");
1668 #endif
1669  }
1670 
1671  switch (family) {
1672  case AF_INET:
1673  if (rai->sockaddr_len != sizeof(struct sockaddr_in))
1674  rb_raise(rb_eSocket, "unexpected sockaddr size for IPv4");
1675  port = ntohs(((struct sockaddr_in *)&rai->addr)->sin_port);
1676  break;
1677 
1678 #ifdef AF_INET6
1679  case AF_INET6:
1680  if (rai->sockaddr_len != sizeof(struct sockaddr_in6))
1681  rb_raise(rb_eSocket, "unexpected sockaddr size for IPv6");
1682  port = ntohs(((struct sockaddr_in6 *)&rai->addr)->sin6_port);
1683  break;
1684 #endif
1685 
1686  default:
1687  goto bad_family;
1688  }
1689 
1690  return INT2NUM(port);
1691 }
1692 
1693 static int
1695 {
1696  rb_addrinfo_t *rai = get_addrinfo(self);
1697  int family = ai_get_afamily(rai);
1698  if (family != AF_INET) return 0;
1699  *addrp = ntohl(((struct sockaddr_in *)&rai->addr)->sin_addr.s_addr);
1700  return 1;
1701 }
1702 
1703 /*
1704  * Returns true for IPv4 private address (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).
1705  * It returns false otherwise.
1706  */
1707 static VALUE
1709 {
1710  uint32_t a;
1711  if (!extract_in_addr(self, &a)) return Qfalse;
1712  if ((a & 0xff000000) == 0x0a000000 || /* 10.0.0.0/8 */
1713  (a & 0xfff00000) == 0xac100000 || /* 172.16.0.0/12 */
1714  (a & 0xffff0000) == 0xc0a80000) /* 192.168.0.0/16 */
1715  return Qtrue;
1716  return Qfalse;
1717 }
1718 
1719 /*
1720  * Returns true for IPv4 loopback address (127.0.0.0/8).
1721  * It returns false otherwise.
1722  */
1723 static VALUE
1725 {
1726  uint32_t a;
1727  if (!extract_in_addr(self, &a)) return Qfalse;
1728  if ((a & 0xff000000) == 0x7f000000) /* 127.0.0.0/8 */
1729  return Qtrue;
1730  return Qfalse;
1731 }
1732 
1733 /*
1734  * Returns true for IPv4 multicast address (224.0.0.0/4).
1735  * It returns false otherwise.
1736  */
1737 static VALUE
1739 {
1740  uint32_t a;
1741  if (!extract_in_addr(self, &a)) return Qfalse;
1742  if ((a & 0xf0000000) == 0xe0000000) /* 224.0.0.0/4 */
1743  return Qtrue;
1744  return Qfalse;
1745 }
1746 
1747 #ifdef INET6
1748 
1749 static struct in6_addr *
1750 extract_in6_addr(VALUE self)
1751 {
1752  rb_addrinfo_t *rai = get_addrinfo(self);
1753  int family = ai_get_afamily(rai);
1754  if (family != AF_INET6) return NULL;
1755  return &((struct sockaddr_in6 *)&rai->addr)->sin6_addr;
1756 }
1757 
1758 /*
1759  * Returns true for IPv6 unspecified address (::).
1760  * It returns false otherwise.
1761  */
1762 static VALUE
1763 addrinfo_ipv6_unspecified_p(VALUE self)
1764 {
1765  struct in6_addr *addr = extract_in6_addr(self);
1766  if (addr && IN6_IS_ADDR_UNSPECIFIED(addr)) return Qtrue;
1767  return Qfalse;
1768 }
1769 
1770 /*
1771  * Returns true for IPv6 loopback address (::1).
1772  * It returns false otherwise.
1773  */
1774 static VALUE
1775 addrinfo_ipv6_loopback_p(VALUE self)
1776 {
1777  struct in6_addr *addr = extract_in6_addr(self);
1778  if (addr && IN6_IS_ADDR_LOOPBACK(addr)) return Qtrue;
1779  return Qfalse;
1780 }
1781 
1782 /*
1783  * Returns true for IPv6 multicast address (ff00::/8).
1784  * It returns false otherwise.
1785  */
1786 static VALUE
1787 addrinfo_ipv6_multicast_p(VALUE self)
1788 {
1789  struct in6_addr *addr = extract_in6_addr(self);
1790  if (addr && IN6_IS_ADDR_MULTICAST(addr)) return Qtrue;
1791  return Qfalse;
1792 }
1793 
1794 /*
1795  * Returns true for IPv6 link local address (ff80::/10).
1796  * It returns false otherwise.
1797  */
1798 static VALUE
1799 addrinfo_ipv6_linklocal_p(VALUE self)
1800 {
1801  struct in6_addr *addr = extract_in6_addr(self);
1802  if (addr && IN6_IS_ADDR_LINKLOCAL(addr)) return Qtrue;
1803  return Qfalse;
1804 }
1805 
1806 /*
1807  * Returns true for IPv6 site local address (ffc0::/10).
1808  * It returns false otherwise.
1809  */
1810 static VALUE
1811 addrinfo_ipv6_sitelocal_p(VALUE self)
1812 {
1813  struct in6_addr *addr = extract_in6_addr(self);
1814  if (addr && IN6_IS_ADDR_SITELOCAL(addr)) return Qtrue;
1815  return Qfalse;
1816 }
1817 
1818 /*
1819  * Returns true for IPv6 unique local address (fc00::/7, RFC4193).
1820  * It returns false otherwise.
1821  */
1822 static VALUE
1823 addrinfo_ipv6_unique_local_p(VALUE self)
1824 {
1825  struct in6_addr *addr = extract_in6_addr(self);
1826  if (addr && IN6_IS_ADDR_UNIQUE_LOCAL(addr)) return Qtrue;
1827  return Qfalse;
1828 }
1829 
1830 /*
1831  * Returns true for IPv4-mapped IPv6 address (::ffff:0:0/80).
1832  * It returns false otherwise.
1833  */
1834 static VALUE
1835 addrinfo_ipv6_v4mapped_p(VALUE self)
1836 {
1837  struct in6_addr *addr = extract_in6_addr(self);
1838  if (addr && IN6_IS_ADDR_V4MAPPED(addr)) return Qtrue;
1839  return Qfalse;
1840 }
1841 
1842 /*
1843  * Returns true for IPv4-compatible IPv6 address (::/80).
1844  * It returns false otherwise.
1845  */
1846 static VALUE
1847 addrinfo_ipv6_v4compat_p(VALUE self)
1848 {
1849  struct in6_addr *addr = extract_in6_addr(self);
1850  if (addr && IN6_IS_ADDR_V4COMPAT(addr)) return Qtrue;
1851  return Qfalse;
1852 }
1853 
1854 /*
1855  * Returns true for IPv6 multicast node-local scope address.
1856  * It returns false otherwise.
1857  */
1858 static VALUE
1859 addrinfo_ipv6_mc_nodelocal_p(VALUE self)
1860 {
1861  struct in6_addr *addr = extract_in6_addr(self);
1862  if (addr && IN6_IS_ADDR_MC_NODELOCAL(addr)) return Qtrue;
1863  return Qfalse;
1864 }
1865 
1866 /*
1867  * Returns true for IPv6 multicast link-local scope address.
1868  * It returns false otherwise.
1869  */
1870 static VALUE
1871 addrinfo_ipv6_mc_linklocal_p(VALUE self)
1872 {
1873  struct in6_addr *addr = extract_in6_addr(self);
1874  if (addr && IN6_IS_ADDR_MC_LINKLOCAL(addr)) return Qtrue;
1875  return Qfalse;
1876 }
1877 
1878 /*
1879  * Returns true for IPv6 multicast site-local scope address.
1880  * It returns false otherwise.
1881  */
1882 static VALUE
1883 addrinfo_ipv6_mc_sitelocal_p(VALUE self)
1884 {
1885  struct in6_addr *addr = extract_in6_addr(self);
1886  if (addr && IN6_IS_ADDR_MC_SITELOCAL(addr)) return Qtrue;
1887  return Qfalse;
1888 }
1889 
1890 /*
1891  * Returns true for IPv6 multicast organization-local scope address.
1892  * It returns false otherwise.
1893  */
1894 static VALUE
1895 addrinfo_ipv6_mc_orglocal_p(VALUE self)
1896 {
1897  struct in6_addr *addr = extract_in6_addr(self);
1898  if (addr && IN6_IS_ADDR_MC_ORGLOCAL(addr)) return Qtrue;
1899  return Qfalse;
1900 }
1901 
1902 /*
1903  * Returns true for IPv6 multicast global scope address.
1904  * It returns false otherwise.
1905  */
1906 static VALUE
1907 addrinfo_ipv6_mc_global_p(VALUE self)
1908 {
1909  struct in6_addr *addr = extract_in6_addr(self);
1910  if (addr && IN6_IS_ADDR_MC_GLOBAL(addr)) return Qtrue;
1911  return Qfalse;
1912 }
1913 
1914 /*
1915  * Returns IPv4 address of IPv4 mapped/compatible IPv6 address.
1916  * It returns nil if +self+ is not IPv4 mapped/compatible IPv6 address.
1917  *
1918  * Addrinfo.ip("::192.0.2.3").ipv6_to_ipv4 #=> #<Addrinfo: 192.0.2.3>
1919  * Addrinfo.ip("::ffff:192.0.2.3").ipv6_to_ipv4 #=> #<Addrinfo: 192.0.2.3>
1920  * Addrinfo.ip("::1").ipv6_to_ipv4 #=> nil
1921  * Addrinfo.ip("192.0.2.3").ipv6_to_ipv4 #=> nil
1922  * Addrinfo.unix("/tmp/sock").ipv6_to_ipv4 #=> nil
1923  */
1924 static VALUE
1925 addrinfo_ipv6_to_ipv4(VALUE self)
1926 {
1927  rb_addrinfo_t *rai = get_addrinfo(self);
1928  struct in6_addr *addr;
1929  int family = ai_get_afamily(rai);
1930  if (family != AF_INET6) return Qnil;
1931  addr = &((struct sockaddr_in6 *)&rai->addr)->sin6_addr;
1932  if (IN6_IS_ADDR_V4MAPPED(addr) || IN6_IS_ADDR_V4COMPAT(addr)) {
1933  struct sockaddr_in sin4;
1934  MEMZERO(&sin4, struct sockaddr_in, 1);
1935  sin4.sin_family = AF_INET;
1936  SET_SIN_LEN(&sin4, sizeof(sin4));
1937  memcpy(&sin4.sin_addr, (char*)addr + sizeof(*addr) - sizeof(sin4.sin_addr), sizeof(sin4.sin_addr));
1938  return rsock_addrinfo_new((struct sockaddr *)&sin4, (socklen_t)sizeof(sin4),
1939  PF_INET, rai->socktype, rai->protocol,
1940  rai->canonname, rai->inspectname);
1941  }
1942  else {
1943  return Qnil;
1944  }
1945 }
1946 
1947 #endif
1948 
1949 #ifdef HAVE_SYS_UN_H
1950 /*
1951  * call-seq:
1952  * addrinfo.unix_path => path
1953  *
1954  * Returns the socket path as a string.
1955  *
1956  * Addrinfo.unix("/tmp/sock").unix_path #=> "/tmp/sock"
1957  */
1958 static VALUE
1959 addrinfo_unix_path(VALUE self)
1960 {
1961  rb_addrinfo_t *rai = get_addrinfo(self);
1962  int family = ai_get_afamily(rai);
1963  struct sockaddr_un *addr;
1964  char *s, *e;
1965 
1966  if (family != AF_UNIX)
1967  rb_raise(rb_eSocket, "need AF_UNIX address");
1968 
1969  addr = (struct sockaddr_un *)&rai->addr;
1970 
1971  s = addr->sun_path;
1972  e = (char*)addr + rai->sockaddr_len;
1973  if (e < s)
1974  rb_raise(rb_eSocket, "too short AF_UNIX address: %"PRIuSIZE" bytes given for minimum %"PRIuSIZE" bytes.",
1975  (size_t)rai->sockaddr_len, (size_t)(s - (char *)addr));
1976  if (addr->sun_path + sizeof(addr->sun_path) < e)
1978  "too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
1979  (size_t)(e - addr->sun_path), sizeof(addr->sun_path));
1980  while (s < e && *(e-1) == '\0')
1981  e--;
1982  return rb_str_new(s, e-s);
1983 }
1984 #endif
1985 
1986 /*
1987  * call-seq:
1988  * Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags) => [addrinfo, ...]
1989  * Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol) => [addrinfo, ...]
1990  * Addrinfo.getaddrinfo(nodename, service, family, socktype) => [addrinfo, ...]
1991  * Addrinfo.getaddrinfo(nodename, service, family) => [addrinfo, ...]
1992  * Addrinfo.getaddrinfo(nodename, service) => [addrinfo, ...]
1993  *
1994  * returns a list of addrinfo objects as an array.
1995  *
1996  * This method converts nodename (hostname) and service (port) to addrinfo.
1997  * Since the conversion is not unique, the result is a list of addrinfo objects.
1998  *
1999  * nodename or service can be nil if no conversion intended.
2000  *
2001  * family, socktype and protocol are hint for preferred protocol.
2002  * If the result will be used for a socket with SOCK_STREAM,
2003  * SOCK_STREAM should be specified as socktype.
2004  * If so, Addrinfo.getaddrinfo returns addrinfo list appropriate for SOCK_STREAM.
2005  * If they are omitted or nil is given, the result is not restricted.
2006  *
2007  * Similarly, PF_INET6 as family restricts for IPv6.
2008  *
2009  * flags should be bitwise OR of Socket::AI_??? constants such as follows.
2010  * Note that the exact list of the constants depends on OS.
2011  *
2012  * AI_PASSIVE Get address to use with bind()
2013  * AI_CANONNAME Fill in the canonical name
2014  * AI_NUMERICHOST Prevent host name resolution
2015  * AI_NUMERICSERV Prevent service name resolution
2016  * AI_V4MAPPED Accept IPv4-mapped IPv6 addresses
2017  * AI_ALL Allow all addresses
2018  * AI_ADDRCONFIG Accept only if any address is assigned
2019  *
2020  * Note that socktype should be specified whenever application knows the usage of the address.
2021  * Some platform causes an error when socktype is omitted and servname is specified as an integer
2022  * because some port numbers, 512 for example, are ambiguous without socktype.
2023  *
2024  * Addrinfo.getaddrinfo("www.kame.net", 80, nil, :STREAM)
2025  * #=> [#<Addrinfo: 203.178.141.194:80 TCP (www.kame.net)>,
2026  * # #<Addrinfo: [2001:200:dff:fff1:216:3eff:feb1:44d7]:80 TCP (www.kame.net)>]
2027  *
2028  */
2029 static VALUE
2031 {
2032  VALUE node, service, family, socktype, protocol, flags;
2033 
2034  rb_scan_args(argc, argv, "24", &node, &service, &family, &socktype, &protocol, &flags);
2035  return addrinfo_list_new(node, service, family, socktype, protocol, flags);
2036 }
2037 
2038 /*
2039  * call-seq:
2040  * Addrinfo.ip(host) => addrinfo
2041  *
2042  * returns an addrinfo object for IP address.
2043  *
2044  * The port, socktype, protocol of the result is filled by zero.
2045  * So, it is not appropriate to create a socket.
2046  *
2047  * Addrinfo.ip("localhost") #=> #<Addrinfo: 127.0.0.1 (localhost)>
2048  */
2049 static VALUE
2051 {
2052  VALUE ret;
2053  rb_addrinfo_t *rai;
2054  ret = addrinfo_firstonly_new(host, Qnil,
2055  INT2NUM(PF_UNSPEC), INT2FIX(0), INT2FIX(0), INT2FIX(0));
2056  rai = get_addrinfo(ret);
2057  rai->socktype = 0;
2058  rai->protocol = 0;
2059  return ret;
2060 }
2061 
2062 /*
2063  * call-seq:
2064  * Addrinfo.tcp(host, port) => addrinfo
2065  *
2066  * returns an addrinfo object for TCP address.
2067  *
2068  * Addrinfo.tcp("localhost", "smtp") #=> #<Addrinfo: 127.0.0.1:25 TCP (localhost:smtp)>
2069  */
2070 static VALUE
2071 addrinfo_s_tcp(VALUE self, VALUE host, VALUE port)
2072 {
2073  return addrinfo_firstonly_new(host, port,
2074  INT2NUM(PF_UNSPEC), INT2NUM(SOCK_STREAM), INT2NUM(IPPROTO_TCP), INT2FIX(0));
2075 }
2076 
2077 /*
2078  * call-seq:
2079  * Addrinfo.udp(host, port) => addrinfo
2080  *
2081  * returns an addrinfo object for UDP address.
2082  *
2083  * Addrinfo.udp("localhost", "daytime") #=> #<Addrinfo: 127.0.0.1:13 UDP (localhost:daytime)>
2084  */
2085 static VALUE
2086 addrinfo_s_udp(VALUE self, VALUE host, VALUE port)
2087 {
2088  return addrinfo_firstonly_new(host, port,
2089  INT2NUM(PF_UNSPEC), INT2NUM(SOCK_DGRAM), INT2NUM(IPPROTO_UDP), INT2FIX(0));
2090 }
2091 
2092 #ifdef HAVE_SYS_UN_H
2093 
2094 /*
2095  * call-seq:
2096  * Addrinfo.unix(path [, socktype]) => addrinfo
2097  *
2098  * returns an addrinfo object for UNIX socket address.
2099  *
2100  * _socktype_ specifies the socket type.
2101  * If it is omitted, :STREAM is used.
2102  *
2103  * Addrinfo.unix("/tmp/sock") #=> #<Addrinfo: /tmp/sock SOCK_STREAM>
2104  * Addrinfo.unix("/tmp/sock", :DGRAM) #=> #<Addrinfo: /tmp/sock SOCK_DGRAM>
2105  */
2106 static VALUE
2107 addrinfo_s_unix(int argc, VALUE *argv, VALUE self)
2108 {
2109  VALUE path, vsocktype, addr;
2110  int socktype;
2111  rb_addrinfo_t *rai;
2112 
2113  rb_scan_args(argc, argv, "11", &path, &vsocktype);
2114 
2115  if (NIL_P(vsocktype))
2116  socktype = SOCK_STREAM;
2117  else
2118  socktype = rsock_socktype_arg(vsocktype);
2119 
2121  DATA_PTR(addr) = rai = alloc_addrinfo();
2122  init_unix_addrinfo(rai, path, socktype);
2123  OBJ_INFECT(addr, path);
2124  return addr;
2125 }
2126 
2127 #endif
2128 
2129 VALUE
2131 {
2132  VALUE val = *v;
2133  if (IS_ADDRINFO(val)) {
2134  *v = addrinfo_to_sockaddr(val);
2135  }
2136  StringValue(*v);
2137  return *v;
2138 }
2139 
2140 char *
2142 {
2144  return RSTRING_PTR(*v);
2145 }
2146 
2147 VALUE
2149 {
2150  if (IS_ADDRINFO(val))
2151  return addrinfo_to_sockaddr(val);
2152  return rb_check_string_type(val);
2153 }
2154 
2155 VALUE
2156 rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len)
2157 {
2158  int family;
2159  int socktype;
2160  int ret;
2161  socklen_t optlen = (socklen_t)sizeof(socktype);
2162 
2163  /* assumes protocol family and address family are identical */
2164  family = get_afamily(addr, len);
2165 
2166  ret = getsockopt(fd, SOL_SOCKET, SO_TYPE, (void*)&socktype, &optlen);
2167  if (ret == -1) {
2168  rb_sys_fail("getsockopt(SO_TYPE)");
2169  }
2170 
2171  return rsock_addrinfo_new(addr, len, family, socktype, 0, Qnil, Qnil);
2172 }
2173 
2174 VALUE
2175 rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
2176 {
2177  rb_io_t *fptr;
2178 
2179  switch (TYPE(io)) {
2180  case T_FIXNUM:
2181  return rsock_fd_socket_addrinfo(FIX2INT(io), addr, len);
2182 
2183  case T_BIGNUM:
2184  return rsock_fd_socket_addrinfo(NUM2INT(io), addr, len);
2185 
2186  case T_FILE:
2187  GetOpenFile(io, fptr);
2188  return rsock_fd_socket_addrinfo(fptr->fd, addr, len);
2189 
2190  default:
2191  rb_raise(rb_eTypeError, "neither IO nor file descriptor");
2192  }
2193 
2194  UNREACHABLE;
2195 }
2196 
2197 /*
2198  * Addrinfo class
2199  */
2200 void
2202 {
2203  /*
2204  * The Addrinfo class maps <tt>struct addrinfo</tt> to ruby. This
2205  * structure identifies an Internet host and a service.
2206  */
2207  rb_cAddrinfo = rb_define_class("Addrinfo", rb_cData);
2211  rb_define_method(rb_cAddrinfo, "inspect_sockaddr", addrinfo_inspect_sockaddr, 0);
2216 #ifdef HAVE_SYS_UN_H
2217  rb_define_singleton_method(rb_cAddrinfo, "unix", addrinfo_s_unix, -1);
2218 #endif
2219 
2225 
2229 
2234 
2238 
2239 #ifdef INET6
2240  rb_define_method(rb_cAddrinfo, "ipv6_unspecified?", addrinfo_ipv6_unspecified_p, 0);
2241  rb_define_method(rb_cAddrinfo, "ipv6_loopback?", addrinfo_ipv6_loopback_p, 0);
2242  rb_define_method(rb_cAddrinfo, "ipv6_multicast?", addrinfo_ipv6_multicast_p, 0);
2243  rb_define_method(rb_cAddrinfo, "ipv6_linklocal?", addrinfo_ipv6_linklocal_p, 0);
2244  rb_define_method(rb_cAddrinfo, "ipv6_sitelocal?", addrinfo_ipv6_sitelocal_p, 0);
2245  rb_define_method(rb_cAddrinfo, "ipv6_unique_local?", addrinfo_ipv6_unique_local_p, 0);
2246  rb_define_method(rb_cAddrinfo, "ipv6_v4mapped?", addrinfo_ipv6_v4mapped_p, 0);
2247  rb_define_method(rb_cAddrinfo, "ipv6_v4compat?", addrinfo_ipv6_v4compat_p, 0);
2248  rb_define_method(rb_cAddrinfo, "ipv6_mc_nodelocal?", addrinfo_ipv6_mc_nodelocal_p, 0);
2249  rb_define_method(rb_cAddrinfo, "ipv6_mc_linklocal?", addrinfo_ipv6_mc_linklocal_p, 0);
2250  rb_define_method(rb_cAddrinfo, "ipv6_mc_sitelocal?", addrinfo_ipv6_mc_sitelocal_p, 0);
2251  rb_define_method(rb_cAddrinfo, "ipv6_mc_orglocal?", addrinfo_ipv6_mc_orglocal_p, 0);
2252  rb_define_method(rb_cAddrinfo, "ipv6_mc_global?", addrinfo_ipv6_mc_global_p, 0);
2253 
2254  rb_define_method(rb_cAddrinfo, "ipv6_to_ipv4", addrinfo_ipv6_to_ipv4, 0);
2255 #endif
2256 
2257 #ifdef HAVE_SYS_UN_H
2258  rb_define_method(rb_cAddrinfo, "unix_path", addrinfo_unix_path, 0);
2259 #endif
2260 
2262  rb_define_method(rb_cAddrinfo, "to_s", addrinfo_to_sockaddr, 0); /* compatibility for ruby before 1.9.2 */
2263 
2264  rb_define_method(rb_cAddrinfo, "getnameinfo", addrinfo_getnameinfo, -1);
2265 
2266  rb_define_method(rb_cAddrinfo, "marshal_dump", addrinfo_mdump, 0);
2267  rb_define_method(rb_cAddrinfo, "marshal_load", addrinfo_mload, 1);
2268 }
VALUE inspectname
Definition: raddrinfo.c:536
RUBY_EXTERN VALUE rb_cData
Definition: ruby.h:1433
struct addrinfo * rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags)
Definition: raddrinfo.c:371
static void make_ipaddr0(struct sockaddr *addr, char *buf, size_t len)
Definition: raddrinfo.c:232
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1101
VALUE rb_str_equal(VALUE str1, VALUE str2)
Definition: string.c:2359
static int str_is_number(const char *)
Definition: raddrinfo.c:264
size_t strlen(const char *)
#define INT2NUM(x)
Definition: ruby.h:1178
int i
Definition: win32ole.c:784
#define T_FIXNUM
Definition: ruby.h:497
#define PF_INET
Definition: sockport.h:77
size_t servlen
Definition: raddrinfo.c:194
VALUE rb_id2str(ID id)
Definition: ripper.c:16944
#define NUM2INT(x)
Definition: ruby.h:622
#define NUM2UINT(x)
Definition: ruby.h:623
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1497
static rb_addrinfo_t * check_addrinfo(VALUE self)
Definition: raddrinfo.c:576
#define SA_LEN(sa)
Definition: sockport.h:29
static struct addrinfo * call_getaddrinfo(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags, int socktype_hack)
Definition: raddrinfo.c:635
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:1963
#define NI_DGRAM
Definition: addrinfo.h:128
struct sockaddr_storage addr
Definition: raddrinfo.c:542
#define Qtrue
Definition: ruby.h:434
static VALUE addrinfo_ipv6_p(VALUE self)
Definition: raddrinfo.c:1521
#define SET_SIN_LEN(si, len)
Definition: sockport.h:48
Definition: io.h:63
#define TypedData_Wrap_Struct(klass, data_type, sval)
Definition: ruby.h:1016
int rsock_socktype_arg(VALUE type)
Definition: constants.c:50
static VALUE addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags)
Definition: raddrinfo.c:756
const int id
Definition: nkf.c:209
VALUE rsock_ipaddr(struct sockaddr *sockaddr, int norevlookup)
Definition: raddrinfo.c:383
VALUE rb_eTypeError
Definition: error.c:511
#define UNREACHABLE
Definition: ruby.h:40
const struct sockaddr * sa
Definition: raddrinfo.c:189
st_table * names
Definition: encoding.c:53
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
static void * nogvl_getaddrinfo(void *arg)
Definition: raddrinfo.c:158
static VALUE addrinfo_ipv4_loopback_p(VALUE self)
Definition: raddrinfo.c:1724
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
ID rsock_intern_ipproto(int val)
Definition: constdefs.c:5794
#define IN6_IS_ADDR_UNIQUE_LOCAL(a)
Definition: rubysocket.h:121
static VALUE addrinfo_protocol(VALUE self)
Definition: raddrinfo.c:1420
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2368
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
VALUE rb_check_sockaddr_string_type(VALUE val)
Definition: raddrinfo.c:2148
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
#define DATA_PTR(dta)
Definition: ruby.h:985
void rb_gc_mark(VALUE ptr)
Definition: gc.c:2598
static VALUE addrinfo_ipv4_p(VALUE self)
Definition: raddrinfo.c:1502
#define T_ARRAY
Definition: ruby.h:492
VALUE rb_tainted_str_new_cstr(const char *)
Definition: string.c:479
const char * service
Definition: raddrinfo.c:152
static size_t addrinfo_memsize(const void *ptr)
Definition: raddrinfo.c:558
const struct addrinfo * hints
Definition: raddrinfo.c:153
#define FIXNUM_P(f)
Definition: ruby.h:355
#define GetOpenFile(obj, fp)
Definition: io.h:120
void rsock_init_addrinfo(void)
Definition: raddrinfo.c:2201
static char * host_str(VALUE host, char *hbuf, size_t len, int *flags_ptr)
Definition: raddrinfo.c:279
VALUE rsock_make_ipaddr(struct sockaddr *addr)
Definition: raddrinfo.c:243
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:2175
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
static VALUE addrinfo_ipv4_multicast_p(VALUE self)
Definition: raddrinfo.c:1738
#define NI_MAXSERV
Definition: addrinfo.h:118
static VALUE addrinfo_inspect_sockaddr(VALUE self)
Definition: raddrinfo.c:1169
Win32OLEIDispatch * p
Definition: win32ole.c:786
VALUE rsock_make_hostent(VALUE host, struct addrinfo *addr, VALUE(*ipaddr)(struct sockaddr *, size_t))
Definition: raddrinfo.c:524
static VALUE addrinfo_to_sockaddr(VALUE self)
Definition: raddrinfo.c:1438
#define IS_ADDRINFO(obj)
Definition: raddrinfo.c:574
#define IPPROTO_TCP
Definition: constdefs.h:605
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1537
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname)
Definition: raddrinfo.c:621
#define MEMZERO(p, type, n)
Definition: ruby.h:1241
int rsock_ipproto_to_int(const char *str, long len, int *valp)
Definition: constdefs.c:4182
int rsock_family_arg(VALUE domain)
Definition: constants.c:43
#define val
socklen_t salen
Definition: raddrinfo.c:190
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1982
VALUE rb_ary_new(void)
Definition: array.c:424
static int ai_get_afamily(rb_addrinfo_t *rai)
Definition: raddrinfo.c:949
VALUE rb_str_buf_cat2(VALUE, const char *)
Definition: string.c:1957
static VALUE addrinfo_initialize(int argc, VALUE *argv, VALUE self)
Definition: raddrinfo.c:860
#define STRTOUL(str, endptr, base)
Definition: ruby.h:1649
#define NI_NUMERICSERV
Definition: addrinfo.h:127
#define snprintf
Definition: subst.h:6
#define NIL_P(v)
Definition: ruby.h:446
static VALUE addrinfo_ip_unpack(VALUE self)
Definition: raddrinfo.c:1604
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:499
static VALUE addrinfo_getnameinfo(int argc, VALUE *argv, VALUE self)
Definition: raddrinfo.c:1570
int fd
Definition: io.h:64
char * ai_canonname
Definition: addrinfo.h:137
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:719
#define offsetof(p_type, field)
Definition: addrinfo.h:186
static const rb_data_type_t addrinfo_type
Definition: raddrinfo.c:563
#define TYPE(x)
Definition: ruby.h:513
int argc
Definition: ruby.c:130
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
Definition: getaddrinfo.c:267
#define IPPROTO_UDP
Definition: constdefs.h:622
ID rsock_intern_protocol_family(int val)
Definition: constdefs.c:5776
#define Qfalse
Definition: ruby.h:433
static char * port_str(VALUE port, char *pbuf, size_t len, int *flags_ptr)
Definition: raddrinfo.c:316
#define T_BIGNUM
Definition: ruby.h:495
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1242
#define OBJ_FREEZE(x)
Definition: ruby.h:1164
int rsock_family_to_int(const char *str, long len, int *valp)
Definition: constdefs.c:3718
unsigned short ss_family
Definition: rubysocket.h:139
static VALUE addrinfo_s_udp(VALUE self, VALUE host, VALUE port)
Definition: raddrinfo.c:2086
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
static int get_afamily(struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:940
#define ALLOC(type)
Definition: ruby.h:1224
static VALUE addrinfo_unix_p(VALUE self)
Definition: raddrinfo.c:1544
static void init_addrinfo_getaddrinfo(rb_addrinfo_t *rai, VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags, VALUE inspectnode, VALUE inspectservice)
Definition: raddrinfo.c:663
int rsock_socktype_to_int(const char *str, long len, int *valp)
Definition: constdefs.c:4112
#define IS_IP_FAMILY(af)
Definition: rubysocket.h:117
#define RSTRING_LEN(str)
Definition: ruby.h:862
char * rsock_sockaddr_string_value_ptr(volatile VALUE *v)
Definition: raddrinfo.c:2141
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1270
static void * nogvl_getnameinfo(void *arg)
Definition: raddrinfo.c:199
VALUE rsock_freeaddrinfo(struct addrinfo *addr)
Definition: raddrinfo.c:517
static VALUE addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags)
Definition: raddrinfo.c:731
static VALUE addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self)
Definition: raddrinfo.c:2030
void freeaddrinfo(struct addrinfo *ai)
Definition: getaddrinfo.c:211
#define NI_NUMERICHOST
Definition: addrinfo.h:125
static rb_addrinfo_t * alloc_addrinfo()
Definition: raddrinfo.c:594
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:2156
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
static VALUE addrinfo_mload(VALUE self, VALUE ary)
Definition: raddrinfo.c:1253
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:545
unsigned long ID
Definition: ruby.h:105
static VALUE addrinfo_pfamily(VALUE self)
Definition: raddrinfo.c:1388
socklen_t sockaddr_len
Definition: raddrinfo.c:541
static VALUE addrinfo_ip_address(VALUE self)
Definition: raddrinfo.c:1631
#define Qnil
Definition: ruby.h:435
ID rsock_intern_family(int val)
Definition: constdefs.c:5758
static VALUE addrinfo_s_ip(VALUE self, VALUE host)
Definition: raddrinfo.c:2050
#define INADDR_BROADCAST
Definition: constdefs.h:742
VALUE host
Definition: raddrinfo.c:468
unsigned long VALUE
Definition: ruby.h:104
#define AI_NUMERICHOST
Definition: addrinfo.h:98
RUBY_EXTERN VALUE rb_cInteger
Definition: ruby.h:1441
#define FIX2INT(x)
Definition: ruby.h:624
#define addrinfo_free
Definition: raddrinfo.c:555
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:804
VALUE rb_str_new_cstr(const char *)
Definition: string.c:447
ID rsock_intern_socktype(int val)
Definition: constdefs.c:5785
static VALUE addrinfo_ip_p(VALUE self)
Definition: raddrinfo.c:1482
void rb_sys_fail(const char *mesg)
Definition: error.c:1899
VALUE rb_str_dup(VALUE)
Definition: string.c:946
static VALUE addrinfo_s_allocate(VALUE klass)
Definition: raddrinfo.c:569
static void init_addrinfo(rb_addrinfo_t *rai, struct sockaddr *sa, socklen_t len, int pfamily, int socktype, int protocol, VALUE canonname, VALUE inspectname)
Definition: raddrinfo.c:604
static void make_inetaddr(unsigned int host, char *buf, size_t len)
Definition: raddrinfo.c:252
static VALUE make_hostent_internal(struct hostent_arg *arg)
Definition: raddrinfo.c:474
unsigned int uint32_t
Definition: sha2.h:101
int ai_protocol
Definition: addrinfo.h:135
static VALUE addrinfo_afamily(VALUE self)
Definition: raddrinfo.c:1372
#define StringValueCStr(v)
Definition: ruby.h:548
int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
Definition: raddrinfo.c:210
#define INADDR_ANY
Definition: constdefs.h:735
#define RSTRING_PTR(str)
Definition: ruby.h:866
VALUE rb_eSocket
Definition: init.c:25
#define AI_NUMERICSERV
Definition: addrinfo.h:99
static VALUE inspect_sockaddr(VALUE addrinfo, VALUE ret)
Definition: raddrinfo.c:955
static VALUE addrinfo_canonname(VALUE self)
Definition: raddrinfo.c:1463
#define INT2FIX(i)
Definition: ruby.h:241
static VALUE addrinfo_ipv4_private_p(VALUE self)
Definition: raddrinfo.c:1708
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:483
#define PF_UNSPEC
Definition: sockport.h:73
int ai_socktype
Definition: addrinfo.h:134
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:557
void rsock_raise_socket_error(const char *reason, int error)
Definition: init.c:34
VALUE canonname
Definition: raddrinfo.c:537
size_t hostlen
Definition: raddrinfo.c:192
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1310
VALUE rb_check_string_type(VALUE)
Definition: string.c:1508
static VALUE addrinfo_s_tcp(VALUE self, VALUE host, VALUE port)
Definition: raddrinfo.c:2071
VALUE rb_cAddrinfo
Definition: init.c:23
struct addrinfo * addr
Definition: raddrinfo.c:469
#define T_STRING
Definition: ruby.h:490
#define AF_UNSPEC
Definition: sockport.h:69
struct addrinfo * rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack)
Definition: raddrinfo.c:343
#define PRIuSIZE
Definition: ruby.h:189
#define OBJ_INFECT(x, s)
Definition: ruby.h:1157
int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
Definition: getnameinfo.c:136
v
Definition: win32ole.c:798
#define T_FILE
Definition: ruby.h:496
#define ISPRINT(c)
Definition: ruby.h:1631
struct addrinfo ** res
Definition: raddrinfo.c:154
struct addrinfo * ai_next
Definition: addrinfo.h:139
#define SafeStringValue(v)
Definition: ruby.h:552
static VALUE addrinfo_socktype(VALUE self)
Definition: raddrinfo.c:1404
VALUE rb_ary_new2(long capa)
Definition: array.c:417
const char * name
Definition: nkf.c:208
const char * rb_id2name(ID id)
Definition: ripper.c:17005
static void addrinfo_mark(void *ptr)
Definition: raddrinfo.c:546
#define RSTRING_LENINT(str)
Definition: ruby.h:874
size_t ai_addrlen
Definition: addrinfo.h:136
static VALUE make_inspectname(VALUE node, VALUE service, struct addrinfo *res)
Definition: raddrinfo.c:685
int ai_flags
Definition: addrinfo.h:132
static VALUE addrinfo_ip_port(VALUE self)
Definition: raddrinfo.c:1656
#define NULL
Definition: _sdbm.c:103
#define FIX2LONG(x)
Definition: ruby.h:353
int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
Definition: raddrinfo.c:167
#define NI_MAXHOST
Definition: addrinfo.h:117
VALUE(* ipaddr)(struct sockaddr *, size_t)
Definition: raddrinfo.c:470
const char * node
Definition: raddrinfo.c:151
static VALUE addrinfo_mdump(VALUE self)
Definition: raddrinfo.c:1176
static rb_addrinfo_t * get_addrinfo(VALUE self)
Definition: raddrinfo.c:582
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
static VALUE addrinfo_inspect(VALUE self)
Definition: raddrinfo.c:1089
VALUE rb_str_new2(const char *)
struct sockaddr * ai_addr
Definition: addrinfo.h:138
VALUE rb_eArgError
Definition: error.c:512
static int extract_in_addr(VALUE self, uint32_t *addrp)
Definition: raddrinfo.c:1694
char ** argv
Definition: ruby.c:131
VALUE rsock_sockaddr_string_value(volatile VALUE *v)
Definition: raddrinfo.c:2130
#define ISSPACE(c)
Definition: ruby.h:1632
#define StringValue(v)
Definition: ruby.h:546
#define RUBY_UBF_IO
Definition: intern.h:843
VALUE rb_str_new(const char *, long)
Definition: string.c:425
int ai_family
Definition: addrinfo.h:133