DNS サービスプロバイダ
Java Naming Directory InterfaceTM (JNDI)


コメントの送付先: jndi@java.sun.com

目次


はじめに

DNS サービスプロバイダによって、JNDI アプリケーションが、インターネットドメインネームシステムに格納された情報にアクセスできるようになります。このプロバイダには、JNDI ディレクトリコンテキストのツリーとしての DNS 名前空間と、JNDI の属性としての DNS リソースレコードが用意されています。

このドキュメントでは、DNS サービスプロバイダの機能と、DNS が JNDI にマッピングされる方法の詳細について説明します。


適合性

DNS サービスプロバイダはドメインネームシステムをサポートします。その規定は、RFC 1034RFC 1035 およびその更新と明細は RFC 1123 RFC 2181 に記述されています。現在のところ、次のリソースレコードの型とクラスをサポートしています。

仕様
A RFC 1035
NS RFC 1035
CNAME RFC 1035
SOA RFC 1035
PTR RFC 1035
MX RFC 1035
TXT RFC 1035
HINFO RFC 1035
AAAA RFC 1886
NAPTR RFC 2915
SRV RFC 2782
               
クラス 仕様
IN RFC 1035
HS RFC 1035
それぞれの検索は、最初に UDP を使用して実行されます。応答が長すぎて、切り捨てないと UDP パケットに返すことができない場合は、TCP を使用して検索が繰り返されます。


環境プロパティ

DNS サービスプロバイダでは、次の JNDI 環境プロパティを使用します。初期コンテキストコンストラクタ、システムプロパティ、アプレットパラメータ、およびリソースファイルを使用したときのプロパティの初期値については、JNDI のドキュメントを参照してください。

java.naming.authoritative
このプロパティは、すべての応答が権限をもっている必要があるかどうかを指定するために使用します。この値が true の場合、権限のある応答のみを DNS サーバから受け入れます。その他の場合は、すべての応答を受け入れます。このプロパティが設定されない場合は、デフォルト値の false が使用されます。すべての応答が権限をもつ必要があることを指定する場合の例を示します。
env.put(Context.AUTHORITATIVE, "true");
権限のある応答のみが返されるように要求した場合、一部の情報が利用できなくなる場合があります。これは、DNS プロトコルが権限をもっている情報を要求する方法を提供していないためです。たとえば、DNS サービスプロバイダがクエリの結果として権限のないデータを取得した場合は、権限のあるデータのみを返すため、そのデータを破棄します。
java.naming.factory.initial
DNS サービスプロバイダを選択するときに、初期コンテキストとして使用されます。プロバイダでは使用されません。プロバイダの初期コンテキストファクトリのクラス名を指定し、次の例のように設定できます。
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
java.naming.factory.object
このプロパティには、DNS から読み取られたオブジェクトを変換するための、オブジェクトファクトリクラスの完全修飾名のリストが含まれます。各クラス名はコロンで区切ります。この機構を使用して、アプリケーションでより使いやすい形式のオブジェクトに変換されます。詳細については、DirectoryManager.getObjectInstance() を参照してください。
java.naming.provider.url
初期 DNS コンテキストで使用される DNS サーバのホスト名とポートのほかに、初期コンテキストのドメイン名を指定します。URL 形式の詳細については、下の「DNS の擬似 URL」を参照してください。

次に例を示します。

env.put(Context.PROVIDER_URL, "dns://server1.sun.com/java.sun.com");
プロバイダが server1.sun.com にある DNS サーバを使用するようにして、初期コンテキストのドメイン名を java.sun.com に設定します。このプロパティが設定されない場合、デフォルト値の「dns:」が使用されます。(使用されるデフォルト値は、「DNS の擬似 URL」セクションに記載されている。)

このプロパティに空白文字で区切った URL のリストを指定して、複数の DNS サーバを指定できます。サーバの 1 つが応答するまで、各サーバに順番に接続します。初期コンテキストには 1 つのドメイン名しか含まれていないため、複数の URL を指定する場合は、それぞれのドメイン部分が同じである必要があります。次に例を示します。

env.put(Context.PROVIDER_URL,
    "dns://server1.sun.com/java.sun.com dns://server2.sun.com/java.sun.com");
com.sun.jndi.dns.lookup.attr
デフォルトでは、JNDI が DNS コンテキストでオブジェクトファクトリを呼び出す前に、コンテキストのインターネット TXT 属性を読み取り、ファクトリに渡します。このプロパティは、設定する場合は、使用する別の属性識別子を指定します。属性識別子の形式については、次の「DNS コンテンツの JNDI へのマッピング」を参照してください。
com.sun.jndi.dns.recursion
このプロパティは、DNS クエリーで回帰を許可しないことを指定するために使用します。このプロパティが設定されていない場合や、「true」に設定されている場合、回帰を許可します。その他の場合は、回帰を許可しません。DNS クエリーでの回帰を許可しないことを指定する場合の例を示します。
env.put("com.sun.jndi.dns.recursion", "false");
com.sun.jndi.dns.timeout.initial
com.sun.jndi.dns.timeout.retries
これらのプロパティは、DNS プロバイダが UDP クエリーの発行時に使用するタイムアウト関連のデフォルトを変更する場合に使用されます。DNS プロバイダは、次の指数バックオフアルゴリズムを使用して UDP クエリーを発行します。プロバイダは、DNS サーバにクエリーを発行して、タイムアウト期間内 (デフォルトでは 1 秒) に応答が到着するのを待機します。プロバイダにタイムアウト期間内に応答が到着しなかった場合、プロバイダは次のサーバにクエリーを発行し、応答を受け取るまで、これを繰り返します。プロバイダがどのサーバからも応答を受け取らなかった場合、タイムアウト期間を 2 倍にし、リトライの最大回数まで (デフォルトでは 4 回) 各サーバにクエリーを発行するプロセスを繰り返します。

com.sun.jndi.dns.timeout.initial」プロパティが設定されている場合、初期タイムアウト期間 (すなわち 2 倍にする前の期間) として使用する数値 (ミリ秒) を指定します。このプロパティが設定されない場合は、デフォルトの初期タイムアウトは 1000 ミリ秒です。

com.sun.jndi.dns.timeout.retries」プロパティが設定されている場合、上記の指数バックオフアルゴリズムを使用して各サーバに対してリトライする回数を指定します。このプロパティが設定されない場合は、デフォルトのリトライ回数は 4 です。

次の例では、タイムアウトの合計の長さをあまり変えずに、初期タイムアウト期間を 2 倍にしています。

env.put("com.sun.jndi.dns.timeout.initial", "2000");
env.put("com.sun.jndi.dns.timeout.retries", "3");

注 - Java 2 SDK、v 1.4.1 以前のシステムでは、上記の 2 つのプロパティは無視され、常にデフォルトが適用されます。


DNS コンテンツの JNDI へのマッピング

DNS サービスプロバイダは、DNS 名、ノード、およびリソースレコードを、次のようにして JNDI のデータ型にマッピングします。

名前

DNS ドメイン名は、JNDI の複合 Name オブジェクトで表現されます。左から右へドットで区切られた構文で、円記号 (\) がエスケープ文字として使用されます。\DDD 形式のエスケープシーケンスも使用できます。ここで DDD は 3 桁の 10 進数です。名前では、大文字と小文字は区別されません。明示的なルートドメインラベル (「.」) で終わる完全修飾名は、もっとも重要な位置を空白要素にした複合 Name オブジェクトで表されます。

ホスト名はドメイン名のサブセットです。ホスト名のラベルには、US-ASCII 文字、数字、ハイフンのみが使用でき、先頭または末尾にハイフンは使用できません。これらの規則に従っていない名前はドメイン名として有効になる場合もありますが、一部の DNS アプリケーションで使用できないため、ほとんどの場合、このような名前の使用は避けるべきです。

DNS では、US-ASCII 以外の文字に使用するための (UTF-8 などの) エンコーディングを指定していません。その結果、DNS 名の文字がゼロ以外の高位のバイトを使用することはありません。ドメイン名の国際化の作業が終了した時点で、その作業に合わせて DNS サービスプロバイダを更新することができます。

ノードおよびリソースレコード

DNS のノードは、DirContext オブジェクトで表現されます。ノードのリソースレコードは、コンテキストの属性で表現されます。たとえば、DNS ノードの sun.com にアドレスが「192.9.49.33」の A レコードとデータが「10 sun.com」の MX レコードが含まれている場合に、対応する JNDI コンテキストには、識別子が「A」で文字列値が「192.9.49.33」の属性と、識別子が「MX」で文字列値が「10 sun.com」の属性があります。

同じ型の複数のレコードは、複数の値がある属性として表現されます。サポートされないレコード型は、数字の識別子およびバイト列の値で表現されます。

属性識別子

DNS リソースレコードのクラス名と型名が、JNDI 属性識別子にマッピングされます。レコードがインターネットクラスの場合、対応する属性 ID はレコードの型名です。サポートされない型の場合は、代わりに整数値が使用されます。レコードがインターネットクラスでない場合は、クラス名 (または整数のクラス値) が、空白文字で区切られて属性 ID に付加されます。たとえば、属性識別子の「AAAA」で IPv6 アドレスレコードが表現され、属性識別子「HS 97」で Hesiod クラスの 97 型のリソースレコードが表現されます。

また、「スーパークラス」属性識別子も定義されます。DirContext.getAttributes() メソッドを使用してレコードを問い合わせる際に、これらの識別子が便利な場合があります。属性名で型名またはクラス名の代わりに「*」がある場合は、任意の型またはクラスのレコードであることを表します。たとえば、属性識別子の「IN *」は、インターネットクラスのすべてのレコードを検出するために getAttributes() メソッドに渡すことができます。属性識別子の「* *」は、任意のクラスまたはタイプを表しています。

属性識別子では、大文字と小文字は区別されません。


DNS の擬似 URL

URL に似た記述を使用して、DNS サーバ、ポート、java.naming.provider.url プロパティおよび初期コンテキストに渡される URL 名内のドメインを表します。この擬似 URL の形式は、次の通りです。
   dns:[//host[:port]][/domain]
「host」および「port」で、使用する DNS サーバを示します。「host」のみが指定されている場合、ポートにはデフォルトの 53 が使用され、「port」のみが指定されている場合、ホストはデフォルトの「localhost」になります。いずれも指定されない場合、プロバイダは基本プラットフォーム用に構成されたサーバを判断し、このサーバの使用を試みます。これに成功した場合、プロバイダは java.naming.provider.url プロパティを、サーバで構築されたスペース区切りの URL リストに設定します (たとえば、Solaris または Linux の場合、プロバイダは /etc/resolv.conf ファイルを読み込む)。DNS が基本プラットフォームに設定されていない場合、ホストとポートはデフォルトの「localhost」と 53 になります。

注 - Java 2 SDK、v 1.4.1 以前のシステムでは、プロバイダは基本プラットフォームの DNS 設定の使用を試みません。ホストもポートも指定されていない場合、ホストとポートはデフォルトの「localhost」と 53 になります。

「domain」はコンテキストの DNS ドメイン名であり、必ずしもサーバのドメインに関連付けられている必要はありません。デフォルトは「.」です。(ルートドメイン) を使用します。


API マッピング

DNS サービスプロバイダには、DirContext インタフェースが実装されています。メソッドが DNS の操作にマッピングされる方法は、次のとおりです。ここに挙げられていないメソッドはサポートされていません。
addToEnvironment()
新しいプロパティを環境に追加するか、既存のプロパティを変更します。
close()
内部データ構造を解放します。
composeName()
2 つの名前を重ね合わせます。
getAttributes()
DNS リソースレコードを表す属性を返します。
getEnvironment()
このコンテキストに関連する環境プロパティを返します。
getNameInNamespace()
このノードの完全修飾ドメイン名を返します。
getNameParser()
DNS ドメイン名を解析するために、名前パーサを返します。
lookup()
lookupLink()
指定されたノードを表す DirContext を返します。アプリケーションまたはユーザがオブジェクトファクトリを供給していた場合は、返される前にオブジェクトで DirectoryManager.getObjectInstance() メソッドが呼び出されます。
list()
listBindings()
DNS 名前空間のリストがゾーン転送を使用して実装されているので、これらの操作はコンピュータおよびネットワークに集中し、すべての DNS インストールではサポートされない可能性があります。アプリケーションまたはユーザがオブジェクトファクトリを供給していた場合は、返される前にオブジェクトで DirectoryManager.getObjectInstance() メソッドが呼び出され、属性は渡されません。
removeFromEnvironment()
環境からプロパティを削除します。

使用例

プログラム例 1

この例では、最初に sun.com ドメインを表す初期コンテキストを作成し、次にそのドメイン内の 2 つのホストの IP アドレス (A レコード) を読み込みます。
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("java.naming.provider.url",    "dns://server1.sun.com/sun.com");

DirContext ictx = new InitialDirContext(env);
Attributes attrs1 = ictx.getAttributes("host1", new String[] {"A"});
Attributes attrs2 = ictx.getAttributes("host2", new String[] {"A"});

プログラム例 2

プログラム例 1 のプロパティを使用しないで、デフォルトの初期コンテキストのメソッドに DNS の擬似 URL を渡します。この例では、sun.com ドメイン内のホストの MX レコードを読み込みます。
DirContext ictx = new InitialDirContext();
Attributes attrs3 = ictx.getAttributes("dns://server1.sun.com/host3.sun.com",
                                       new String[] {"MX"});

セキュリティについて

セキュリティマネージャがインストールされていると、これを使用する DNS サービスプロバイダとアプリケーションの両方に、次のアクセス権が許可されます。

permission java.net.SocketPermission "host[:port]", "connect,accept";
各ホストまたはポートは、java.naming.provider.url プロパティ、コンテキストメソッドに渡された URL 文字列名、およびオブジェクト参照から識別されます。


連合

DNS サービスプロバイダでは、複合名は「強く区分されている」と見なされます。つまり、複合名の最初のコンポーネントが DNS ドメイン名として処理され、残りのコンポーネントは次のネームシステム (nns) の名前として処理されます。暗示的な次のネームシステムは動的に決定されます。

たとえば、次の例では、次のネームシステムのルートのリストを出力しています。このネームシステムは、DNS コンテキストを超えて連合されています。次に、マルチコンポーネントの複合名を使用して名前が参照されます。

// List the root of the nns.
// Note the use of a trailing slash to indicate traversal into the nns.
NamingEnumeration enum = ctx.list("java.sun.com/");

// A composite name lookup.
Object obj = ctx.lookup("sun.com/some/x/y/z");



Copyright © 2002 Sun Microsystems, Inc. All rights reserved.