From: "akira yamada / やまだあきら" Date: 2000-05-14T12:44:46+09:00 Subject: [ruby-dev:9677] Re: host.conf は参照しないの? Sat, 13 May 2000 13:05:22 +0900 頃の Mail-Count: 9670 Subject: [ruby-dev:9670] Re: host.conf は参照しないの? についてのお話にて Yukihiro Matsumoto さん曰く… (Y == matz@netlab.co.jp (Yukihiro Matsumoto) さん) |というわけで… あの patch ではやっぱりダメでしょうか? In article 9670, Y> 基本的には採用したいんですが、動的な切替えの辺りで迷いがある Y> んです。インタフェースって一度決めるとなかなか変えられません Y> から。 迷いがあるというのは 「動的に切り替えることをする必要があるかどうか?」という点ですか? それだとダメですが Y> そういえば、do_not_reverse_lookup なんて属性もあるし。 に準ずるということなら, いろいろきりはりしただけですが, こんなんでどうでしょうか? P.S. extconf.rb の方の「@@ -99,6 +99,10 @@」の部分ですが, よくわからないんですが Linux で glibc2 な環境(?)だと, こうでもしないと INET6 が define されないような気がするんですが, それはそれでよいのでしょうか? --- ruby-1.4.4.cvs2000051209.orig/ext/socket/socket.c +++ ruby-1.4.4.cvs2000051209/ext/socket/socket.c @@ -104,6 +104,52 @@ }; #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 +static int lookup_order = LOOKUP_ORDER_INET; +#elif DEFAULT_LOOKUP_ORDER == INET6 +static int lookup_order = LOOKUP_ORDER_INET6; +#elif DEFAULT_LOOKUP_ORDER == UNSPEC +static int lookup_order = 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; + + 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) @@ -456,6 +502,35 @@ return val; } +static VALUE +bsock_lookup_order() +{ +#ifndef INET6 + return Qnil; +#else + return INT2FIX(lookup_order); +#endif +} + +static VALUE +bsock_lookup_order_set(self, val) +{ +#ifndef INET6 + return Qnil; +#else + int lo; + + FIXNUM_P(val); + lo = FIX2INT(val); + if (lo < 0 || LOOKUP_ORDERS <= lo) { + rb_raise(rb_eRuntimeError, "invalid value for lookup_order"); + } + + lookup_order = lo; + return val; +#endif +} + static void mkipaddr0(addr, buf, len) struct sockaddr *addr; @@ -545,7 +620,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 +815,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 +1838,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 +1852,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)); } @@ -1903,6 +1997,11 @@ rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup=", bsock_do_not_rev_lookup_set, 1); + rb_define_singleton_method(rb_cBasicSocket, "lookup_order", + bsock_lookup_order, 0); + rb_define_singleton_method(rb_cBasicSocket, "lookup_order=", + bsock_lookup_order_set, 1); + rb_define_method(rb_cBasicSocket, "close_read", bsock_close_read, 0); rb_define_method(rb_cBasicSocket, "close_write", bsock_close_write, 0); rb_define_method(rb_cBasicSocket, "shutdown", bsock_shutdown, -1); @@ -2035,6 +2134,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); --- ruby-1.4.4.cvs2000051209.orig/ext/socket/extconf.rb +++ ruby-1.4.4.cvs2000051209/ext/socket/extconf.rb @@ -99,6 +99,10 @@ $ipv6lib="inet6" $ipv6libdir="/usr/local/v6/lib" $CFLAGS="-DINET6 "+$CFLAGS + else + $ipv6lib=with_config("ipv6-lib", nil) + $ipv6libdir=with_config("ipv6-libdir", nil) + $CFLAGS="-DINET6 "+$CFLAGS end if $ipv6lib @@ -273,6 +277,20 @@ exit end +case with_config("ipv6-lookup-order", "INET") +when "INET" + $CFLAGS="-DDEFAULT_LOOKUP_ORDER=INET "+$CFLAGS +when "INET6" + $CFLAGS="-DDEFAULT_LOOKUP_ORDER=INET6 "+$CFLAGS +when "UNSPEC" + $CFLAGS="-DDEFAULT_LOOKUP_ORDER=UNSPEC "+$CFLAGS +else + print < (akira@arika.org, akira@ruby-lang.org or akira@ad-hoc.org)