メインコンテンツへジャンプする

JPNICはインターネットの円滑な運営を支えるための組織です

ロゴ:JPNIC

WHOIS 検索 サイト内検索 WHOISとは? JPNIC WHOIS Gateway
WHOIS検索 サイト内検索

多言語ドメイン名変換 API


概要

多言語ドメイン名の処理は次の2つの処理から構成されます。

  • エンコーディング変換
  • NAMEPREP

mDNkit では、これに加えて地域化のために

  • デリミタマッピング
  • トップレベルドメインに基づくローカルマッピング

の2つの処理を追加しています。

多言語ドメイン処理のアーキテクチャ IDNA では、これらの処理はすべてアプリケーションで行うことになっており、 例えば名前解決用の関数 gethostbyname を呼び出して 多言語ドメイン名の名前解決を行う場合には、 すでにこれらの処理が行われた結果の文字列を渡すことになっています。

mDNkit はアプリケーションでこれらの処理を行うために 2種類の API を用意しています。

高レベル API
一般アプリケーションのためのシンプルで使いやすい API です。 この API を使用すれば、アプリケーションに簡単に多言語ドメイン処理機能を 追加することができます。ただし細かい設定などはできません。
低レベル API
高レベル API ではできないような細かい設定をする必要がある 一部の特殊なアプリケーションのための API です。 高レベル API はこの低レベル API の上に作られています。

低レベル API は特殊なアプリケーションのために用意された API ですので、 ここでは説明しません。もし低レベル API を使用したい場合には、 MDN ライブラリ仕様書resconfモジュール および resモジュール をご覧ください。

高レベル API は次の3つの関数から構成されます。

  1. 初期化を行う mdn_nameinit
  2. 名前解決などのために多言語ドメイン名をエンコードする mdn_encodename
  3. DNS サーバなどから返ってきた多言語ドメイン名をデコードする mdn_decodename

以下、それぞれの関数の説明をします。 MDN ライブラリ仕様書の apiモジュール も合わせてご覧ください。


初期化

多言語ドメイン名の処理のための初期化を行うためには mdn_nameinit を用います。

mdn_result_t mdn_nameinit(void)
              

この関数は MDN ライブラリ全体の初期化を行い、次に 多言語ドメイン名の処理のための各種の設定が記述されている 設定ファイル (mdn.conf) を読み込みます。

この関数は戻り値として実行結果を示す mdn_result_t 型の値を返します。 本関数が返すコードとその意味は次の通りです。

mdn_success
初期化が正常に終了した。
mdn_nofile
設定ファイルがオープンできなかった。
mdn_invalid_syntax
設定ファイルにシンタックスエラーがある。
mdn_invalid_name
設定ファイルに指定されている名前 (エンコーディング名など) に誤りがある。
mdn_nomemory
malloc に失敗した。

この関数を複数回呼び出すこともできますが、その場合 MDN ライブラリ全体の初期化が行われるのは最初の呼び出しの時だけで、 2回目以降は設定ファイルの再読み込みのみが行われます。 アプリケーションの実行中に設定ファイルの内容を変更した場合、 この関数を呼び出すことで最新の設定に合わせることができます。

この関数をあらかじめ呼び出さずにエンコードやデコード関数を 呼び出しても構いません。その場合には、エンコードやデコードの処理に先だち この関数で行われるような初期化の処理が暗黙的に行われます。


エンコード

多言語ドメイン名のエンコード処理、つまり名前解決関数などへ渡すための 文字列に変換するには mdn_encodename を用います。

mdn_result_t mdn_encodename(int actions, const char *from,
                            char *to, size_t tolen)
              

from で指定されるドメイン名に対して、actions で 指定される処理を行い、その結果を to の指す領域に書き込みます。 tolento の指す領域の大きさ (バイト数) で、 tolen を越えて書き込むことはありません。

この関数による多言語ドメイン名のエンコード処理は一般的には 次のような手順になります。

  1. エンコーディング変換
    アプリケーションの使用しているローカルエンコーディング (SJIS 等) から UTF-8 への変換
  2. デリミタマッピング
    特定の文字を、ドメイン名の区切りであるドットに変換
  3. トップレベルドメインに基づくローカルマッピング
    入力されたドメイン名のトップレベルドメインに対応するマッピング
  4. NAMEPREP
    多言語ドメイン名の正規化、禁止文字の検出
  5. エンコーディング変換
    UTF-8 から、多言語ドメイン名の標準エンコーディング (IDN エンコーディング) への変換

引数 actions で、これらのどの処理を実際に実行するかを以下に示す フラグで指定します。 実際に actions に指定するのはこれらのビット毎の論理和です。

MDN_LOCALCONV
ローカルエンコーディングから UTF-8 への変換を行う
MDN_DELIMMAP
デリミタマッピングを行う
MDN_LOCALMAP
トップレベルドメインに基づくローカルマッピングを行う
MDN_NAMEPREP
多言語ドメイン名の正規化、禁止文字の検出を行う
MDN_UNASCHECK
NAMEPREP の中のオプショナルな機能 (実行してもしなくてもよい) である 未割り当てコードポイントの検出を実行する
MDN_IDNCONV
UTF-8 から IDN エンコーディングへの変換を行う

通常のアプリケーションは MDN_UNASCHECK を除くすべての処理を 行えばよいはずです。そのために MDN_ENCODE_APP というマクロが 定義されており、actions にこの値を指定すれば 未割り当てコードポイントの検出を除くすべての処理が行われます。

なお、上記の各処理でのパラメータはすべて mDNkit の 設定ファイル (mdn.conf) で設定されたものが使用されます。以下に使用されるパラメータを記します。

  • デリミタマッピングにおいてドットにマッピングする文字
  • ローカルマッピング規則
  • NAMEPREP のバージョン
  • IDN エンコーディングとして使用するエンコーディング名

この関数は戻り値として実行結果を示す mdn_result_t 型の値を返します。 本関数が返すコードとその意味は次の通りです。

mdn_success
処理が正常に終了した。
mdn_invalid_action
actions で誤ったフラグを指定している。
mdn_invalid_encoding
from で指定された文字列のエンコーディングに誤りがある。
mdn_prohibited
入力文字列中に禁止文字が存在する。 フラグ MDN_UNASCHECK を指定した場合には 未割り当てコードポイントが存在した場合にもこのコードを返す。
mdn_buffer_overflow
tolen の値が小さすぎて結果を格納できない。
mdn_nomemory
malloc に失敗した。

なお、初期化関数 mdn_nameinit を事前に呼び出さずに 本関数を呼び出した場合には、変換処理に先だって初期化が行われます。 この場合には本関数は上に示した他に次のような実行結果を返すことがあります。

mdn_nofile
設定ファイルがオープンできなかった。
mdn_invalid_syntax
設定ファイルにシンタックスエラーがある。
mdn_invalid_name
設定ファイルに指定されている名前 (エンコーディング名など) に誤りがある。

なお、 環境変数 MDN_DISABLE が設定されている場合は、この関数を使用しても 文字列の変換は行われず、元の文字列のままの結果が返されます。 MDN_DISABLE が設定されている環境で文字列の変換を強制的に行う方法は、 環境変数 MDN_DISABLE のオーバーライド に書かれています。


デコード

多言語ドメイン名のデコード処理、つまり名前解決関数などから返された エンコード済のドメイン名文字列を、アプリケーションが使用している エンコーディングの文字列に変換するには mdn_decodename を用います。

mdn_result_t mdn_decodename(int actions, const char *from,
                            char *to, size_t tolen)
              

from で指定されるドメイン名に対して、actions で 指定される処理を行い、その結果を to の指す領域に書き込みます。 tolento の指す領域の大きさ (バイト数) で、 tolen を越えて書き込むことはありません。

この関数による多言語ドメイン名のデコード処理は一般的には 次のような手順になります。

  1. エンコーディング変換
    多言語ドメイン名の標準エンコーディング (IDN エンコーディング) から UTF-8 への変換
  2. NAMEPREP チェック
    正しく NAMEPREP が行われた文字列であるかどうかのチェック
  3. エンコーディング変換
    UTF-8 からアプリケーションの使用しているローカルエンコーディング (SJIS 等) への変換

引数 actions で、これらのどの処理を実際に実行するかを以下に示す フラグで指定します。 実際に actions に指定するのはこれらのビット毎の論理和です。

MDN_IDNCONV
IDN エンコーディングから UTF-8 への変換を行う
MDN_NAMEPREP
正しく NAMEPREP が行われた文字列であるかどうかのチェックを行う。 正しく行われていない場合は、文字列を再び IDN エンコーディングに戻す。
MDN_UNASCHECK
文字列が NAMEPREP の未割り当てコードポイントを含んでいるかどうかのチェック を行う。含んでいた場合は、文字列を再び IDN エンコーディングに戻す。
MDN_LOCALCONV
UTF-8 からローカルエンコーディングへの変換を行う。 ただしローカルエンコーディングに対応する文字がないために 変換不可能な場合には、IDN エンコーディングへの変換を行う。

通常のアプリケーションは MDN_UNASCHECK を除くすべての処理を 行えばよいはずです。そのために MDN_DECODE_APP というマクロが 定義されており、actions にこの値を指定すれば 未割り当てコードポイントの検出を除くすべての処理が行われます。

なお、上記の各処理でのパラメータはすべて mDNkit の 設定ファイル (mdn.conf) で設定されたものが使用されます。以下に使用されるパラメータを記します。

  • IDN エンコーディングとして使用するエンコーディング名
  • NAMEPREP のバージョン

この関数は戻り値として実行結果を示す mdn_result_t 型の値を返します。 本関数が返すコードとその意味は次の通りです。

mdn_success
処理が正常に終了した。
mdn_invalid_action
actions で誤ったフラグを指定している。
mdn_invalid_encoding
from で指定された文字列のエンコーディングに誤りがある。
mdn_buffer_overflow
tolen の値が小さすぎて結果を格納できない。
mdn_nomemory
malloc に失敗した。

なお、初期化関数 mdn_nameinit を事前に呼び出さずに 本関数を呼び出した場合には、変換処理に先だって初期化が行われます。 この場合には本関数は上に示した他に次のような実行結果を返すことがあります。

mdn_nofile
設定ファイルがオープンできなかった。
mdn_invalid_syntax
設定ファイルにシンタックスエラーがある。
mdn_invalid_name
設定ファイルに指定されている名前 (エンコーディング名など) に誤りがある。

なお、 環境変数 MDN_DISABLE が設定されている場合は、この関数を使用しても 文字列の変換は行われず、元の文字列のままの結果が返されます。 MDN_DISABLE が設定されている環境で文字列の変換を強制的に行う方法は、 環境変数 MDN_DISABLE のオーバーライド に書かれています。


環境変数 MDN_DISABLE のオーバーライド

通常の場合、 環境変数 MDN_DISABLE が設定されている環境でドメイン名を変換 するための API を使用しても変換処理は実行されず、元の文字列のまま結果が 返されます。ただし、この設定を明示的にオーバーライドするための API とし て、mdn_enableが用意されています。

void
mdn_enable(int on_off)
              

環境変数 MDN_DISABLE が設定されているかどうかにかかわらず、 on_off が 0 の場合、これ以降のドメイン名変換は行われません。 また、on_off が 0 以外の値であれば、この関数の呼び出し以降は MDN_DISABLE 環境変数が設定されているかどうかにかかわらず、ドメイン名変換 処理が行われます。


プログラム作成方法

上記の API を使用したプログラムを作る方法、および注意点などについて まとめておきます。

  • インクルードファイル
    高レベル API を使用するプログラムでは、stddef.hmdn/api.h の2つのヘッダファイルをインクルードしてください。
    #include <stddef.h>
    #include <mdn/api.h>
                      
  • ロケール設定
    mDNkit はアプリケーションの使用しているローカルエンコーディングを ロケール情報、あるいは環境変数 MDN_LOCAL_CODESET から 取得します。ロケール情報から取得する場合にはアプリケーションの先頭で setlocale を行い、アプリケーションのロケールを正しく 設定してください。
  • エラー表示
    API はいずれも mdn_result_t 型の値を返します。この値から 対応するメッセージ文字列を得るための関数 mdn_result_tostring が用意されています。エラーメッセージを表示する際に使うことができます。 この関数については 仕様書の説明をご覧ください。
  • コンパイルとリンク
    コンパイルする際には、-I オプションで mDNkit の ヘッダファイルのインストールディレクトリ (デフォルトでは /usr/local/include) を指定してください。
    またリンクの際は MDN ライブラリをリンクしてください。もし iconv が標準ライブラリにない場合には、iconv の ライブラリも合わせてリンクしてください。
    cc -I/usr/local/include example.c -L/usr/local/lib -lmdn -liconv
                      

プログラム例

ここでは、上記の API を使用して多言語ドメイン名の名前解決を行うための 簡単なプログラムを紹介します。

#include <stdio.h>
#include <stddef.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <mdn/api.h>

int main(int ac, char **av)
{
    struct hostent *hp;
    char buf1[256];
    char buf2[256];
    char addrbuf[100];
    mdn_result_t r;

    /* ロケールを設定する */
    setlocale(LC_ALL, "");
    if (ac != 2) {
        fprintf(stderr, "Usage: %s hostname\n", av[0]);
        return 1;
    }
    /* gethostbyname を呼ぶ前に名前を変換する */
    if ((r = mdn_encodename(MDN_ENCODE_APP, av[1],
                            buf1, sizeof(buf1))) != mdn_success) {
        fprintf(stderr, "mdn_encodename: %s\n", mdn_result_tostring(r));
        return 1;
    }
    /* 名前解決を行う */
    if ((hp = gethostbyname(buf1)) == NULL) {
        fprintf(stderr, "gethostbyname failed\n");
        return 1;
    }
    /* 返された名前をローカルエンコーディングに変換する */
    if ((r = mdn_decodename(MDN_DECODE_APP, hp->h_name,
                            buf2, sizeof(buf2))) != mdn_success) {
        fprintf(stderr, "mdn_decodename: %s\n", mdn_result_tostring(r));
        return 1;
    }
    printf("%s  %s\n",
           inet_ntop(hp->h_addrtype, hp->h_addr, addrbuf, sizeof(addrbuf)),
           buf2);
    return 0;
}
              

このページを評価してください

このWebページは役に立ちましたか?
よろしければ回答の理由をご記入ください

それ以外にも、ページの改良点等がございましたら自由にご記入ください。

回答が必要な場合は、お問い合わせ先をご利用ください。

ロゴ:JPNIC

Copyright© 1996-2024 Japan Network Information Center. All Rights Reserved.