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

目次


はじめに

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

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


適合性

DNS サービスプロバイダは、RFC 1034RFC 1035 に記述され、RFC 1123RFC 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
それぞれのルックアップは、最初に 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.example.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.example.com/example.com");

プロバイダが server1.example.com にある DNS サーバーを使用するようにして、初期コンテキストのドメイン名を example.com に設定します。このプロパティーが設定されていない場合は、デフォルトで「dns:」になります (「DNS の擬似 URL」で説明されているすべてのデフォルト値が使用されます)。

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

env.put(Context.PROVIDER_URL,
    "dns://server1.example.com/example.com dns://server2.example.com/example.com");

com.example.jndi.dns.lookup.attr

JNDI は DNS コンテキストでオブジェクトファクトリを呼び出す前に、デフォルトでは、そのコンテキストのすべてのインターネット TXT 属性を読み取ってファクトリに渡します。このプロパティーは、設定する場合は、使用する別の属性識別子を指定します。属性識別子の形式については、下の「DNS コンテンツの JNDI へのマッピング」を参照してください。

com.example.jndi.dns.recursion

このプロパティーは、DNS クエリーで再帰が許可されないことを指定するために使用されます。このプロパティーが設定されていない場合や、"true" に設定されている場合は、再帰が許可されます。それ以外の場合は、再帰が許可されません。次に、DNS クエリーで再帰が許可されないことを指定する例を示します。

env.put("com.example.jndi.dns.recursion", "false");

com.example.jndi.dns.timeout.initial
com.example.jndi.dns.timeout.retries

これらのプロパティーは、DNS プロバイダが UDP クエリーを発行するときに使用するタイムアウト関連のデフォルト値を変更するために使用されます。DNS プロバイダは、次の指数バックオフアルゴリズムを使用して UDP クエリーを発行します。プロバイダは、DNS サーバーにクエリーを発行して、タイムアウト期間内 (デフォルトでは 1 秒) に応答が到着するのを待機します。プロバイダにタイムアウト期間内に応答が到着しなかった場合、プロバイダは次のサーバーにクエリーを発行し、応答を受け取るまで、これを繰り返します。どのサーバーからも応答を受信しなかった場合、プロバイダはタイムアウト期間を 2 倍にして、最大の再試行回数 (デフォルトでは 4 回) まで各サーバーにクエリーを発行するプロセスを繰り返します。

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

"com.example.jndi.dns.timeout.retries" プロパティーは、設定されている場合、前に説明した指数バックオフアルゴリズムを使用して各サーバーを再試行する回数を指定します。このプロパティーが設定されていない場合、デフォルトの再試行回数は 4 です。

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

env.put("com.example.jndi.dns.timeout.initial", "2000");
env.put("com.example.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 ノード example.com にアドレスが 192.0.2.33 の A レコードと、データが「10 example.com」の MX レコードが含まれている場合、対応する JNDI コンテキストには識別子が「A」で文字列値が「192.0.2.33」の属性と、識別子が「MX」で文字列値が「10 example.com」の属性が含まれます。

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

属性識別子

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

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

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


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 になります。

このドメインはコンテキストの 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

この例では、example.com ドメインを表す初期コンテキストを作成したあと、そのドメイン内の 2 つのホストの IP アドレス (A レコード) を読み取ります。
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.example.jndi.dns.DnsContextFactory");
env.put("java.naming.provider.url",    "dns://server1.example.com/example.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 を渡します。この例では、example.com ドメイン内のホストの MX レコードを読み取ります。

DirContext ictx = new InitialDirContext();
Attributes attrs3 = ictx.getAttributes("dns://server1.example.com/host3.example.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.example.com/");

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

クラス 仕様
IN RFC 1035
HS RFC 1035

Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.