From: "akira yamada / やまだあきら" Date: 2000-05-09T21:14:37+09:00 Subject: [ruby-dev:9644] Re: host.conf は参照しないの? Tue, 9 May 2000 18:38:43 +0900 頃の Mail-Count: 22420 Subject: [ruby-list:22420] Re: host.conf は参照しないの? についてのお話にて やまだは言いました… (あ == やまだ あきら) In article 22420, <20000509093828.B6D3A4587D@qp.linux.or.jp> あ> 4) しかし, どうせなら(というか UNSPEC なので) あ> IPv4 優先, IPv6 優先, ほんとに UNSPEC(スタック依存?) あ> くらいから選択できるようにしてはどうか あ> あ> というようなことでした. (このやり取りのログはのこっています) あ> そうすることに問題がないのであれば上の 3) のようにするか, あ> できたら 4) のようにしてほしいな, というのが あ> わたしからの(?)提案です. いかがでしょうか? というわけで, あんましよくわかってませんし, やり方についてあんましちゃんと考えたわけではないですし, ちゃんとチェックもしてませんが, とりあえず, 書くだけ書いてみました. 定数がさす配列の中の要素に依存するってのは とても脆いとは自分でも思いますが, やり方として, それ以上のことをするのには もう少しちゃんと考えなきゃならなそうだったので こんなんしてみました(これは言訳ですが, あくまでとりあえずってことで X-). # おまけに単純な切り貼りしかしてませんし… --- ruby-1.4.4.cvs2000050803.orig/ext/socket/socket.c +++ ruby-1.4.4.cvs2000050803/ext/socket/socket.c @@ -64,6 +64,7 @@ VALUE rb_cUNIXServer; #endif VALUE rb_cSocket; +VALUE lookup_order; static VALUE rb_eSocket; @@ -542,10 +543,28 @@ portp = STR2CSTR(port); } +#ifndef INET6 MEMZERO(&hints, struct addrinfo, 1); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; error = getaddrinfo(hostp, portp, &hints, &res); +#else + { + int i, af; + for (i = 0; i < RARRAY(lookup_order)->len; i++) { + af = FIX2INT(RARRAY(lookup_order)->ptr[i]); + MEMZERO(&hints, struct addrinfo, 1); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; + error = getaddrinfo(hostp, portp, &hints, &res); + if (error) { + if (af == PF_UNSPEC) { + break; + } + } + } + } +#endif if (error) { if (hostp && hostp[strlen(hostp)-1] == '\n') { rb_raise(rb_eSocket, "newline at the end of hostname"); @@ -730,6 +749,7 @@ strcpy(pbuf, STR2CSTR(serv)); portp = pbuf; } +#ifndef INET6 MEMZERO(&hints, struct addrinfo, 1); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -737,6 +757,26 @@ hints.ai_flags = AI_PASSIVE; } error = getaddrinfo(host, portp, &hints, &res0); +#else + { + int i, af; + for (i = 0; i < RARRAY(lookup_order)->len; i++) { + af = FIX2INT(RARRAY(lookup_order)->ptr[i]); + MEMZERO(&hints, struct addrinfo, 1); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + if (type == INET_SERVER) { + hints.ai_flags = AI_PASSIVE; + } + error = getaddrinfo(host, portp, &hints, &res0); + if (error) { + if (af == PF_UNSPEC) { + break; + } + } + } + } +#endif if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -1751,6 +1791,7 @@ pptr = pbuf; } +#ifndef INET6 MEMZERO(&hints, struct addrinfo, 1); if (!NIL_P(family)) { hints.ai_family = NUM2INT(family); @@ -1768,6 +1809,36 @@ hints.ai_flags = NUM2INT(flags); } error = getaddrinfo(hptr, pptr, &hints, &res); +#else + { + int i, af; + for (i = 0; i < RARRAY(lookup_order)->len; i++) { + af = FIX2INT(RARRAY(lookup_order)->ptr[i]); + MEMZERO(&hints, struct addrinfo, 1); + if (!NIL_P(family)) { + hints.ai_family = NUM2INT(family); + } + else { + hints.ai_family = af; + } + if (!NIL_P(socktype)) { + hints.ai_socktype = NUM2INT(socktype); + } + if (!NIL_P(protocol)) { + hints.ai_protocol = NUM2INT(protocol); + } + if (!NIL_P(flags)) { + hints.ai_flags = NUM2INT(flags); + } + error = getaddrinfo(hptr, pptr, &hints, &res); + if (error) { + if (!NIL_P(family) || af == PF_UNSPEC) { + break; + } + } + } + } +#endif if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -2036,6 +2107,29 @@ #ifdef PF_INET6 sock_define_const("PF_INET6", PF_INET6); #endif +#ifdef INET6 +# if defined(PF_UNSPEC) && defined(PF_INET6) + lookup_order = + rb_ary_new3(3, +# if DEFAULT_LOOKUP_ORDER == INET + INT2FIX(PF_INET), + INT2FIX(PF_INET6), + INT2FIX(PF_UNSPEC) +# elif DEFAULT_LOOKUP_ORDER == INET6 + INT2FIX(PF_INET6), + INT2FIX(PF_INET), + INT2FIX(PF_UNSPEC) +# elif DEFAULT_LOOKUP_ORDER == UNSPEC + INT2FIX(PF_UNSPEC), + INT2FIX(PF_UNSPEC), + INT2FIX(PF_UNSPEC) +# endif + ); +# endif +#else + lookup_order = Qnil; +#endif + rb_define_const(rb_cSocket, "LOOKUP_ORDER", lookup_order); sock_define_const("MSG_OOB", MSG_OOB); #ifdef MSG_PEEK --- ruby-1.4.4.cvs2000050803.orig/ext/socket/extconf.rb +++ ruby-1.4.4.cvs2000050803/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 <