Skip to content

Instantly share code, notes, and snippets.

@shyouhei
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shyouhei/9134269 to your computer and use it in GitHub Desktop.
Save shyouhei/9134269 to your computer and use it in GitHub Desktop.
git-strata
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