Last active
August 29, 2015 13:56
-
-
Save shyouhei/9134269 to your computer and use it in GitHub Desktop.
git-strata
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97cbab7 (akr 2009-01-17 04:11:27 +0000) /************************************************ | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ainfo.c - | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) created at: Thu Mar 31 12:21:29 JST 1994 | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) Copyright (C) 1993-2007 Yukihiro Matsumoto | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ************************************************/ | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #include "rubysocket.h" | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #if defined(INET6) && (defined(LOOKUP_ORDER_HACK_INET) || defined(LOOKUP_ORDER_HACK_INET6)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #define LOOKUP_ORDERS (sizeof(lookup_order_table) / sizeof(lookup_order_table[0])) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static const int lookup_order_table[] = { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #if defined(LOOKUP_ORDER_HACK_INET) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) PF_INET, PF_INET6, PF_UNSPEC, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #elif defined(LOOKUP_ORDER_HACK_INET6) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) PF_INET6, PF_INET, PF_UNSPEC, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #else | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) /* should not happen */ | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) }; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static int | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ruby_getaddrinfo(const char *nodename, const char *servname, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) const struct addrinfo *hints, struct addrinfo **res) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct addrinfo tmp_hints; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int i, af, error; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (hints->ai_family != PF_UNSPEC) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return getaddrinfo(nodename, servname, hints, res); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) for (i = 0; i < LOOKUP_ORDERS; i++) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) af = lookup_order_table[i]; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) MEMCPY(&tmp_hints, hints, struct addrinfo, 1); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) tmp_hints.ai_family = af; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) error = getaddrinfo(nodename, servname, &tmp_hints, res); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (error) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (tmp_hints.ai_family == PF_UNSPEC) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) break; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) break; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return error; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo((node),(serv),(hints),(res)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #if defined(_AIX) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static int | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ruby_getaddrinfo__aix(const char *nodename, const char *servname, | |
97cbab7 -> 54886d0 (kanemoto 2010-09-13 16:02:35 +0000) const struct addrinfo *hints, struct addrinfo **res) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int error = getaddrinfo(nodename, servname, hints, res); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct addrinfo *r; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (error) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return error; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) for (r = *res; r != NULL; r = r->ai_next) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (r->ai_addr->sa_family == 0) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) r->ai_addr->sa_family = r->ai_family; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (r->ai_addr->sa_len == 0) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) r->ai_addr->sa_len = r->ai_addrlen; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return 0; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #undef getaddrinfo | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__aix((node),(serv),(hints),(res)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static int | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ruby_getnameinfo__aix(const struct sockaddr *sa, size_t salen, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *host, size_t hostlen, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *serv, size_t servlen, int flags) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct sockaddr_in6 *sa6; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) u_int32_t *a6; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (sa->sa_family == AF_INET6) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) sa6 = (struct sockaddr_in6 *)sa; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) a6 = sa6->sin6_addr.u6_addr.u6_addr32; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) strncpy(host, "::", hostlen); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) snprintf(serv, servlen, "%d", sa6->sin6_port); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return 0; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #undef getnameinfo | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #define getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) \ | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ruby_getnameinfo__aix((sa), (salen), (host), (hostlen), (serv), (servlen), (flags)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> acb8b3f -> 89f2c44 -> 512a356 (akr 2010-06-23 15:05:25 +0000) static int str_is_number(const char *); | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) #if defined(__APPLE__) | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) static int | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) ruby_getaddrinfo__darwin(const char *nodename, const char *servname, | |
97cbab7 -> acb8b3f -> 3f4a73f (nobu 2010-09-14 23:26:03 +0000) const struct addrinfo *hints, struct addrinfo **res) | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) { | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) /* fix [ruby-core:29427] */ | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) const char *tmp_servname; | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) struct addrinfo tmp_hints; | |
97cbab7 -> acb8b3f -> 3f4a73f (nobu 2010-09-14 23:26:03 +0000) int error; | |
97cbab7 -> acb8b3f -> 3f4a73f (nobu 2010-09-14 23:26:03 +0000) | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) tmp_servname = servname; | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) MEMCPY(&tmp_hints, hints, struct addrinfo, 1); | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) if (nodename && servname) { | |
97cbab7 -> acb8b3f -> 512a356 (akr 2010-06-23 15:05:25 +0000) if (str_is_number(tmp_servname) && atoi(servname) == 0) { | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) tmp_servname = NULL; | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) #ifdef AI_NUMERICSERV | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) if (tmp_hints.ai_flags) tmp_hints.ai_flags &= ~AI_NUMERICSERV; | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) #endif | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) } | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) } | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) | |
97cbab7 -> acb8b3f -> f77d872 -> 3f4a73f (nobu 2010-09-14 23:26:03 +0000) error = getaddrinfo(nodename, tmp_servname, &tmp_hints, res); | |
97cbab7 -> acb8b3f -> f77d872 -> 3f4a73f (nobu 2010-09-14 23:26:03 +0000) if (error == 0) { | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) /* [ruby-dev:23164] */ | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) struct addrinfo *r; | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) r = *res; | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) while (r) { | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) if (! r->ai_socktype) r->ai_socktype = hints->ai_socktype; | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) if (! r->ai_protocol) { | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) if (r->ai_socktype == SOCK_DGRAM) { | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) r->ai_protocol = IPPROTO_UDP; | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) } | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) else if (r->ai_socktype == SOCK_STREAM) { | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) r->ai_protocol = IPPROTO_TCP; | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) } | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) } | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) r = r->ai_next; | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) } | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) } | |
97cbab7 -> acb8b3f -> f77d872 (akr 2010-06-23 21:24:31 +0000) | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) return error; | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) } | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) #undef getaddrinfo | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__darwin((node),(serv),(hints),(res)) | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) #endif | |
97cbab7 -> acb8b3f (akr 2010-06-23 12:25:07 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifndef GETADDRINFO_EMU | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct getaddrinfo_arg | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) const char *node; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) const char *service; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) const struct addrinfo *hints; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct addrinfo **res; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) }; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> c51a826 (nobu 2012-07-10 13:57:11 +0000) static void * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) nogvl_getaddrinfo(void *arg) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) int ret; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct getaddrinfo_arg *ptr = arg; | |
97cbab7 -> c51a826 -> 7bca2f0 -> 52a802a -> f6921a3 -> e214b1b (kou 2013-06-10 12:51:48 +0000) ret = getaddrinfo(ptr->node, ptr->service, ptr->hints, ptr->res); | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) #ifdef __linux__ | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420] | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) */ | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) if (ret == EAI_SYSTEM && errno == ENOENT) | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) ret = EAI_NONAME; | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) #endif | |
97cbab7 -> 52a802a (naruse 2013-06-10 11:59:36 +0000) return (void *)(VALUE)ret; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) static int | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) numeric_getaddrinfo(const char *node, const char *service, | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) const struct addrinfo *hints, | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) struct addrinfo **res) | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) static const struct { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int socktype; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int protocol; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } list[] = { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) { SOCK_STREAM, IPPROTO_TCP }, | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) { SOCK_DGRAM, IPPROTO_UDP }, | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) { SOCK_RAW, 0 } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) }; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) struct addrinfo *ai = NULL; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) #ifdef HAVE_INET_PTON | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) if (node && (!service || strspn(service, "0123456789") == strlen(service))) { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int port = service ? (unsigned short)atoi(service): 0; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int hint_family = hints ? hints->ai_family : PF_UNSPEC; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int hint_socktype = hints ? hints->ai_socktype : 0; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int hint_protocol = hints ? hints->ai_protocol : 0; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) char ipv4addr[4]; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) #ifdef AF_INET6 | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) char ipv6addr[16]; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) if ((hint_family == PF_UNSPEC || hint_family == PF_INET6) && | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) strspn(node, "0123456789abcdefABCDEF.:") == strlen(node) && | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) inet_pton(AF_INET6, node, ipv6addr)) { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int i; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) for (i = numberof(list)-1; 0 <= i; i--) { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) if ((hint_socktype == 0 || hint_socktype == list[i].socktype) && | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) (hint_protocol == 0 || list[i].protocol == 0 || hint_protocol == list[i].protocol)) { | |
97cbab7 -> 2e6b97a -> 81dfa8b (akr 2014-02-20 13:22:44 +0000) struct addrinfo *ai0 = xcalloc(1, sizeof(struct addrinfo)); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) struct sockaddr_in6 *sa = xmalloc(sizeof(struct sockaddr_in6)); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) INIT_SOCKADDR_IN6(sa, sizeof(struct sockaddr_in6)); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) memcpy(&sa->sin6_addr, ipv6addr, sizeof(ipv6addr)); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) sa->sin6_port = htons(port); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_family = PF_INET6; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_socktype = list[i].socktype; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_protocol = hint_protocol ? hint_protocol : list[i].protocol; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_addrlen = sizeof(struct sockaddr_in6); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_addr = (struct sockaddr *)sa; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_canonname = NULL; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_next = ai; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai = ai0; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) else | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) #endif | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) if ((hint_family == PF_UNSPEC || hint_family == PF_INET) && | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) strspn(node, "0123456789.") == strlen(node) && | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) inet_pton(AF_INET, node, ipv4addr)) { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int i; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) for (i = numberof(list)-1; 0 <= i; i--) { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) if ((hint_socktype == 0 || hint_socktype == list[i].socktype) && | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) (hint_protocol == 0 || list[i].protocol == 0 || hint_protocol == list[i].protocol)) { | |
97cbab7 -> 2e6b97a -> 81dfa8b (akr 2014-02-20 13:22:44 +0000) struct addrinfo *ai0 = xcalloc(1, sizeof(struct addrinfo)); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) struct sockaddr_in *sa = xmalloc(sizeof(struct sockaddr_in)); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) INIT_SOCKADDR_IN(sa, sizeof(struct sockaddr_in)); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) memcpy(&sa->sin_addr, ipv4addr, sizeof(ipv4addr)); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) sa->sin_port = htons(port); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_family = PF_INET; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_socktype = list[i].socktype; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_protocol = hint_protocol ? hint_protocol : list[i].protocol; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_addrlen = sizeof(struct sockaddr_in); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_addr = (struct sockaddr *)sa; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_canonname = NULL; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai0->ai_next = ai; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai = ai0; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) if (ai) { | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) *res = ai; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) return 0; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) #endif | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) return EAI_FAIL; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_getaddrinfo(const char *node, const char *service, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) const struct addrinfo *hints, | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo **res) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct addrinfo *ai; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) int ret; | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) int allocated_by_malloc = 0; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ret = numeric_getaddrinfo(node, service, hints, &ai); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) if (ret == 0) | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) allocated_by_malloc = 1; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifdef GETADDRINFO_EMU | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ret = getaddrinfo(node, service, hints, &ai); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #else | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) struct getaddrinfo_arg arg; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) MEMZERO(&arg, sizeof arg, 1); | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) arg.node = node; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) arg.service = service; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) arg.hints = hints; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) arg.res = &ai; | |
97cbab7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) if (ret == 0) { | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) *res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo)); | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) (*res)->allocated_by_malloc = allocated_by_malloc; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) (*res)->ai = ai; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) } | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) return ret; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) } | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) void | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) rb_freeaddrinfo(struct rb_addrinfo *ai) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) { | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) if (!ai->allocated_by_malloc) | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) freeaddrinfo(ai->ai); | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) else { | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) struct addrinfo *ai1, *ai2; | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai1 = ai->ai; | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) while (ai1) { | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai2 = ai1->ai_next; | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) xfree(ai1->ai_addr); | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) xfree(ai1); | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) ai1 = ai2; | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> dd1c3a7 -> 2e6b97a (akr 2014-02-19 10:37:43 +0000) } | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) xfree(ai); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifndef GETADDRINFO_EMU | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct getnameinfo_arg | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) const struct sockaddr *sa; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) socklen_t salen; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *host; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) size_t hostlen; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *serv; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) size_t servlen; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int flags; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) }; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> c51a826 (nobu 2012-07-10 13:57:11 +0000) static void * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) nogvl_getnameinfo(void *arg) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct getnameinfo_arg *ptr = arg; | |
97cbab7 -> c51a826 -> 7bca2f0 (nobu 2012-07-11 03:17:35 +0000) return (void *)(VALUE)getnameinfo(ptr->sa, ptr->salen, | |
97cbab7 -> c51a826 -> 7bca2f0 (nobu 2012-07-11 03:17:35 +0000) ptr->host, (socklen_t)ptr->hostlen, | |
97cbab7 -> c51a826 -> 7bca2f0 (nobu 2012-07-11 03:17:35 +0000) ptr->serv, (socklen_t)ptr->servlen, | |
97cbab7 -> c51a826 -> 7bca2f0 (nobu 2012-07-11 03:17:35 +0000) ptr->flags); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *host, size_t hostlen, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *serv, size_t servlen, int flags) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifdef GETADDRINFO_EMU | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #else | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct getnameinfo_arg arg; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int ret; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.sa = sa; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.salen = salen; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.host = host; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.hostlen = hostlen; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.serv = serv; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.servlen = servlen; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.flags = flags; | |
97cbab7 -> 4822d20 -> c51a826 -> 7bca2f0 (nobu 2012-07-11 03:17:35 +0000) ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getnameinfo, &arg, RUBY_UBF_IO, 0); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return ret; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static void | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) make_ipaddr0(struct sockaddr *addr, socklen_t addrlen, char *buf, size_t buflen) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int error; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) error = rb_getnameinfo(addr, addrlen, buf, buflen, NULL, 0, NI_NUMERICHOST); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (error) { | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) rsock_raise_socket_error("getnameinfo", error); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE | |
97cbab7 -> c49f05d -> 18a8046 (akr 2013-02-14 11:28:49 +0000) rsock_make_ipaddr(struct sockaddr *addr, socklen_t addrlen) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> be25c48 (akr 2009-02-10 15:39:16 +0000) char hbuf[1024]; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> be25c48 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) make_ipaddr0(addr, addrlen, hbuf, sizeof(hbuf)); | |
97cbab7 -> be25c48 (akr 2009-02-10 15:39:16 +0000) return rb_str_new2(hbuf); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static void | |
97cbab7 -> 4822d20 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) make_inetaddr(unsigned int host, char *buf, size_t buflen) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct sockaddr_in sin; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 1ff7108 -> e41b789 -> 84a525b (akr 2013-02-15 22:08:25 +0000) INIT_SOCKADDR_IN(&sin, sizeof(sin)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) sin.sin_addr.s_addr = host; | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) make_ipaddr0((struct sockaddr*)&sin, sizeof(sin), buf, buflen); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static int | |
97cbab7 -> 512a356 (akr 2010-06-23 15:05:25 +0000) str_is_number(const char *p) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *ep; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!p || *p == '\0') | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return 0; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ep = NULL; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) (void)STRTOUL(p, &ep, 10); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (ep && *ep == '\0') | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return 1; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return 0; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static char* | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (NIL_P(host)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return NULL; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else if (rb_obj_is_kind_of(host, rb_cInteger)) { | |
97cbab7 -> 4822d20 (nobu 2010-04-28 08:14:13 +0000) unsigned int i = NUM2UINT(host); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) make_inetaddr(htonl(i), hbuf, hbuflen); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (flags_ptr) *flags_ptr |= AI_NUMERICHOST; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return hbuf; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *name; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) SafeStringValue(host); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) name = RSTRING_PTR(host); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!name || *name == 0 || (name[0] == '<' && strcmp(name, "<any>") == 0)) { | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) make_inetaddr(INADDR_ANY, hbuf, hbuflen); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (flags_ptr) *flags_ptr |= AI_NUMERICHOST; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) { | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) make_inetaddr(INADDR_BROADCAST, hbuf, hbuflen); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (flags_ptr) *flags_ptr |= AI_NUMERICHOST; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) else if (strlen(name) >= hbuflen) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eArgError, "hostname too long (%"PRIuSIZE")", | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) strlen(name)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) strcpy(hbuf, name); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return hbuf; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static char* | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) port_str(VALUE port, char *pbuf, size_t pbuflen, int *flags_ptr) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (NIL_P(port)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return 0; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else if (FIXNUM_P(port)) { | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) snprintf(pbuf, pbuflen, "%ld", FIX2LONG(port)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifdef AI_NUMERICSERV | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (flags_ptr) *flags_ptr |= AI_NUMERICSERV; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return pbuf; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *serv; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) SafeStringValue(port); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) serv = RSTRING_PTR(port); | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) if (strlen(serv) >= pbuflen) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eArgError, "service name too long (%"PRIuSIZE")", | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) strlen(serv)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) strcpy(pbuf, serv); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return pbuf; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo* | |
97cbab7 -> 172d208 (akr 2009-03-01 06:48:22 +0000) rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo* res = NULL; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char *hostp, *portp; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int error; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int additional_flags = 0; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hostp = host_str(host, hbuf, sizeof(hbuf), &additional_flags); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) portp = port_str(port, pbuf, sizeof(pbuf), &additional_flags); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 512a356 (akr 2010-06-23 15:05:25 +0000) if (socktype_hack && hints->ai_socktype == 0 && str_is_number(portp)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hints->ai_socktype = SOCK_DGRAM; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hints->ai_flags |= additional_flags; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) error = rb_getaddrinfo(hostp, portp, hints, &res); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (error) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (hostp && hostp[strlen(hostp)-1] == '\n') { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eSocket, "newline at the end of hostname"); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) rsock_raise_socket_error("getaddrinfo", error); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return res; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo* | |
97cbab7 -> 172d208 (akr 2009-03-01 06:48:22 +0000) rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct addrinfo hints; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) MEMZERO(&hints, struct addrinfo, 1); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hints.ai_family = AF_UNSPEC; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hints.ai_socktype = socktype; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hints.ai_flags = flags; | |
97cbab7 -> 172d208 (akr 2009-03-01 06:48:22 +0000) return rsock_getaddrinfo(host, port, &hints, 1); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE | |
97cbab7 -> c49f05d -> 18a8046 (akr 2013-02-14 11:28:49 +0000) rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE family, port, addr1, addr2; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE ary; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int error; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char hbuf[1024], pbuf[1024]; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ID id; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) id = rsock_intern_family(sockaddr->sa_family); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (id) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) family = rb_str_dup(rb_id2str(id)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) sprintf(pbuf, "unknown:%d", sockaddr->sa_family); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) family = rb_str_new2(pbuf); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) addr1 = Qnil; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!norevlookup) { | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) error = rb_getnameinfo(sockaddr, sockaddrlen, hbuf, sizeof(hbuf), | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) NULL, 0, 0); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (! error) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) addr1 = rb_str_new2(hbuf); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 -> 18a8046 (akr 2013-02-14 11:28:49 +0000) error = rb_getnameinfo(sockaddr, sockaddrlen, hbuf, sizeof(hbuf), | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (error) { | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) rsock_raise_socket_error("getnameinfo", error); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) addr2 = rb_str_new2(hbuf); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (addr1 == Qnil) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) addr1 = addr2; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) port = INT2FIX(atoi(pbuf)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ary = rb_ary_new3(4, family, port, addr1, addr2); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return ary; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifdef HAVE_SYS_UN_H | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) VALUE | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) char *s, *e; | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) s = sockaddr->sun_path; | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) e = (char *)sockaddr + len; | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) while (s < e && *(e-1) == '\0') | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) e--; | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) if (s <= e) | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) return rb_str_new(s, e-s); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else | |
97cbab7 -> 1413510 (akr 2012-04-26 03:34:12 +0000) return rb_str_new2(""); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return rb_assoc_new(rb_str_new2("AF_UNIX"), | |
97cbab7 -> c49f05d -> 1413510 (akr 2012-04-26 03:34:12 +0000) rsock_unixpath_str(sockaddr, len)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) socklen_t | |
97cbab7 -> ad55d14 -> 07e9f12 (shugo 2013-01-25 23:33:50 +0000) rsock_unix_sockaddr_len(VALUE path) | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) { | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) #ifdef __linux__ | |
97cbab7 -> ad55d14 -> 4ccfb27 (shugo 2013-01-31 04:59:31 +0000) if (RSTRING_LEN(path) == 0) { | |
97cbab7 -> ad55d14 -> 4ccfb27 (shugo 2013-01-31 04:59:31 +0000) /* autobind; see unix(7) for details. */ | |
97cbab7 -> ad55d14 -> 4ccfb27 (shugo 2013-01-31 04:59:31 +0000) return (socklen_t) sizeof(sa_family_t); | |
97cbab7 -> ad55d14 -> 4ccfb27 (shugo 2013-01-31 04:59:31 +0000) } | |
97cbab7 -> ad55d14 -> 4ccfb27 (shugo 2013-01-31 04:59:31 +0000) else if (RSTRING_PTR(path)[0] == '\0') { | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) /* abstract namespace; see unix(7) for details. */ | |
97cbab7 -> ad55d14 -> ce6db8f (akr 2013-04-17 11:01:17 +0000) if (SOCKLEN_MAX - offsetof(struct sockaddr_un, sun_path) < (size_t)RSTRING_LEN(path)) | |
97cbab7 -> ad55d14 -> ce6db8f (akr 2013-04-17 11:01:17 +0000) rb_raise(rb_eArgError, "Linux abstract socket too long"); | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) return (socklen_t) offsetof(struct sockaddr_un, sun_path) + | |
97cbab7 -> ad55d14 -> ce6db8f (akr 2013-04-17 11:01:17 +0000) RSTRING_SOCKLEN(path); | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) } | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) else { | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) #endif | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) return (socklen_t) sizeof(struct sockaddr_un); | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) #ifdef __linux__ | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) } | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) #endif | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct hostent_arg { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE host; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo* addr; | |
97cbab7 -> 66c1e79 (nobu 2013-02-15 07:54:38 +0000) VALUE (*ipaddr)(struct sockaddr*, socklen_t); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) }; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static VALUE | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) make_hostent_internal(struct hostent_arg *arg) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE host = arg->host; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct addrinfo* addr = arg->addr->ai; | |
97cbab7 -> 66c1e79 (nobu 2013-02-15 07:54:38 +0000) VALUE (*ipaddr)(struct sockaddr*, socklen_t) = arg->ipaddr; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct addrinfo *ai; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct hostent *h; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE ary, names; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char **pch; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) const char* hostp; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) char hbuf[NI_MAXHOST]; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ary = rb_ary_new(); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (addr->ai_canonname) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hostp = addr->ai_canonname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hostp = host_str(host, hbuf, sizeof(hbuf), NULL); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_ary_push(ary, rb_str_new2(hostp)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (addr->ai_canonname && (h = gethostbyname(addr->ai_canonname))) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) names = rb_ary_new(); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (h->h_aliases != NULL) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) for (pch = h->h_aliases; *pch; pch++) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_ary_push(names, rb_str_new2(*pch)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) names = rb_ary_new2(0); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_ary_push(ary, names); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_ary_push(ary, INT2NUM(addr->ai_family)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) for (ai = addr; ai; ai = ai->ai_next) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_ary_push(ary, (*ipaddr)(ai->ai_addr, ai->ai_addrlen)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return ary; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE | |
97cbab7 -> c49f05d -> 785f417 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) rsock_freeaddrinfo(VALUE arg) | |
97cbab7 -> c49f05d -> 785f417 (mame 2010-02-26 12:06:17 +0000) { | |
97cbab7 -> c49f05d -> 785f417 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo *addr = (struct rb_addrinfo *)arg; | |
97cbab7 -> c49f05d -> 785f417 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) rb_freeaddrinfo(addr); | |
97cbab7 -> c49f05d -> 785f417 (mame 2010-02-26 12:06:17 +0000) return Qnil; | |
97cbab7 -> c49f05d -> 785f417 (mame 2010-02-26 12:06:17 +0000) } | |
97cbab7 -> c49f05d -> 785f417 (mame 2010-02-26 12:06:17 +0000) | |
97cbab7 -> c49f05d -> 785f417 (mame 2010-02-26 12:06:17 +0000) VALUE | |
97cbab7 -> c49f05d -> 66c1e79 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) rsock_make_hostent(VALUE host, struct rb_addrinfo *addr, VALUE (*ipaddr)(struct sockaddr *, socklen_t)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct hostent_arg arg; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.host = host; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.addr = addr; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) arg.ipaddr = ipaddr; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return rb_ensure(make_hostent_internal, (VALUE)&arg, | |
97cbab7 -> 785f417 (mame 2010-02-26 12:06:17 +0000) rsock_freeaddrinfo, (VALUE)addr); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) typedef struct { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE inspectname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE canonname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int pfamily; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int socktype; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int protocol; | |
97cbab7 -> 4822d20 (nobu 2010-04-28 08:14:13 +0000) socklen_t sockaddr_len; | |
97cbab7 -> c89844d (akr 2013-02-24 17:51:17 +0000) union_sockaddr addr; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } rb_addrinfo_t; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static void | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) addrinfo_mark(void *ptr) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) rb_addrinfo_t *rai = ptr; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (rai) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_gc_mark(rai->inspectname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_gc_mark(rai->canonname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) #define addrinfo_free RUBY_TYPED_DEFAULT_FREE | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) static size_t | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) addrinfo_memsize(const void *ptr) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) return ptr ? sizeof(rb_addrinfo_t) : 0; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) static const rb_data_type_t addrinfo_type = { | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) "socket/addrinfo", | |
97cbab7 -> 0ad3bee -> 25b9eb5 (nobu 2010-07-18 07:31:54 +0000) {addrinfo_mark, addrinfo_free, addrinfo_memsize,}, | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) }; | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static VALUE | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) addrinfo_s_allocate(VALUE klass) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) return TypedData_Wrap_Struct(klass, &addrinfo_type, 0); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 0ad3bee -> d8ac44f (akr 2011-03-28 20:20:33 +0000) #define IS_ADDRINFO(obj) rb_typeddata_is_kind_of((obj), &addrinfo_type) | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) static inline rb_addrinfo_t * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) check_addrinfo(VALUE self) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> 0ad3bee (nobu 2009-12-30 21:03:51 +0000) return rb_check_typeddata(self, &addrinfo_type); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static rb_addrinfo_t * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) get_addrinfo(VALUE self) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_addrinfo_t *rai = check_addrinfo(self); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!rai) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eTypeError, "uninitialized socket address"); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return rai; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static rb_addrinfo_t * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) alloc_addrinfo() | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_addrinfo_t *rai = ALLOC(rb_addrinfo_t); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) memset(rai, 0, sizeof(rb_addrinfo_t)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rai->inspectname = Qnil; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rai->canonname = Qnil; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return rai; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static void | |
97cbab7 -> 4822d20 (nobu 2010-04-28 08:14:13 +0000) init_addrinfo(rb_addrinfo_t *rai, struct sockaddr *sa, socklen_t len, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int pfamily, int socktype, int protocol, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE canonname, VALUE inspectname) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> e63c5b3 (wanabe 2010-09-23 12:42:49 +0000) if ((socklen_t)sizeof(rai->addr) < len) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eArgError, "sockaddr string too big"); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) memcpy((void *)&rai->addr, (void *)sa, len); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rai->sockaddr_len = len; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rai->pfamily = pfamily; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rai->socktype = socktype; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rai->protocol = protocol; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rai->canonname = canonname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rai->inspectname = inspectname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> bd3cdcf (akr 2009-01-20 11:19:09 +0000) VALUE | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) int family, int socktype, int protocol, | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) VALUE canonname, VALUE inspectname) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE a; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_addrinfo_t *rai; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 88f04bd (akr 2009-02-05 11:01:43 +0000) a = addrinfo_s_allocate(rb_cAddrinfo); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) DATA_PTR(a) = rai = alloc_addrinfo(); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) init_addrinfo(rai, addr, len, family, socktype, protocol, canonname, inspectname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return a; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) static struct rb_addrinfo * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) call_getaddrinfo(VALUE node, VALUE service, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE family, VALUE socktype, VALUE protocol, VALUE flags, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int socktype_hack) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct addrinfo hints; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo *res; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) MEMZERO(&hints, struct addrinfo, 1); | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!NIL_P(socktype)) { | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) hints.ai_socktype = rsock_socktype_arg(socktype); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!NIL_P(protocol)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hints.ai_protocol = NUM2INT(protocol); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!NIL_P(flags)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) hints.ai_flags = NUM2INT(flags); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 -> 172d208 (akr 2009-03-01 06:48:22 +0000) res = rsock_getaddrinfo(node, service, &hints, socktype_hack); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (res == NULL) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eSocket, "host not found"); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return res; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) static VALUE make_inspectname(VALUE node, VALUE service, struct addrinfo *res); | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static void | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) init_addrinfo_getaddrinfo(rb_addrinfo_t *rai, VALUE node, VALUE service, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE family, VALUE socktype, VALUE protocol, VALUE flags, | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) VALUE inspectnode, VALUE inspectservice) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 1); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE canonname; | |
97cbab7 -> 9cd0874 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) VALUE inspectname = rb_str_equal(node, inspectnode) ? Qnil : make_inspectname(inspectnode, inspectservice, res->ai); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) canonname = Qnil; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) if (res->ai->ai_canonname) { | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) canonname = rb_tainted_str_new_cstr(res->ai->ai_canonname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) OBJ_FREEZE(canonname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) init_addrinfo(rai, res->ai->ai_addr, res->ai->ai_addrlen, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) NUM2INT(family), NUM2INT(socktype), NUM2INT(protocol), | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) canonname, inspectname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) rb_freeaddrinfo(res); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static VALUE | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) make_inspectname(VALUE node, VALUE service, struct addrinfo *res) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE inspectname = Qnil; | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) if (res) { | |
97cbab7 -> 9cd0874 -> 5525d82 (akr 2012-02-02 11:51:25 +0000) /* drop redundant information which also shown in address:port part. */ | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) int ret; | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) ret = rb_getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) sizeof(hbuf), pbuf, sizeof(pbuf), | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) NI_NUMERICHOST|NI_NUMERICSERV); | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) if (ret == 0) { | |
97cbab7 -> 9cd0874 -> b0dd250 (nobu 2012-05-23 07:13:21 +0000) if (RB_TYPE_P(node, T_STRING) && strcmp(hbuf, RSTRING_PTR(node)) == 0) | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) node = Qnil; | |
97cbab7 -> 9cd0874 -> b0dd250 (nobu 2012-05-23 07:13:21 +0000) if (RB_TYPE_P(service, T_STRING) && strcmp(pbuf, RSTRING_PTR(service)) == 0) | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) service = Qnil; | |
97cbab7 -> 9cd0874 -> b0dd250 (nobu 2012-05-23 07:13:21 +0000) else if (RB_TYPE_P(service, T_FIXNUM) && atoi(pbuf) == FIX2INT(service)) | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) service = Qnil; | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) } | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) } | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) | |
97cbab7 -> b0dd250 (nobu 2012-05-23 07:13:21 +0000) if (RB_TYPE_P(node, T_STRING)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) inspectname = rb_str_dup(node); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 -> b0dd250 (nobu 2012-05-23 07:13:21 +0000) if (RB_TYPE_P(service, T_STRING)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (NIL_P(inspectname)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) inspectname = rb_sprintf(":%s", StringValueCStr(service)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_str_catf(inspectname, ":%s", StringValueCStr(service)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 -> b0dd250 (nobu 2012-05-23 07:13:21 +0000) else if (RB_TYPE_P(service, T_FIXNUM) && FIX2INT(service) != 0) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (NIL_P(inspectname)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) inspectname = rb_sprintf(":%d", FIX2INT(service)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_str_catf(inspectname, ":%d", FIX2INT(service)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!NIL_P(inspectname)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) OBJ_INFECT(inspectname, node); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) OBJ_INFECT(inspectname, service); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) OBJ_FREEZE(inspectname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return inspectname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static VALUE | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE ret; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE canonname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE inspectname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 9cd0874 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) inspectname = make_inspectname(node, service, res->ai); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) canonname = Qnil; | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) if (res->ai->ai_canonname) { | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) canonname = rb_tainted_str_new_cstr(res->ai->ai_canonname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) OBJ_FREEZE(canonname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> c49f05d -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) ret = rsock_addrinfo_new(res->ai->ai_addr, res->ai->ai_addrlen, | |
97cbab7 -> c49f05d -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) res->ai->ai_family, res->ai->ai_socktype, | |
97cbab7 -> c49f05d -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) res->ai->ai_protocol, | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) canonname, inspectname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) rb_freeaddrinfo(res); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return ret; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static VALUE | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE ret; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct addrinfo *r; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE inspectname; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> 9cd0874 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) inspectname = make_inspectname(node, service, res->ai); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ret = rb_ary_new(); | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) for (r = res->ai; r; r = r->ai_next) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE addr; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE canonname = Qnil; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (r->ai_canonname) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) canonname = rb_tainted_str_new_cstr(r->ai_canonname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) OBJ_FREEZE(canonname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) addr = rsock_addrinfo_new(r->ai_addr, r->ai_addrlen, | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) r->ai_family, r->ai_socktype, r->ai_protocol, | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) canonname, inspectname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_ary_push(ret, addr); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> dd1c3a7 (akr 2014-02-19 09:38:24 +0000) rb_freeaddrinfo(res); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return ret; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifdef HAVE_SYS_UN_H | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static void | |
97cbab7 -> 0314971 (akr 2009-02-08 04:53:17 +0000) init_unix_addrinfo(rb_addrinfo_t *rai, VALUE path, int socktype) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct sockaddr_un un; | |
97cbab7 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) socklen_t len; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) StringValue(path); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> d79dc0f -> 1413510 (akr 2012-04-26 03:34:12 +0000) if (sizeof(un.sun_path) < (size_t)RSTRING_LEN(path)) | |
97cbab7 -> 7c346a4 -> c1d27b8 (akr 2012-04-25 14:05:10 +0000) rb_raise(rb_eArgError, | |
97cbab7 -> 7c346a4 -> c1d27b8 (akr 2012-04-25 14:05:10 +0000) "too long unix socket path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)", | |
97cbab7 -> 7c346a4 -> c1d27b8 -> 1413510 (akr 2012-04-26 03:34:12 +0000) (size_t)RSTRING_LEN(path), sizeof(un.sun_path)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> cb31e78 (akr 2013-02-15 22:19:05 +0000) INIT_SOCKADDR_UN(&un, sizeof(struct sockaddr_un)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) memcpy((void*)&un.sun_path, RSTRING_PTR(path), RSTRING_LEN(path)); | |
97cbab7 -> 977267c (nobu 2010-04-22 08:04:13 +0000) | |
97cbab7 -> 0314971 -> 4822d20 -> ad55d14 -> 07e9f12 (shugo 2013-01-25 23:33:50 +0000) len = rsock_unix_sockaddr_len(path); | |
97cbab7 -> 0314971 -> 4822d20 -> ad55d14 (shugo 2013-01-25 08:15:26 +0000) init_addrinfo(rai, (struct sockaddr *)&un, len, | |
97cbab7 -> 0314971 -> 4822d20 (nobu 2010-04-28 08:14:13 +0000) PF_UNIX, socktype, 0, Qnil, Qnil); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) /* | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * call-seq: | |
97cbab7 -> 88f04bd (akr 2009-02-05 11:01:43 +0000) * Addrinfo.new(sockaddr) => addrinfo | |
97cbab7 -> 88f04bd (akr 2009-02-05 11:01:43 +0000) * Addrinfo.new(sockaddr, family) => addrinfo | |
97cbab7 -> 88f04bd (akr 2009-02-05 11:01:43 +0000) * Addrinfo.new(sockaddr, family, socktype) => addrinfo | |
97cbab7 -> 88f04bd (akr 2009-02-05 11:01:43 +0000) * Addrinfo.new(sockaddr, family, socktype, protocol) => addrinfo | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * | |
97cbab7 -> 88f04bd (akr 2009-02-05 11:01:43 +0000) * returns a new instance of Addrinfo. | |
97cbab7 -> 7f44bad -> 9c4ac94 (akr 2009-11-04 12:02:37 +0000) * The instance contains sockaddr, family, socktype, protocol. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * sockaddr means struct sockaddr which can be used for connect(2), etc. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * family, socktype and protocol are integers which is used for arguments of socket(2). | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * sockaddr is specified as an array or a string. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * The array should be compatible to the value of IPSocket#addr or UNIXSocket#addr. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * The string should be struct sockaddr as generated by | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * Socket.sockaddr_in or Socket.unpack_sockaddr_un. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * sockaddr examples: | |
97cbab7 -> 977267c (nobu 2010-04-22 08:04:13 +0000) * - ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] | |
97cbab7 -> 977267c (nobu 2010-04-22 08:04:13 +0000) * - ["AF_INET6", 42304, "ip6-localhost", "::1"] | |
97cbab7 -> 977267c (nobu 2010-04-22 08:04:13 +0000) * - ["AF_UNIX", "/tmp/sock"] | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * - Socket.sockaddr_in("smtp", "2001:DB8::1") | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * - Socket.sockaddr_in(80, "172.18.22.42") | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * - Socket.sockaddr_in(80, "www.ruby-lang.org") | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * - Socket.sockaddr_un("/tmp/sock") | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * In an AF_INET/AF_INET6 sockaddr array, the 4th element, | |
97cbab7 -> 88f04bd (akr 2009-02-05 11:01:43 +0000) * numeric IP address, is used to construct socket address in the Addrinfo instance. | |
97cbab7 -> 88f04bd -> 7f44bad (akr 2009-02-26 14:18:09 +0000) * If the 3rd element, textual host name, is non-nil, it is also recorded but used only for Addrinfo#inspect. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * family is specified as an integer to specify the protocol family such as Socket::PF_INET. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * It can be a symbol or a string which is the constant name | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * with or without PF_ prefix such as :INET, :INET6, :UNIX, "PF_INET", etc. | |
97cbab7 -> 9c4ac94 (akr 2009-11-04 12:02:37 +0000) * If omitted, PF_UNSPEC is assumed. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * socktype is specified as an integer to specify the socket type such as Socket::SOCK_STREAM. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * It can be a symbol or a string which is the constant name | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * with or without SOCK_ prefix such as :STREAM, :DGRAM, :RAW, "SOCK_STREAM", etc. | |
97cbab7 -> 9c4ac94 (akr 2009-11-04 12:02:37 +0000) * If omitted, 0 is assumed. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * protocol is specified as an integer to specify the protocol such as Socket::IPPROTO_TCP. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * It must be an integer, unlike family and socktype. | |
97cbab7 -> 9c4ac94 (akr 2009-11-04 12:02:37 +0000) * If omitted, 0 is assumed. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * Note that 0 is reasonable value for most protocols, except raw socket. | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) * | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) */ | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static VALUE | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) addrinfo_initialize(int argc, VALUE *argv, VALUE self) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_addrinfo_t *rai; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE sockaddr_arg, sockaddr_ary, pfamily, socktype, protocol; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int i_pfamily, i_socktype, i_protocol; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) struct sockaddr *sockaddr_ptr; | |
97cbab7 -> 4822d20 (nobu 2010-04-28 08:14:13 +0000) socklen_t sockaddr_len; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE canonname = Qnil, inspectname = Qnil; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (check_addrinfo(self)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eTypeError, "already initialized socket address"); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) DATA_PTR(self) = rai = alloc_addrinfo(); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_scan_args(argc, argv, "13", &sockaddr_arg, &pfamily, &socktype, &protocol); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) i_pfamily = NIL_P(pfamily) ? PF_UNSPEC : rsock_family_arg(pfamily); | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) i_socktype = NIL_P(socktype) ? 0 : rsock_socktype_arg(socktype); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) i_protocol = NIL_P(protocol) ? 0 : NUM2INT(protocol); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) sockaddr_ary = rb_check_array_type(sockaddr_arg); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!NIL_P(sockaddr_ary)) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE afamily = rb_ary_entry(sockaddr_ary, 0); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int af; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) StringValue(afamily); | |
97cbab7 -> c49f05d (akr 2009-03-01 06:30:41 +0000) if (rsock_family_to_int(RSTRING_PTR(afamily), RSTRING_LEN(afamily), &af) == -1) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eSocket, "unknown address family: %s", StringValueCStr(afamily)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) switch (af) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) case AF_INET: /* ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] */ | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifdef INET6 | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) case AF_INET6: /* ["AF_INET6", 42304, "ip6-localhost", "::1"] */ | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE service = rb_ary_entry(sockaddr_ary, 1); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE nodename = rb_ary_entry(sockaddr_ary, 2); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE numericnode = rb_ary_entry(sockaddr_ary, 3); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) int flags; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) service = INT2NUM(NUM2INT(service)); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) if (!NIL_P(nodename)) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) StringValue(nodename); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) StringValue(numericnode); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) flags = AI_NUMERICHOST; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifdef AI_NUMERICSERV | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) flags |= AI_NUMERICSERV; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) init_addrinfo_getaddrinfo(rai, numericnode, service, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) INT2NUM(i_pfamily ? i_pfamily : af), INT2NUM(i_socktype), INT2NUM(i_protocol), | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) INT2NUM(flags), | |
97cbab7 -> 9cd0874 (akr 2009-01-17 06:03:42 +0000) nodename, service); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) break; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #ifdef HAVE_SYS_UN_H | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) case AF_UNIX: /* ["AF_UNIX", "/tmp/sock"] */ | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) VALUE path = rb_ary_entry(sockaddr_ary, 1); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) StringValue(path); | |
97cbab7 -> 0314971 (akr 2009-02-08 04:53:17 +0000) init_unix_addrinfo(rai, path, SOCK_STREAM); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) break; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) #endif | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) default: | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_raise(rb_eSocket, "unexpected address family"); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) StringValue(sockaddr_arg); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) sockaddr_ptr = (struct sockaddr *)RSTRING_PTR(sockaddr_arg); | |
97cbab7 -> 4822d20 -> c7135dd (nobu 2013-04-06 07:58:51 +0000) sockaddr_len = RSTRING_SOCKLEN(sockaddr_arg); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) init_addrinfo(rai, sockaddr_ptr, sockaddr_len, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) i_pfamily, i_socktype, i_protocol, | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) canonname, inspectname); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return self; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static int | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) get_afamily(struct sockaddr *addr, socklen_t len) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> 85198c5 (akr 2010-08-19 10:54:56 +0000) if ((socklen_t)((char*)&addr->sa_family + sizeof(addr->sa_family) - (char*)addr) <= len) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return addr->sa_family; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) return AF_UNSPEC; | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static int | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) ai_get_afamily(rb_addrinfo_t *rai) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> c89844d (akr 2013-02-24 17:51:17 +0000) return get_afamily(&rai->addr.addr, rai->sockaddr_len); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) static VALUE | |
97cbab7 -> db88104 (akr 2009-01-18 08:03:24 +0000) inspect_sockaddr(VALUE addrinfo, VALUE ret) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) { | |
97cbab7 -> db88104 (akr 2009-01-18 08:03:24 +0000) rb_addrinfo_t *rai = get_addrinfo(addrinfo); | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) union_sockaddr *sockaddr = &rai->addr; | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) socklen_t socklen = rai->sockaddr_len; | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) return rsock_inspect_sockaddr((struct sockaddr *)sockaddr, socklen, ret); | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) } | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) VALUE | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE ret) | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) { | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) union_sockaddr *sockaddr = (union_sockaddr *)sockaddr_arg; | |
97cbab7 -> b323d7d (akr 2013-05-11 08:32:26 +0000) if (socklen == 0) { | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_str_cat2(ret, "empty-sockaddr"); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) } | |
97cbab7 -> 438b870 -> c89844d -> b323d7d (akr 2013-05-11 08:32:26 +0000) else if ((long)socklen < ((char*)&sockaddr->addr.sa_family + sizeof(sockaddr->addr.sa_family)) - (char*)sockaddr) | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) rb_str_cat2(ret, "too-short-sockaddr"); | |
97cbab7 (akr 2009-01-17 04:11:27 +0000) else { | |
97cbab7 -> c89844d -> b323d7d (akr 2013-05-11 08:32:26 +0000) switch (sockaddr->addr.sa_family) { | |
97cbab7 -> c89844d -> b323d7d (akr 2013-05-11 08:32:26 +0000) case AF_UNSPEC: | |
97cbab7 -> c89844d -> b323d7d (akr 2013-05-11 08:32:26 +0000) { | |
97cbab7 -> c89844d -> b323d7d (akr 2013-05-11 08:32:26 +0000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment