名前解決についてのまとまりのない話
ソケットプログラミングをやっていると、いつもうっとうしく感じるのが getaddrinfo() である。getaddrinfo() は、名前解決の際に使う API である。なにがうっとうしいかというと、これは完全なブロッキング API なので、どれだけ非ブロッキングなコードを書いてもここだけがブロッキングなコードになってしまうのだ。
c-ares *1 はこういった悩みを解消してくれる良き友である。
- c-ares: library for asynchronous name resolves
c-ares は現在も活発に開発が行われていて、つい先日の 2010/06/10 にもリリースされている。リリースノートには以下のような記載がある。
c-ares version 1.7.3
Fixed:
o builds on Android
o now includes all files necessary to build it (1.7.2 lacked a file)Thanks go to these friendly people for their efforts and contributions:
Yang Tse, Bogdan Vatra
Have fun!
1.7.3 で Android にも対応したらしい。Android は NDK が使えるので、こういった C の資産がかなり使えるのが素晴らしい。
それにしても、メーリングリストに投稿されたパッチを取り込むのが早すぎる。どうやって確認しているのかが少し気になるほどだ。c-ares の Android 対応は、メーリングリストに投稿されたパッチを Daniel Stenberg 氏がその日のうちに取り込んでリリースしている。
投稿されたパッチの内容を見る限りでは、ANDROID というプリプロセッサが定義されていれば、適当にメイクファイルを作ってやってビルドできそうである。他にも何かやるべきことがあるかどうかを確認するため、Snow Leopard で configure して Makefile を見てみたら、CFLAGS は以下のようなものだけだった。
CFLAGS = -g0 -O2 -Wno-system-headers -fvisibility=hidden
普通にいけそうなので、後で試してみよう。
それはさておき、名前解決である。
c-ares を使うなり、UDP ソケットを使って DNS クエリを投げるなりすれば、非ブロッキングにできる。ここで面倒なのが、hosts ファイルである。getaddrinfo() は hosts ファイルの内容を優先して名前解決を行うようだが、DNS クエリだけを扱っている場合、hosts ファイルの内容は加味されない。ちなみに、c-ares はちゃんと加味してくれるようである。PATH_HOSTS というのが定義されていて、それを読みにいくようになっている。ares_gethostbyaddr.c にある file_lookup() というのがそれをやってくれる。
・・・しかし、Android 対応とあるが、hosts ファイルのパスをちゃんと定義していないようだ。Android の hosts ファイルのパスは、自分が知る限りでは、/system/etc/hosts である。メーリングリストに投稿してみようかな。
実際に各 OS の getaddrinfo() が何をやっているかを確かめたわけではないが、Wine や Linux のコードを追えばもう少し詳しく分かりそうだ。まぁしかし、c-ares を使えば名前解決に関する私の欲求はほぼ満たされそうである。
*1:c-ares は、HTTP でよく使う libcurl と仲がいいライブラリでもある。