runmdn specification

# runmdn

## 概要

runmdn は BIND-4 あるいは BIND-8 をベースとした リゾルバライブラリを持つクライアントを、 再コンパイルなしに多言語ドメイン名を扱えるようにするためのコマンドです。

## 起動

>     % runmdn コマンド [引数...]

例えば `telnet` コマンドで多言語ドメイン名を扱うためには 次のようにします。

>     % runmdn telnet ログイン.どこかの会社.jp

## 実装

runmdn は共有ライブラリのプリロード機構を用いて、標準の リゾルバライブラリに含まれる関数の一部を、多言語ドメイン名の処理機能を持つ 別のバージョンに動的に置換えることで、クライアントでの多言語ドメイン名の 処理を実現します。

多くのシステムでは共有ライブラリのプリロードは環境変数 LD_PRELOAD を用いて実現されています。この環境変数にプリロードしたい 共有ライブラリファイルのパス名を指定すると、クライアントの実行時に、 アプリケーションに標準の共有ライブラリがリンクされる前に 指定したライブラリがリンクされます。これによって標準のライブラリ関数を 置換えることができます。

したがって、runmdn の実体は、この環境変数を設定し、引数で 指定されたコマンドを起動するだけのシェルスクリプトであり、実際に 多言語ドメイン名の処理を行うのはアプリケーションにリンクされる 共有ライブラリ libmdnresolv です。

libmdnresolv をリンクすることにより、BIND4 あるいは BIND8 ベースの リゾルバライブラリで用いられている次の関数が置き換わります。

>     dn_comp
>     dn_expand
>     res_hnok
>     res_ownok
>     res_mailok
>     res_dnok

それぞれの変更点を簡単に記述します。

dn_comp
  指定されたドメイン名を DNS プロトコルで用いられるドメインデータに変換する前に、 ローカルコードセットから DNS プロトコル上で用いられるエンコーディングへの 変換および正規化、(必要ならば) ZLDの付加を行います。
dn_expand
  DNS プロトコルで用いられるドメインデータをドメイン名文字列に変換した後、 (必要なら) ZLD を削除し、ローカルコードセットへの変換を行います。 また通常この関数はドメイン名に含まれる ASCII 以外の文字を バックスラッシュエスケープする処理をしますが、これを抑制します。
res_hnok
  どんな文字でも正当な文字であると判断するようにします。
res_ownok
  どんな文字でも正当な文字であると判断するようにします。
res_mailok
  どんな文字でも正当な文字であると判断するようにします。
res_dnok
  どんな文字でも正当な文字であると判断するようにします。

エンコーディング変換や正規化、ZLD の処理等はすべて MDN ライブラリ (libmdn) の res モジュールを使用しています。

> 現在の実装では libmdnresolv は MDN ライブラリ (libmdn) を 呼び出すのではなく、libmdn 自体を内部に抱え込むような形態になっていますが、 これは単なる実装上の都合からそうなっているだけで、論理的には MDN ライブラリの機能を呼び出しているといってよいでしょう。

また使用するエンコーディングや正規化の設定は クライアント設定ファイルの設定を 利用します。

## 制限

runmdn にはいくつかの制限があり、どんなシステムでも使えるわけでは ありません。

- runmdn は共有ライブラリの動的リンク機構を用いているので、 共有ライブラリが使用できるシステムでなければなりません。
- また環境変数 LD_PRELOAD または類似の機構による ライブラリのプリロード機能を持つシステムでなければなりません。
- runmdn の対象となるコマンドはリゾルバライブラリをスタティックリンク していてはなりません。
- システムのライブラリが iconv() 関数を提供していない場合、外部の ライブラリを用いることになりますが、そのライブラリも共有ライブラリで なければなりません。
- システムのリゾルバライブラリは BIND4 あるいは BIND8 ベースのものでなければ なりません。
- セキュリティ上の理由から一般に setuid されたコマンドはプリロード機能が 使えないようになっているので、setuid されたコマンドであってはなりません。