BINDパッチの仕様書
概要
idnkit では BIND 8 および 9 用のパッチファイルを提供しています。 このパッチを適用することにより、 BIND に含まれる dig, nslookup host コマンドで国際化ドメイン名を扱うこと が可能になります。
いずれのパッチも、国際化ドメイン名のエンコードやデコードの処理はすべて idnkit ライブラリ (libidnkit) の高レベル API (api モジュール) を使用しています。 したがって、BIND をコンパイルする際に、dig, nslookup host コマンドには libidnkit および必要に応じて iconv ライブラリをリンクさせる必要が あります。
BIND 8 パッチの詳細
BIND 8 パッチが元の BIND 8 に対して行う改変の具体的な内容、および改変する ファイルの名前、新規に作成するファイルの名前について説明します。
国際化ドメイン名のエンコード、デコード
ユーザが入力した国際化ドメイン名を ローカルエンコーディングから IDN エンコーディングへとエンコードしてから DNS サーバに問い合わせる ようにし、逆に DNS サーバからの応答に含まれていた国際化ドメイン名を、 IDN エンコーディングからローカルエンコーディングへとデコードしてから 問い合わせ結果として出力するようにしました。
また、こうした国際化ドメイン名のエンコード、デコードは、コンパイル時に
CPP マクロ WITH_IDN
が定義されていたときのみ有効になるよう
にしてあります。
WITH_IDN
が定義されていなければ、パッチを適用する前のコード
がコンパイルされるようになっています。
変更を施したファイルは、次の通りです。
-
src/lib/resolv/res_debug.c
-
resolv ライブラリの中の、デバッグ出力を行う部分のソースコードです。 DNS サーバからの応答データをデバッグ出力する際に、データ中の 国際化ドメイン名をデコードしてから出力するように変更しました。
ただし、resolv ライブラリは dig, nslookup, host 以外のアプリケーション もリンクするため、libidnkit のデコード関数は直接呼ばずに、アプリケーション が登録したデコード関数を呼び出すようにしました。そして、アプリケーション が登録したデコード関数から、libidnkit のデコード関数を呼び出すようにして います。 こうしないと、resolv ライブラリを利用するすべてのアプリケーションが、 libidnkit も一緒にリンクしなければならなくなるためです。
これに伴い、アプリケーションがデコード関数を登録するために呼び出す関数
res_setidndecoder()
も追加作成しました。デコード関数は 初期状態では登録されておらず、未登録時はデコードは行わないようになって います。 -
src/include/idnresolv.h
-
(パッチを適用すると)新規に作成されるファイルです。
src/lib/resolv/res_debug.c
で追加登録した関数res_setidndecoder()
の関数宣言だけが記されたヘッダファイル です。 このファイルは make install を行ってもインストールされません。 -
src/lib/nameser/ns_print.c
-
nameser ライブラリの中の、リソースレコードのデータをテキスト化して 出力する部分のソースコードです。国際化ドメイン名が含まれていた場合は、 デコードを行うように変更しました。
src/lib/resolv/res_debug.c
と同様に、libidnkit のデコード関数 は直接呼ばずに、アプリケーションが登録したデコード関数を呼び出すようにして います。このため、アプリケーションがデコード関数を登録するために呼び出す関数
res_setidndecoder()
も追加作成しました。デコード関数は 初期状態では登録されておらず、未登録時はデコードは行わないようになって います。 -
src/include/arpa/idnnameser.h
-
(パッチを適用すると)新規に作成されるファイルです。
src/lib/nameser/ns_print.c
で追加登録した関数ns_setidndecoder()
の関数宣言だけが記されたヘッダファイル です。 このファイルは make install を行ってもインストールされません。 -
src/bin/dig/dig.c
-
dig コマンドのソースコードです。 国際化ドメイン名のエンコード、デコードを行うようにしました。 ただし、エンコードの対象となるのは、コマンド行引数中のホスト名の 部分に限られます。(他の引数、たとえば「@ネームサーバ名」の部分など に国際化ドメイン名を記述してもエンコードされません。)
また、本パッチを適用するしないにかかわらず、
+domain=XXX
オプションは正しく動作しません。したがって、この部分には国際化ドメイン名 だけでなく、従来の ASCII ドメイン名も指定できません。上記に加えて、このファイでは libidnkit の初期化を行い、
ns_setidndecoder()
、res_setidndecoder()
を 呼んで前述のデコード関数を登録するように変更しました。 そのために、登録用のデコード関数idn_decode()
を追加作成 しています。 -
src/bin/host/host.c
-
host コマンドのソースコードです。 国際化ドメイン名のエンコード、デコードを行うようにしました。 dig 同様、エンコードの対象となるのは、コマンド行引数中のホスト名の 部分に限られ、ネームサーバ名の部分はエンコードされません。
さらに dig と同様に、libidnkit の初期化を行い、
ns_setidndecoder()
、res_setidndecoder()
を 呼んでデコード関数を登録するように変更しました。 そのために、登録用のデコード関数idn_decode()
を追加作成 しています。 -
src/bin/nslookup/debug.c
src/bin/nslookup/main.c
src/bin/nslookup/subr.c
-
nslookup コマンドのソースコードです。 国際化ドメイン名のエンコード、デコードを行うようにしました。 エンコードの対象となるのは、コマンド行およびプロンプトから入力された ホスト名およびデフォルトドメイン名 (コマンド行では
-domain=XXX
、 プロンプトではset domain=XXX
として設定) の部分に限られます。 ネームサーバ名やサーチリストの部分はエンコードされません。nslookup も dig, host と同様に、libidnkit の初期化を行い、
ns_setidndecoder()
、res_setidndecoder()
を 呼んでデコード関数を登録するようにしました。 そのために、登録用のデコード関数idn_decode()
を追加作成 しています。
8 ビットデータの透過処理
BIND 8 パッチでは、国際化ドメイン名のエンコード、デコード機能に加え、 8 ビットデータを透過処理 (8bits through) するための修正が施されています。
idnkit では国際化ドメイン名のエンコード方式として ACE を使うことを 前提としていますので、本来なら 8 ビットデータの透過処理は不要ですが、 idnkit の前身である mDNkit の頃の BIND 8 パッチでこの機能を提供していた ことから、そのまま残してあります。 (BIND 9 は最初から 8 ビットデータ対応になっていますので、BIND 9 パッチ ではこの機能を提供していません。)
変更を施したファイルは、次の通りです。
-
src/bin/addr/addr.c
src/bin/dig/dig.c
src/bin/dnskeygen/dnskeygen.c
src/bin/irpd/irpd.c
src/bin/named/db_defs.h
src/bin/named/db_glue.c
src/bin/named/db_ixfr.c
src/bin/named/db_load.c
src/bin/named/ns_config.c
src/bin/named/ns_init.c
src/bin/named/ns_lexer.c
src/bin/named/ns_main.c
src/bin/named/ns_parseutil.c
src/bin/named/ns_update.c
src/bin/named-xfer/named-xfer.c
src/bin/ndc/ndc.c
src/bin/nslookup/commands.l
src/bin/nslookup/main.c
src/bin/nslookup/subr.c
src/bin/nsupdate/nsupdate.c
src/lib/bsd/mktemp.c
src/lib/bsd/strtoul.c
src/lib/dst/dst_api.c
src/lib/inet/inet_addr.c
src/lib/inet/inet_cidr_pton.c
src/lib/inet/inet_net_pton.c
src/lib/inet/inet_network.c
src/lib/inet/nsap_addr.c
src/lib/irs/dns_nw.c
src/lib/irs/dns_sv.c
src/lib/irs/getnetent.c
src/lib/irs/irpmarshall.c
src/lib/isc/base64.c
src/lib/isc/ctl_clnt.c
src/lib/isc/ctl_srvr.c
src/lib/nameser/ns_name.c
src/lib/nameser/ns_ttl.c
src/lib/resolv/res_comp.c
src/lib/resolv/res_init.c
src/lib/resolv/res_query.c
- いずれも、
char
型のデータの操作に対して、必要に 応じてunsigned char
型への変換を行うように変更しました。
src/idnconfig.sh の作成
前述の通り、パッチを適用した BIND 8 では、コンパイル時に idnkit の インストール位置等の情報をコンパイラに指定してやる必要がありますが、 このときの指定を簡便に行えるようにするためのスクリプトです。 このファイルは新規に作成しました。
make all
を行う前に、ユーザにこのスクリプトを実行して
もらうようになっています。利用方法について詳しくは、本パッチを適用
すると作成される src/README.idnkit
というファイルを
ご覧ください。
このスクリプトを実行すると、make 変数 IDNCPPFLAGS
と
IDNLIBS
の値を src/.idnsettings
というファイル
に書き込みます。
IDNCPPFLAGS
には、C コンパイラに idnkit のヘッダファイルの
インストール位置を教えるオプションと CPP マクロ WITH_IDN
を
定義するオプション (-DWITH_IDN
) がセットされます。
ただし、BIND 8 を国際化ドメイン名に対応させずにコンパイルする際
(--with-idn=no
ないし --without-idn
が指定された
際) は、WITH_IDN
は定義しません。
IDNLIBS
には、C コンパイラが dig, nslookup, host コマンドを
生成する際に、libidnkit および iconv ライブラリをリンクするよう指示する
オプションがセットされます。
以下は、src/idnconfig.sh
が生成した
src/.idnsettings
の例です。
'IDNCPPFLAGS= -DWITH_IDN -I/usr/local/include' 'IDNLIBS=-L/usr/local/lib -R/usr/local/lib -lidnkit -L/usr/local/lib \ -R/usr/local/lib -liconv'
src/README.idnkit の作成
src/idnconfig.sh
スクリプトの使用方法について英語で記述した
ファイルです。このファイルは新規に作成しました。
Makefile
への変更
変更を施したファイルは、次の通りです。
-
src/Makefile
src/bin/Makefile
src/lib/Makefile
- サブディレクトリの
Makefile
を実行する際に、src/idnconfig.sh
が書き込んだIDNCPPFLAGS
,IDNLIBS
の値が伝播するように変更しました。 -
src/bin/dig/Makefile
src/bin/host/Makefile
src/bin/nslookup/Makefile
src/lib/nameser/Makefile
src/lib/resolv/Makefile
- dig, nslookup, host のオブジェクトファイルを生成するときに、
コンパイラに対して
IDNCPPFLAGS
に記されたオプション列を 指定し、同様にリンク時にIDNLIBS
を指定するようにしました。
BIND 9 パッチの詳細
BIND 9 パッチが元の BIND 9 に対して行う改変の具体的な内容、および改変する ファイルの名前、新規に作成するファイルの名前について説明します。
国際化ドメイン名のエンコード、デコード
ユーザが入力した国際化ドメイン名を ローカルエンコーディングから IDN エンコーディングへとエンコードしてから DNS サーバに問い合わせる ようにし、逆に DNS サーバからの応答に含まれていた国際化ドメイン名を、 IDN エンコーディングからローカルエンコーディングへとデコードしてから 問い合わせ結果として出力するようにしました。
また、こうした国際化ドメイン名のエンコード、デコードは、コンパイル時に
CPP マクロ WITH_IDN
が定義されていたときのみ有効になるよう
にしてあります。
WITH_IDN
が定義されていなければ、パッチを適用する前のコード
がコンパイルされるようになっています。
変更を施したファイルは、次の通りです。
-
lib/dns/name.c
-
dns ライブラリの中の、ドメイン名をテキストに変換する関数
dns_name_totext()
に改造を施し、与えられたドメイン名が 国際化ドメイン名であった場合は、デコードを行うようにしました。ただし、dns ライブラリは dig, nslookup, host 以外のアプリケーション もリンクするため、libidnkit のデコード関数は直接呼ばずに、アプリケーション が登録したデコード関数を呼び出すようにしました。そして、アプリケーション が登録したデコード関数から、libidnkit のデコード関数を呼び出すようにして います。 こうしないと、dns ライブラリを利用するすべてのアプリケーションが、 libidnkit も一緒にリンクしなければならなくなるためです。
これに伴い、アプリケーションがデコード関数を登録するために呼び出す関数
dns_name_settotextfilter()
を追加作成しました。デコード関数は 初期状態では登録されておらず、未登録時はデコードは行わないようになって います。 -
lib/dns/include/dns/name.h
-
lib/dns/name.c
に追加登録したdns_name_settotextfilter()
の関数宣言を追加しました。 -
bin/dig/dighost.c
-
dig, nslookup, host コマンド共通のソースコードです。 国際化ドメイン名のエンコード、デコードを行うようにしました。 エンコードの対象となるのは、ユーザから入力されたホスト名と デフォルトドメイン名 (dig では
+domain=XXX
、nslookup では-domain=XXX
で設定) に限られ、ネームサーバ名やサーチリスト の部分はエンコードされません。上記に加えて、libidnkit の初期化や、
dns_name_settotextfilter()
を呼んでデコード関数を登録する処理を追加しました。 このために、登録用のデコード関数output_filter
も合わせて 追加作成しています。
configure
への変更
コンパイル前に実行する configure
スクリプトに対して、
次の変更を施しました。
- 以下のオプションを追加しました。
-
--with-idn
-
--with-libiconv
-
--with-idnlib
README.idnkit
というファイルを参照してください。 -
-
--with-idn
オプションの指定に応じて、make 変数STD_CINCLUDES
の値を変更するようにしました。 この変数には、C コンパイラに対してヘッダファイルの検索パスを 足すよう指示するオプションを記しておきます。--with-idn
オプションによって国際化ドメイン名への 対応を有効とするように指示された場合は、idnkit のヘッダファイル のインストール先を検索パスに含めるようにしました。 - 新たに make 変数
IDNLIBS
を設け、この変数の値をconfigure
の中で設定するようにしました。 C コンパイラがアプリケーションをリンクする際に、libidnkit および iconv ライブラリをリンクするよう指示するオプションをこの変数にセット します。 セットする値は--with-idn
、--with-libiconv
、--with-idnlib
オプションで指定された値から導出します。 - 関数
setlocale()
の有無をチェックし、存在すれば コンパイル時に CPP マクロHAVE_SETLOCALE
が定義される ようにしました。 - ヘッダファイル
locale.h
の有無についてチェックし、 存在すればコンパイル時に CPP マクロHAVE_LOCALE_H
が 定義されるようにしました。
なお、configure
は GNU Autoconf によって
configure.in
というファイルから自動生成されるファイルですので、
実際には configure.in
を編集することで、この変更を行っています。
README.idnkit の作成
configure
スクリプトに対して追加したオプションついて、
英語で記述したファイルです。このファイルは新規に作成しました。
Makefile
への変更
bin/dig/Makefile.in
に改造を施し、国際化ドメイン名への
対応が有効になっている場合 (configure
実行時に
--with-idn
オプションが指定された場合) は、
dig, nslookup, host コマンドを生成する際に libidnkit および iconv の
ライブラリをリンクするようにしました。
マニュアルの変更
BIND 9 付属のマニュアル dig(1), host(1) に、
「環境変数 IDN_DISABLE
がセットされていると、
国際化ドメイン名への対応が無効になる」旨を記述しました。
BIND 9 ではマニュアルは DocBook 形式の SGML ファイルから生成する
ようになっているので、元の SGML ファイルを編集しました。
変更を施したファイルは、次の通りです。
- bin/dig/host.1
- bin/dig/host.docbook
- host のマニュアルと、その元となる DocBook 形式のファイルです。
- bin/dig/host.1
- bin/dig/host.docbook
- host のマニュアルと、その元となる DocBook 形式のファイルです。
なお、nslookup のマニュアルは、BIND 9 には付属していません。