«前の日記(2004-01-20) 最新 次の日記(2004-01-22)» 編集

Matzにっき

迷惑メール対策なら Dr.WEB
『Dr.WEB メールデーモン』、MTA 用迷惑メール対策製品です!


2004-01-21 [長年日記]

_ [Ruby]getaddrinfo(その4)

「通常のホスト名からも数値的なホスト名からも、区別なくホスト情報(hostent)を得たい」というのはちょっと変ですか。 もともとIPv6 safeで通常のホスト名からも数値的なホスト名も区別しないgethostbyname(3)が欲しいだけなんですが、 それってそんなに変な要求なのでしょうか。

念のためですが、欲しいのはhostentであって、かならずしも逆引きして欲しいわけではないです。 よって、ゆうぞうさんのパッチは やりすぎのような気がします。

問題にしているのはman getaddrinfo(3)に

The nodename and servname arguments are pointers to null-terminated strings or NULL. One or both of these two arguments must be a non-NULL pointer.

とあり、

If the AI_CANONNAME bit is set in the ai_flags member of the hints struc- ture, then upon successful return the ai_canonname member of the first addrinfo structure in the linked list will point to a null-terminated string containing the canonical name of the specified nodename.

としか書いてないのにai_canonnameがNULLというのはどういうことか、使いにくいじゃないか、という点だけです。 しかもservnameを指定するとちゃんと逆引きしてai_canonnameを与えてくれるのに。 RFCを読めばちゃんと書いてあるのかしら。

_ [Ruby]getaddrinfo(その5)

servnameを指定するとちゃんと逆引きして」というのは勘違いでした。 RubyのSocket#getaddrinfoメソッドは確かにそうなんですけど、 内部でgetnameinfoを呼んで明示的に逆引きしてました。

で、結論としては

if the canonical name is not available, then ai_canonname shall refer to the nodename argument or a string with the same contents.

ということであれば、τ森さんや曽田さんのおっしゃる通り 「getaddrinfo(3) が成功して、かつ ai_canonname がNULLなら元の文字列(のコピー)を使う」 という線で行こうと思います。

情報提供してくださった皆さん、どうもありがとうございました。

本日のツッコミ(全1件) [ツッコミを入れる]
_ soda (2004-01-21 19:00)

「しかもservnameを指定するとちゃんと逆引きして ai_canonnameを<br>与えてくれる」というのは確かでしょうか?<br>少なくとも NetBSD では、たとえ AI_CANONNAME と servname を<br>指定しても、nodename が IPv4 の数値的なホスト名だと、<br>ai_canonname は NULL のままです。たぶん FreeBSD でも同じだと<br>思うんですが…<br><br>それから、「かならずしも逆引きして欲しいわけではない」という<br>ところにひょっとすると誤解がありそうな気がするんですが、<br>gethostbyname(3) は、決して逆引きをしないと思います。<br>最新の BSD 系の getaddrinfo(3) も、この常識を引き継いでいて、<br>逆引きは行わないと理解しています。ただし、古いバージョンでは、<br>実は逆引きを行っていました。KAME のリポジトリ<br>http://orange.kame.net/dev/cvsweb.cgi/kame/kame/kame/libinet6/getaddrinfo.c?cvsroot=kame<br>の revision 1.42 で、逆引きを行わないように訂正されており、<br>BSD 系 OS が利用しているのも、この実装です。<br>従って、getaddrinfo(3) が ai_canonname に返すのは、逆引き<br>した名前ではなく、正引きを行った際に用いた FQDN です。<br>しかし、glibc で AI_CANONNAME を指定すると、KAME の昔の実装の<br>ように逆引きを行い、その結果を ai_canonname に返すようです。<br>この意味で、従来の gethostbyname(3) 的な常識は、Linux の<br>getaddrinfo(3) には通用しません。<br><br>で、実は前回の私のコメントに誤りがありました。<br>前回「Solaris のやっているような数値アドレス文字列をそのまま<br>ai_canonname に返すやり方は、この点で問題がある」と書きました<br>が、最新の仕様である RFC3493 や SUSv3 では、この Solaris の<br>挙動にすべきであると、明示的に書かれていました:<br>if the canonical name is not available, then ai_canonname<br>shall refer to the nodename argument or a string with<br>the same contents. <br>「shall」ですから、「must」や「required」と同義であり必須を<br>意味すると思います。(この記述は、旧版の RFC2553 にはありま<br>せんでした)<br><br>この Solaris が行っているような処理は、BSD 系 getaddrinfo(3) <br>のソースコードに も含まれてはいるんですが、IPv4 の場合には<br>#if 0 で明示的に disable されています (→ KAME の revision 1.158)。<br>ただし IPv6 の場合には enableされています (→ KAME の revision<br>1.105)。この disable は意図的なものだと思うのですが、理由は<br>私には分かりません。itojun さんなど、KAME 関係者に聞くのが<br>早道ではないかと思います。<br><br>で、実際にどうすれば良いかという話に戻ると、上述のように、<br>実装内容に揺れがあるがあるわけですから、移植性を考えると、<br>RFC3493 の仕様に従ってない実装を無視するわけにはいかないと<br>思います。結局、τ森さんの書かれた通り、getaddrinfo(3) が<br>成功して、かつ ai_canonname がNULLなら元の文字列(のコピー)を<br>使うというのが、SUSv3 と等価な結果を得られる、最も現実的な<br>解ではないでしょうか。

お名前:
E-mail:
コメント:
[]

«前の日記(2004-01-20) 最新 次の日記(2004-01-22)» 編集

RSS feed meter for http://www.rubyist.net/~matz/ track feed Matzにっき Creative Commons License This work is licensed under a Creative Commons License.