Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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) {
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
149 struct getaddrinfo_arg
150 {
151 const char *node;
152 const char *service;
153 const struct addrinfo *hints;
154 struct addrinfo **res;
155 };
156
157 static void *
158 nogvl_getaddrinfo(void *arg)
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;
181 ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0);
182 return ret;
183 #endif
184 }
185
186 #ifndef GETADDRINFO_EMU
187 struct getnameinfo_arg
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 *
199 nogvl_getnameinfo(void *arg)
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;
226 ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getnameinfo, &arg, RUBY_UBF_IO, 0);
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 {
468 VALUE host;
469 struct addrinfo* addr;
470 VALUE (*ipaddr)(struct sockaddr*, size_t);
471 };
472
473 static VALUE
474 make_hostent_internal(struct hostent_arg *arg)
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
517 rsock_freeaddrinfo(struct addrinfo *addr)
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 {
536 VALUE inspectname;
537 VALUE canonname;
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
563 static const rb_data_type_t addrinfo_type = {
564 "socket/addrinfo",
565 {addrinfo_mark, addrinfo_free, addrinfo_memsize,},
566 };
567
568 static VALUE
569 addrinfo_s_allocate(VALUE klass)
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 *
576 check_addrinfo(VALUE self)
577 {
578 return rb_check_typeddata(self, &addrinfo_type);
579 }
580
581 static rb_addrinfo_t *
582 get_addrinfo(VALUE self)
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 *
594 alloc_addrinfo()
595 {
596 rb_addrinfo_t *rai = ALLOC(rb_addrinfo_t);
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
628 a = addrinfo_s_allocate(rb_cAddrinfo);
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 *
635 call_getaddrinfo(VALUE node, VALUE service,
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
663 init_addrinfo_getaddrinfo(rb_addrinfo_t *rai, VALUE node, VALUE service,
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),
695 NI_NUMERICHOST|NI_NUMERICSERV);
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))
798 rb_raise(rb_eArgError,
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
860 addrinfo_initialize(int argc, VALUE *argv, VALUE self)
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
949 ai_get_afamily(rb_addrinfo_t *rai)
950 {
951 return get_afamily((struct sockaddr *)&rai->addr, rai->sockaddr_len);
952 }
953
954 static VALUE
955 inspect_sockaddr(VALUE addrinfo, VALUE ret)
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,
1007 NI_NUMERICHOST|NI_NUMERICSERV);
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
1089 addrinfo_inspect(VALUE self)
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) {
1100 ID id = rsock_intern_protocol_family(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
1169 addrinfo_inspect_sockaddr(VALUE self)
1170 {
1171 return inspect_sockaddr(self, rb_str_new("", 0));
1172 }
1173
1174 /* :nodoc: */
1175 static VALUE
1176 addrinfo_mdump(VALUE self)
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
1183 id = rsock_intern_protocol_family(rai->pfamily);
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),
1239 NI_NUMERICHOST|NI_NUMERICSERV);
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
1253 addrinfo_mload(VALUE self, VALUE ary)
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))
1327 rb_raise(rb_eSocket,
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
1372 addrinfo_afamily(VALUE self)
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
1388 addrinfo_pfamily(VALUE self)
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
1404 addrinfo_socktype(VALUE self)
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
1420 addrinfo_protocol(VALUE self)
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
1438 addrinfo_to_sockaddr(VALUE self)
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
1463 addrinfo_canonname(VALUE self)
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
1482 addrinfo_ip_p(VALUE self)
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
1502 addrinfo_ipv4_p(VALUE self)
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
1521 addrinfo_ipv6_p(VALUE self)
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
1544 addrinfo_unix_p(VALUE self)
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
1570 addrinfo_getnameinfo(int argc, VALUE *argv, VALUE self)
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
1604 addrinfo_ip_unpack(VALUE self)
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
1614 vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV);
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
1631 addrinfo_ip_address(VALUE self)
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
1641 vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV);
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
1656 addrinfo_ip_port(VALUE self)
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
1694 extract_in_addr(VALUE self, uint32_t *addrp)
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
1708 addrinfo_ipv4_private_p(VALUE self)
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
1724 addrinfo_ipv4_loopback_p(VALUE self)
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
1738 addrinfo_ipv4_multicast_p(VALUE self)
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)
1977 rb_raise(rb_eSocket,
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
2030 addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self)
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
2050 addrinfo_s_ip(VALUE self, VALUE host)
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
2120 addr = addrinfo_s_allocate(rb_cAddrinfo);
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
2130 rsock_sockaddr_string_value(volatile VALUE *v)
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 *
2141 rsock_sockaddr_string_value_ptr(volatile VALUE *v)
2142 {
2143 rsock_sockaddr_string_value(v);
2144 return RSTRING_PTR(*v);
2145 }
2146
2147 VALUE
2148 rb_check_sockaddr_string_type(VALUE val)
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
2201 rsock_init_addrinfo(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);
2208 rb_define_alloc_func(rb_cAddrinfo, addrinfo_s_allocate);
2209 rb_define_method(rb_cAddrinfo, "initialize", addrinfo_initialize, -1);
2210 rb_define_method(rb_cAddrinfo, "inspect", addrinfo_inspect, 0);
2211 rb_define_method(rb_cAddrinfo, "inspect_sockaddr", addrinfo_inspect_sockaddr, 0);
2212 rb_define_singleton_method(rb_cAddrinfo, "getaddrinfo", addrinfo_s_getaddrinfo, -1);
2213 rb_define_singleton_method(rb_cAddrinfo, "ip", addrinfo_s_ip, 1);
2214 rb_define_singleton_method(rb_cAddrinfo, "tcp", addrinfo_s_tcp, 2);
2215 rb_define_singleton_method(rb_cAddrinfo, "udp", addrinfo_s_udp, 2);
2216 #ifdef HAVE_SYS_UN_H
2217 rb_define_singleton_method(rb_cAddrinfo, "unix", addrinfo_s_unix, -1);
2218 #endif
2219
2220 rb_define_method(rb_cAddrinfo, "afamily", addrinfo_afamily, 0);
2221 rb_define_method(rb_cAddrinfo, "pfamily", addrinfo_pfamily, 0);
2222 rb_define_method(rb_cAddrinfo, "socktype", addrinfo_socktype, 0);
2223 rb_define_method(rb_cAddrinfo, "protocol", addrinfo_protocol, 0);
2224 rb_define_method(rb_cAddrinfo, "canonname", addrinfo_canonname, 0);
2225
2226 rb_define_method(rb_cAddrinfo, "ipv4?", addrinfo_ipv4_p, 0);
2227 rb_define_method(rb_cAddrinfo, "ipv6?", addrinfo_ipv6_p, 0);
2228 rb_define_method(rb_cAddrinfo, "unix?", addrinfo_unix_p, 0);
2229
2230 rb_define_method(rb_cAddrinfo, "ip?", addrinfo_ip_p, 0);
2231 rb_define_method(rb_cAddrinfo, "ip_unpack", addrinfo_ip_unpack, 0);
2232 rb_define_method(rb_cAddrinfo, "ip_address", addrinfo_ip_address, 0);
2233 rb_define_method(rb_cAddrinfo, "ip_port", addrinfo_ip_port, 0);
2234
2235 rb_define_method(rb_cAddrinfo, "ipv4_private?", addrinfo_ipv4_private_p, 0);
2236 rb_define_method(rb_cAddrinfo, "ipv4_loopback?", addrinfo_ipv4_loopback_p, 0);
2237 rb_define_method(rb_cAddrinfo, "ipv4_multicast?", addrinfo_ipv4_multicast_p, 0);
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
2261 rb_define_method(rb_cAddrinfo, "to_sockaddr", addrinfo_to_sockaddr, 0);
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 }
getnameinfo_arg::flags
int flags
Definition: raddrinfo.c:195
RB_TYPE_P
#define RB_TYPE_P(obj, type)
rb_addrinfo_t::inspectname
VALUE inspectname
Definition: raddrinfo.c:536
ALLOC
#define ALLOC(type)
rsock_addrinfo
struct addrinfo * rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags)
Definition: raddrinfo.c:371
make_ipaddr0
static void make_ipaddr0(struct sockaddr *addr, char *buf, size_t len)
Definition: raddrinfo.c:232
ary
volatile VALUE ary
Definition: tcltklib.c:9713
int
VP_EXPORT int
Definition: bigdecimal.c:5050
rb_ary_entry
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1101
str_is_number
static int str_is_number(const char *)
Definition: raddrinfo.c:264
strlen
size_t strlen(const char *)
OBJ_INFECT
#define OBJ_INFECT(x, s)
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
PF_INET
#define PF_INET
Definition: sockport.h:77
getnameinfo_arg::servlen
size_t servlen
Definition: raddrinfo.c:194
rb_id2str
VALUE rb_id2str(ID id)
Definition: ripper.c:16944
p
Win32OLEIDispatch * p
Definition: win32ole.c:786
pair
volatile VALUE pair
Definition: tkutil.c:554
rb_define_singleton_method
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
check_addrinfo
static rb_addrinfo_t * check_addrinfo(VALUE self)
Definition: raddrinfo.c:576
SA_LEN
#define SA_LEN(sa)
Definition: sockport.h:29
call_getaddrinfo
static struct addrinfo * call_getaddrinfo(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags, int socktype_hack)
Definition: raddrinfo.c:635
NI_DGRAM
#define NI_DGRAM
Definition: addrinfo.h:128
getnameinfo_arg::host
char * host
Definition: raddrinfo.c:191
rb_addrinfo_t::addr
struct sockaddr_storage addr
Definition: raddrinfo.c:542
addrinfo_ipv6_p
static VALUE addrinfo_ipv6_p(VALUE self)
Definition: raddrinfo.c:1521
SET_SIN_LEN
#define SET_SIN_LEN(si, len)
Definition: sockport.h:48
i
ssize_t i
Definition: bigdecimal.c:5655
rb_io_t
Definition: io.h:63
rsock_socktype_arg
int rsock_socktype_arg(VALUE type)
Definition: constants.c:50
addrinfo_list_new
static VALUE addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags)
Definition: raddrinfo.c:756
getaddrinfo_arg
Definition: raddrinfo.c:149
getnameinfo_arg::serv
char * serv
Definition: raddrinfo.c:193
rb_str_new_cstr
VALUE rb_str_new_cstr(const char *)
Definition: string.c:447
ret
int ret
Definition: tcltklib.c:280
rsock_ipaddr
VALUE rsock_ipaddr(struct sockaddr *sockaddr, int norevlookup)
Definition: raddrinfo.c:383
a
Real * a
Definition: bigdecimal.c:1182
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:511
OBJ_FREEZE
#define OBJ_FREEZE(x)
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
UNREACHABLE
#define UNREACHABLE
Definition: ruby.h:40
names
st_table * names
Definition: encoding.c:53
RUBY_UBF_IO
#define RUBY_UBF_IO
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
nogvl_getaddrinfo
static void * nogvl_getaddrinfo(void *arg)
Definition: raddrinfo.c:158
path
gz path
Definition: zlib.c:2279
TYPE
#define TYPE(x)
hostent_arg
Definition: raddrinfo.c:467
RSTRING_PTR
#define RSTRING_PTR(str)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
T_ARRAY
#define T_ARRAY
rb_str_buf_cat2
VALUE rb_str_buf_cat2(VALUE, const char *)
Definition: string.c:1957
addrinfo_ipv4_loopback_p
static VALUE addrinfo_ipv4_loopback_p(VALUE self)
Definition: raddrinfo.c:1724
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
rsock_intern_ipproto
ID rsock_intern_ipproto(int val)
Definition: constdefs.c:5794
IN6_IS_ADDR_UNIQUE_LOCAL
#define IN6_IS_ADDR_UNIQUE_LOCAL(a)
Definition: rubysocket.h:121
Qtrue
return Qtrue
Definition: tcltklib.c:9610
addrinfo_protocol
static VALUE addrinfo_protocol(VALUE self)
Definition: raddrinfo.c:1420
T_FILE
#define T_FILE
SafeStringValue
#define SafeStringValue(v)
rb_check_sockaddr_string_type
VALUE rb_check_sockaddr_string_type(VALUE val)
Definition: raddrinfo.c:2148
rb_ary_new3
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
addrinfo_ipv4_p
static VALUE addrinfo_ipv4_p(VALUE self)
Definition: raddrinfo.c:1502
r
r
Definition: bigdecimal.c:1196
rb_str_new2
#define rb_str_new2
getaddrinfo_arg::service
const char * service
Definition: raddrinfo.c:152
addrinfo_memsize
static size_t addrinfo_memsize(const void *ptr)
Definition: raddrinfo.c:558
STRTOUL
#define STRTOUL(str, endptr, base)
GetOpenFile
#define GetOpenFile(obj, fp)
Definition: io.h:120
rsock_init_addrinfo
void rsock_init_addrinfo(void)
Definition: raddrinfo.c:2201
host_str
static char * host_str(VALUE host, char *hbuf, size_t len, int *flags_ptr)
Definition: raddrinfo.c:279
rsock_make_ipaddr
VALUE rsock_make_ipaddr(struct sockaddr *addr)
Definition: raddrinfo.c:243
rsock_io_socket_addrinfo
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:2175
rb_str_equal
VALUE rb_str_equal(VALUE str1, VALUE str2)
Definition: string.c:2359
addrinfo_ipv4_multicast_p
static VALUE addrinfo_ipv4_multicast_p(VALUE self)
Definition: raddrinfo.c:1738
NI_MAXSERV
#define NI_MAXSERV
Definition: addrinfo.h:118
addrinfo_inspect_sockaddr
static VALUE addrinfo_inspect_sockaddr(VALUE self)
Definition: raddrinfo.c:1169
rsock_make_hostent
VALUE rsock_make_hostent(VALUE host, struct addrinfo *addr, VALUE(*ipaddr)(struct sockaddr *, size_t))
Definition: raddrinfo.c:524
addrinfo_to_sockaddr
static VALUE addrinfo_to_sockaddr(VALUE self)
Definition: raddrinfo.c:1438
MEMZERO
#define MEMZERO(p, type, n)
IS_ADDRINFO
#define IS_ADDRINFO(obj)
Definition: raddrinfo.c:574
IPPROTO_TCP
#define IPPROTO_TCP
Definition: constdefs.h:605
strcpy
strcpy(cmd2, cmd)
rsock_addrinfo_new
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname)
Definition: raddrinfo.c:621
memset
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
rsock_ipproto_to_int
int rsock_ipproto_to_int(const char *str, long len, int *valp)
Definition: constdefs.c:4182
Qfalse
return Qfalse
Definition: tcltklib.c:6779
FIXNUM_P
#define FIXNUM_P(f)
rsock_family_arg
int rsock_family_arg(VALUE domain)
Definition: constants.c:43
Qnil
#define Qnil
Definition: tcltklib.c:1896
val
#define val
Definition: tcltklib.c:1949
getnameinfo_arg::salen
socklen_t salen
Definition: raddrinfo.c:190
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:424
ai_get_afamily
static int ai_get_afamily(rb_addrinfo_t *rai)
Definition: raddrinfo.c:949
StringValueCStr
#define StringValueCStr(v)
flags
int flags
Definition: tcltklib.c:3023
ID
unsigned long ID
Definition: ripper.y:105
PRIuSIZE
#define PRIuSIZE
addrinfo_initialize
static VALUE addrinfo_initialize(int argc, VALUE *argv, VALUE self)
Definition: raddrinfo.c:860
NI_NUMERICSERV
#define NI_NUMERICSERV
Definition: addrinfo.h:127
rb_gc_mark
void rb_gc_mark(VALUE)
Definition: gc.c:2598
addrinfo_ip_unpack
static VALUE addrinfo_ip_unpack(VALUE self)
Definition: raddrinfo.c:1604
rb_str_cat2
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1982
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:499
RSTRING_LEN
#define RSTRING_LEN(str)
FIX2INT
#define FIX2INT(x)
addrinfo_getnameinfo
static VALUE addrinfo_getnameinfo(int argc, VALUE *argv, VALUE self)
Definition: raddrinfo.c:1570
INT2FIX
#define INT2FIX(i)
rb_io_t::fd
int fd
Definition: io.h:64
addrinfo::ai_canonname
char * ai_canonname
Definition: addrinfo.h:137
rb_ary_store
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:719
FIX2LONG
#define FIX2LONG(x)
offsetof
#define offsetof(p_type, field)
Definition: addrinfo.h:186
addrinfo_type
static const rb_data_type_t addrinfo_type
Definition: raddrinfo.c:563
T_STRING
#define T_STRING
getaddrinfo
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
Definition: getaddrinfo.c:267
IPPROTO_UDP
#define IPPROTO_UDP
Definition: constdefs.h:622
rsock_intern_protocol_family
ID rsock_intern_protocol_family(int val)
Definition: constdefs.c:5776
port_str
static char * port_str(VALUE port, char *pbuf, size_t len, int *flags_ptr)
Definition: raddrinfo.c:316
TypedData_Wrap_Struct
#define TypedData_Wrap_Struct(klass, data_type, sval)
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
rsock_family_to_int
int rsock_family_to_int(const char *str, long len, int *valp)
Definition: constdefs.c:3718
sockaddr_storage::ss_family
unsigned short ss_family
Definition: rubysocket.h:139
addrinfo_s_udp
static VALUE addrinfo_s_udp(VALUE self, VALUE host, VALUE port)
Definition: raddrinfo.c:2086
rb_thread_call_without_gvl
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
get_afamily
static int get_afamily(struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:940
addrinfo_unix_p
static VALUE addrinfo_unix_p(VALUE self)
Definition: raddrinfo.c:1544
rb_str_dup
VALUE rb_str_dup(VALUE)
Definition: string.c:946
rb_tainted_str_new_cstr
VALUE rb_tainted_str_new_cstr(const char *)
Definition: string.c:479
init_addrinfo_getaddrinfo
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
argv
VALUE * argv
Definition: tcltklib.c:1971
rb_cInteger
RUBY_EXTERN VALUE rb_cInteger
Definition: ripper.y:1441
rsock_socktype_to_int
int rsock_socktype_to_int(const char *str, long len, int *valp)
Definition: constdefs.c:4112
IS_IP_FAMILY
#define IS_IP_FAMILY(af)
Definition: rubysocket.h:117
memcpy
memcpy(buf+1, str, len)
id
const int id
Definition: nkf.c:209
rsock_sockaddr_string_value_ptr
char * rsock_sockaddr_string_value_ptr(volatile VALUE *v)
Definition: raddrinfo.c:2141
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1270
StringValue
#define StringValue(v)
nogvl_getnameinfo
static void * nogvl_getnameinfo(void *arg)
Definition: raddrinfo.c:199
rsock_freeaddrinfo
VALUE rsock_freeaddrinfo(struct addrinfo *addr)
Definition: raddrinfo.c:517
addrinfo_firstonly_new
static VALUE addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags)
Definition: raddrinfo.c:731
s
register char * s
Definition: os2.c:56
addrinfo_s_getaddrinfo
static VALUE addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self)
Definition: raddrinfo.c:2030
freeaddrinfo
void freeaddrinfo(struct addrinfo *ai)
Definition: getaddrinfo.c:211
NI_NUMERICHOST
#define NI_NUMERICHOST
Definition: addrinfo.h:125
alloc_addrinfo
static rb_addrinfo_t * alloc_addrinfo()
Definition: raddrinfo.c:594
void
VP_EXPORT void
Definition: bigdecimal.c:5083
rsock_fd_socket_addrinfo
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:2156
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
addrinfo_mload
static VALUE addrinfo_mload(VALUE self, VALUE ary)
Definition: raddrinfo.c:1253
NUM2UINT
#define NUM2UINT(x)
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:545
addrinfo_pfamily
static VALUE addrinfo_pfamily(VALUE self)
Definition: raddrinfo.c:1388
rb_addrinfo_t::sockaddr_len
socklen_t sockaddr_len
Definition: raddrinfo.c:541
sockaddr_storage
Definition: rubysocket.h:134
addrinfo_ip_address
static VALUE addrinfo_ip_address(VALUE self)
Definition: raddrinfo.c:1631
rsock_intern_family
ID rsock_intern_family(int val)
Definition: constdefs.c:5758
addrinfo_s_ip
static VALUE addrinfo_s_ip(VALUE self, VALUE host)
Definition: raddrinfo.c:2050
INADDR_BROADCAST
#define INADDR_BROADCAST
Definition: constdefs.h:742
hostent_arg::host
VALUE host
Definition: raddrinfo.c:468
T_FIXNUM
#define T_FIXNUM
argc
int argc
Definition: tcltklib.c:1970
getnameinfo_arg::sa
struct sockaddr * sa
Definition: raddrinfo.c:189
AI_NUMERICHOST
#define AI_NUMERICHOST
Definition: addrinfo.h:98
addrinfo_free
#define addrinfo_free
Definition: raddrinfo.c:555
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:804
rsock_intern_socktype
ID rsock_intern_socktype(int val)
Definition: constdefs.c:5785
addrinfo_ip_p
static VALUE addrinfo_ip_p(VALUE self)
Definition: raddrinfo.c:1482
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:1899
addrinfo_s_allocate
static VALUE addrinfo_s_allocate(VALUE klass)
Definition: raddrinfo.c:569
ptr
return ptr
Definition: tcltklib.c:784
init_addrinfo
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
make_inetaddr
static void make_inetaddr(unsigned int host, char *buf, size_t len)
Definition: raddrinfo.c:252
T_BIGNUM
#define T_BIGNUM
make_hostent_internal
static VALUE make_hostent_internal(struct hostent_arg *arg)
Definition: raddrinfo.c:474
rb_addrinfo_t::protocol
int protocol
Definition: raddrinfo.c:540
uint32_t
unsigned int uint32_t
Definition: sha2.h:101
MEMCPY
#define MEMCPY(p1, p2, type, n)
addrinfo::ai_protocol
int ai_protocol
Definition: addrinfo.h:135
addrinfo_afamily
static VALUE addrinfo_afamily(VALUE self)
Definition: raddrinfo.c:1372
rb_getnameinfo
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
INADDR_ANY
#define INADDR_ANY
Definition: constdefs.h:735
rb_eSocket
VALUE rb_eSocket
Definition: init.c:25
AI_NUMERICSERV
#define AI_NUMERICSERV
Definition: addrinfo.h:99
arg
arg
Definition: ripper.y:1315
rb_str_cat
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:1963
inspect_sockaddr
static VALUE inspect_sockaddr(VALUE addrinfo, VALUE ret)
Definition: raddrinfo.c:955
addrinfo_canonname
static VALUE addrinfo_canonname(VALUE self)
Definition: raddrinfo.c:1463
addrinfo_ipv4_private_p
static VALUE addrinfo_ipv4_private_p(VALUE self)
Definition: raddrinfo.c:1708
rubysocket.h
rb_check_typeddata
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:483
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
PF_UNSPEC
#define PF_UNSPEC
Definition: sockport.h:73
addrinfo::ai_socktype
int ai_socktype
Definition: addrinfo.h:134
rb_data_type_struct
Definition: ripper.y:960
rb_check_array_type
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:557
DATA_PTR
DATA_PTR(self)
rsock_raise_socket_error
void rsock_raise_socket_error(const char *reason, int error)
Definition: init.c:34
rb_addrinfo_t::canonname
VALUE canonname
Definition: raddrinfo.c:537
getnameinfo_arg::hostlen
size_t hostlen
Definition: raddrinfo.c:192
rb_str_catf
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1310
addrinfo_s_tcp
static VALUE addrinfo_s_tcp(VALUE self, VALUE host, VALUE port)
Definition: raddrinfo.c:2071
rb_cAddrinfo
VALUE rb_cAddrinfo
Definition: init.c:23
hostent_arg::addr
struct addrinfo * addr
Definition: raddrinfo.c:469
AF_UNSPEC
#define AF_UNSPEC
Definition: sockport.h:69
rsock_getaddrinfo
struct addrinfo * rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack)
Definition: raddrinfo.c:343
klass
klass
Definition: tcltklib.c:3504
INT2NUM
#define INT2NUM(x)
getnameinfo
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
getaddrinfo_arg::hints
struct addrinfo * hints
Definition: raddrinfo.c:153
ISPRINT
#define ISPRINT(c)
Definition: ruby.h:1631
io
gz io
Definition: zlib.c:2263
getaddrinfo_arg::res
struct addrinfo ** res
Definition: raddrinfo.c:154
addrinfo::ai_next
struct addrinfo * ai_next
Definition: addrinfo.h:139
RSTRING_LENINT
#define RSTRING_LENINT(str)
addrinfo_socktype
static VALUE addrinfo_socktype(VALUE self)
Definition: raddrinfo.c:1404
rb_ary_new2
VALUE rb_ary_new2(long capa)
Definition: array.c:417
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:425
res
Real * res
Definition: bigdecimal.c:1233
NUM2INT
#define NUM2INT(x)
rb_id2name
const char * rb_id2name(ID id)
Definition: ripper.c:17005
addrinfo_mark
static void addrinfo_mark(void *ptr)
Definition: raddrinfo.c:546
getnameinfo_arg
Definition: raddrinfo.c:187
e
BDIGIT e
Definition: bigdecimal.c:5085
VALUE
unsigned long VALUE
Definition: ripper.y:104
hostent_arg::ipaddr
VALUE(* ipaddr)(struct sockaddr *, size_t)
Definition: raddrinfo.c:470
rb_addrinfo_t
Definition: raddrinfo.c:535
addrinfo::ai_addrlen
size_t ai_addrlen
Definition: addrinfo.h:136
make_inspectname
static VALUE make_inspectname(VALUE node, VALUE service, struct addrinfo *res)
Definition: raddrinfo.c:685
addrinfo
Definition: addrinfo.h:131
snprintf
#define snprintf
addrinfo::ai_flags
int ai_flags
Definition: addrinfo.h:132
v
BDIGIT v
Definition: bigdecimal.c:5656
addrinfo_ip_port
static VALUE addrinfo_ip_port(VALUE self)
Definition: raddrinfo.c:1656
rb_cData
RUBY_EXTERN VALUE rb_cData
Definition: ripper.y:1433
NULL
#define NULL
Definition: _sdbm.c:103
name
const char * name
Definition: nkf.c:208
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:1508
rb_getaddrinfo
int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
Definition: raddrinfo.c:167
NI_MAXHOST
#define NI_MAXHOST
Definition: addrinfo.h:117
getaddrinfo_arg::node
const char * node
Definition: raddrinfo.c:151
addrinfo_mdump
static VALUE addrinfo_mdump(VALUE self)
Definition: raddrinfo.c:1176
get_addrinfo
static rb_addrinfo_t * get_addrinfo(VALUE self)
Definition: raddrinfo.c:582
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
addrinfo_inspect
static VALUE addrinfo_inspect(VALUE self)
Definition: raddrinfo.c:1089
addrinfo::ai_addr
struct sockaddr * ai_addr
Definition: addrinfo.h:138
rb_eArgError
VALUE rb_eArgError
Definition: error.c:512
rb_convert_type
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2368
rb_addrinfo_t::pfamily
int pfamily
Definition: raddrinfo.c:538
rb_addrinfo_t::socktype
int socktype
Definition: raddrinfo.c:539
extract_in_addr
static int extract_in_addr(VALUE self, uint32_t *addrp)
Definition: raddrinfo.c:1694
rsock_sockaddr_string_value
VALUE rsock_sockaddr_string_value(volatile VALUE *v)
Definition: raddrinfo.c:2130
ISSPACE
#define ISSPACE(c)
Definition: ruby.h:1632
len
size_t len
Definition: tcltklib.c:3568
addrinfo::ai_family
int ai_family
Definition: addrinfo.h:133