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