From: "akira yamada / やまだあきら" Date: 2000-05-10T12:32:35+09:00 Subject: [ruby-dev:9648] Re: host.conf は参照しないの? Wed, 10 May 2000 02:06:22 +0900 頃の Mail-Count: 9646 Subject: [ruby-dev:9646] Re: host.conf は参照しないの? についてのお話にて Yukihiro Matsumoto さん曰く… (Y == matz@netlab.co.jp (Yukihiro Matsumoto) さん) In article 9646, Y> [ruby-dev:9644]の配列 Y> を使う方法はちょっと脆弱な気がします。コンパイル時に指定でき Y> ればそれで良いというようなものなのでしょうか。それともやっぱ Y> り動的に指定できないと駄目? extconf に with_config("ipv6-lookup-order","INET") を追加した上で, たとえばこんなんだとどうですかね? diff -rU3 /home/akira/src/ruby-cvs/ruby_1_4/ext/socket/socket.c ./socket.c --- /src/ruby-cvs/ruby_1_4/ext/socket/socket.c Mon May 8 06:55:27 2000 +++ ./socket.c Wed May 10 12:27:10 2000 @@ -104,6 +104,78 @@ }; #endif +#ifdef INET6 +#define LOOKUP_ORDERS 3 +int lookup_order_table[LOOKUP_ORDERS][LOOKUP_ORDERS] = { +#define LOOKUP_ORDER_INET 0 + {PF_UNSPEC, PF_UNSPEC, PF_UNSPEC}, /* 0:unspec */ +#define LOOKUP_ORDER_INET6 1 + {PF_INET, PF_INET6, PF_UNSPEC}, /* 1:inet inet6 */ +#define LOOKUP_ORDER_UNSPEC 2 + {PF_INET6, PF_INET, PF_UNSPEC} /* 2:inet6 inet */ +}; +#if DEFAULT_LOOKUP_ORDER == INET +# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_INET +#elif DEFAULT_LOOKUP_ORDER == INET6 +# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_INET6 +#elif DEFAULT_LOOKUP_ORDER == UNSPEC +# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_UNSPEC +#endif +static int +rb_getaddrinfo(nodename, servname, hints, res) + char *nodename; + char *servname; + struct addrinfo *hints; + struct addrinfo **res; +{ + + struct addrinfo tmp_hints; + int i, af, error; + VALUE lookup_order; + ID lookup_order_id; + + lookup_order_id = rb_intern("LOOKUP_ORDER"); +#if 0 + if (rb_const_defined(rb_cSocket, lookup_order_id)) { + lookup_order = rb_const_get(rb_cSocket, lookup_order_id); + } +#endif + if (rb_const_defined(rb_cObject, lookup_order_id)) { + lookup_order = rb_const_get(rb_cObject, lookup_order_id); + } + else { + lookup_order = LOOKUP_ORDER_DEFAULT; + } + + if (TYPE(lookup_order) != T_FIXNUM) { + rb_raise(rb_eRuntimeError, + "invalid value of type for LOOKUP_ORDER (expected Fixnum)"); + } + lookup_order = FIX2INT(lookup_order); + + if (lookup_order < 0 || LOOKUP_ORDERS <= lookup_order) { + rb_raise(rb_eRuntimeError, "invalid value for LOOKUP_ORDER"); + } + + for (i = 0; i < LOOKUP_ORDERS; i++) { + af = lookup_order_table[lookup_order][i]; + MEMCPY(&tmp_hints, hints, struct addrinfo, 1); + tmp_hints.ai_family = af; + error = getaddrinfo(nodename, servname, &tmp_hints, res); + if (error) { + if (tmp_hints.ai_family == PF_UNSPEC) { + break; + } + } + else { + break; + } + } + + return error; +} +#endif + #ifdef NT static void sock_finalize(fptr) @@ -545,7 +617,11 @@ MEMZERO(&hints, struct addrinfo, 1); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; +#ifndef INET6 error = getaddrinfo(hostp, portp, &hints, &res); +#else + error = rb_getaddrinfo(hostp, portp, &hints, &res); +#endif if (error) { if (hostp && hostp[strlen(hostp)-1] == '\n') { rb_raise(rb_eSocket, "newline at the end of hostname"); @@ -736,7 +812,11 @@ if (type == INET_SERVER) { hints.ai_flags = AI_PASSIVE; } +#ifndef INET6 error = getaddrinfo(host, portp, &hints, &res0); +#else + error = rb_getaddrinfo(host, portp, &hints, &res0); +#endif if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -1755,9 +1835,11 @@ if (!NIL_P(family)) { hints.ai_family = NUM2INT(family); } +#ifndef INET6 else { hints.ai_family = PF_UNSPEC; } +#endif if (!NIL_P(socktype)) { hints.ai_socktype = NUM2INT(socktype); } @@ -1767,7 +1849,16 @@ if (!NIL_P(flags)) { hints.ai_flags = NUM2INT(flags); } +#ifndef INET6 error = getaddrinfo(hptr, pptr, &hints, &res); +#else + if (!NIL_P(family)) { + error = getaddrinfo(hptr, pptr, &hints, &res); + } + else { + error = rb_getaddrinfo(hptr, pptr, &hints, &res); + } +#endif if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -2035,6 +2126,11 @@ #endif #ifdef PF_INET6 sock_define_const("PF_INET6", PF_INET6); +#endif +#ifdef INET6 + sock_define_const("LOOKUP_INET", LOOKUP_ORDER_INET); + sock_define_const("LOOKUP_INET6", LOOKUP_ORDER_INET6); + sock_define_const("LOOKUP_UNSPEC", LOOKUP_ORDER_UNSPEC); #endif sock_define_const("MSG_OOB", MSG_OOB); ただ, これをするなら, ホントは, Socket::LOOKUP_ORDER とかでなんとかしたいとこなんでしょうが, うまい方法がわかんなかったです. # バランス悪いような…