runmdn
概要
runmdnはgethostbyname
などの標準的なリゾルバ関数を用いて名前解決を行う UNIX クライアントを、
再コンパイルなしに多言語ドメイン名を扱えるようにするためのコマンドです。
起動
% runmdn コマンド [引数...]
例えばtelnet
コマンドで多言語ドメイン名を扱うためには、
次のようにします。
% runmdn telnet ログイン.どこかの会社.jp
実装
runmdnは共有ライブラリのプリロード機構を用いて、 標準的な名前解決用の関数を、 多言語ドメイン名の処理機能を持つ別のバージョンのものに動的に置き換えることで、 クライアントでの多言語ドメイン名の処理を実現します。
多くのシステムでは、
共有ライブラリのプリロードは環境変数LD_PRELOAD
を用いて実現されています。
この環境変数にプリロードしたい共有ライブラリファイルのパス名を指定すると、
アプリケーションの実行時にアプリケーションに標準の共有ライブラリがリンクされる前に指定したライブラリがリンクされます。
これによって標準のライブラリ関数を置換えることができます。
runmdnの実体はこの環境変数LD_PRELOAD
を設定して引数で指定されたコマンドを起動するだけのシェルスクリプトであり、
実際に多言語ドメイン名の処理を行うのはアプリケーションにリンクされる共有ライブラリ libmdnresolv
です。
libmdnresolv
をリンクすることにより、
多くのシステムで標準的に用意されている次の名前解決関数が置き換わります。
gethostbyname gethostbyname_r gethostbyname2 gethostbyname2_r gethostbyaddr gethostbyaddr_r getipnodebyname getipnodebyaddr getaddrinfo getnameinfo
またメモリ管理等の都合により、 これらの名前解決関数の置換えにしたがって、 次の関数も置き換わります。
freehostent freeaddrinfo
これらの関数にはオリジナルと比較して次のような機能が追加されています。
- 引数で指定されたドメイン名をローカルコードセットから国際化 DNS で用いられるエンコーディングに変換するとともにNAMEPREP等の正規化を行います。
- DNSから返ってきたドメイン名のエンコーディングをローカルコードセットに変換します。
エンコーディング変換や正規化等の処理はすべてMDNライブラリ (libmdn) のresモジュールを使用しています。
現在の実装ではlibmdnresolv
はMDNライブラリ (libmdn) を呼び出すのではなく、
libmdn自体を内部に抱え込むような形態になっていますが、
これは単なる実装上の都合からそうなっているだけで、
論理的にはMDNライブラリの機能を呼び出しているといってよいでしょう。
また使用するエンコーディングや正規化の設定はmDNkit設定ファイルの設定を利用します。
制限
runmdnにはいくつかの制限があり、 どんなシステムでも使えるわけではありません。
- runmdnは共有ライブラリの動的リンク機構を用いているので、 共有ライブラリが使用できるシステムでなければなりません。
- また環境変数LD_PRELOADまたは類似の機構によるライブラリのプリロード機能を持つシステムでなければなりません。
- runmdnの対象となるコマンドはリゾルバライブラリを動的リンクしていなくてはなりません
- システムのライブラリがiconv()関数を提供していない場合、 外部のライブラリを用いることになりますが、 そのライブラリも共有ライブラリでなければなりません。
- アプリケーションは名前解決に上記の関数を使用していなければなりません。
- セキュリティ上の理由から一般にsetuidされたコマンドはプリロード機能が使えないようになっているので、 setuidされたコマンドであってはなりません。