DNS Service Provider for the
Java Naming Directory Interface™ (JNDI)

Table of Contents


Introduction

The DNS service provider allows JNDI applications to access information stored in the internet Domain Name System. The provider presents the DNS namespace as a tree of JNDI directory contexts, and DNS resource records as JNDI attributes.

This document describes the features of the DNS service provider, and contains details of how DNS is mapped onto JNDI.


Conformance

The DNS service provider supports the Domain Name System as described in RFC 1034 and RFC 1035, and as updated and clarified by RFC 1123 and RFC 2181. It currently supports the following resource record types and classes:

Type Where Specified
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
Each lookup is initially performed using UDP. If the response is too long to be returned in a UDP packet without being truncated, the lookup is repeated using TCP.

Environment Properties

The following JNDI environment properties are relevant to the DNS service provider. See the JNDI documentation for a description of how properties are initialized using the initial context constructor, system properties, applet parameters, and resource files.

java.naming.authoritative

This property is used to specify whether all responses must be authoritative. If its value is "true", only authoritative responses are accepted from DNS servers; otherwise, all responses are accepted. If this property has not been set, the default is "false". Here is an example that specifies that all responses must be authoritative.

env.put(Context.AUTHORITATIVE, "true");

Note that some information might be made unavailable when you request that only authoritative responses be returned because the DNS protocol does not provide a way to request authoritative information. For example, the DNS service provider might have retrieved nonauthoritative data as the result of a query and is subsequently forced to discard it because only authoritative data may be returned.

java.naming.factory.initial

This property is used to select the DNS service provider as the initial context. It is not used by the provider itself. It specifies the class name of the initial context factory for the provider, and may be set as in the following example:

env.put(Context.INITIAL_CONTEXT_FACTORY, "com.example.jndi.dns.DnsContextFactory");

java.naming.factory.object

This property contains a colon-separated list of the fully-qualified class names of object factories for transforming objects read from DNS. This mechanism is used to transform objects into forms more useful to the application. See DirectoryManager.getObjectInstance() for details.

java.naming.provider.url

This property specifies the host name and port of the DNS server used by the initial DNS context, as well the initial context's domain name. For details on the URL format see DNS Pseudo-URLs below. For example:

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

will cause the provider to use the DNS server at server1.example.com, and set the initial context's domain name to example.com. If this property is not set, it defaults to "dns:" (all defaults as described in the DNS Pseudo-URLs section are used).

Multiple DNS servers may be specified by setting this property to a space-separated list of URLs. Each of the servers is contacted in turn until one of them responds. Since the initial context has only a single domain name, if multiple URLs are listed then each must contain the same domain part. For example:

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

com.example.jndi.dns.lookup.attr

Before JNDI invokes an object factory on a DNS context, it by default reads and passes to the factory any internet TXT attributes of the context. This property, if set, names an alternate attribute identifier to use. See Mapping DNS Content to JNDI below for information on the format of attribute identifiers.

com.example.jndi.dns.recursion

This property is used to specify that recursion is disallowed on DNS queries. If this property has not been set or if it has been set to "true", recursion is allowed; otherwise, recursion is disallowed. Here is an example that specifies that recursion on DNS queries is to be disallowed.

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

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

These properties are used to alter the timeout-related defaults that the DNS provider uses when submitting UDP queries. The DNS provider submits UDP queries using the following exponential backoff algorithm. The provider submits a query to a DNS server and waits for a response to arrive within a timeout period (1 second by default). If it receives no response within the timeout period, it queries the next server, and so on. If the provider receives no response from any server, it doubles the timeout period and repeats the process of submitting the query to each server, up to a maximum number of retries (4 by default).

The "com.example.jndi.dns.timeout.initial" property, if set, specifies the number of milliseconds to use as the initial timeout period (i.e., before any doubling). If this property has not been set, the default initial timeout is 1000 milliseconds.

The "com.example.jndi.dns.timeout.retries" property, if set, specifies the number of times to retry each server using the exponential backoff algorithm described previously. If this property has not been set, the default number of retries is 4.

Here is an example that doubles the initial timeout period while keeping total length of all timeouts roughly unchanged.

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

NOTE: On systems earlier than the Java 2 SDK, v 1.4.1, these two properties are ignored and the defaults always apply.


Mapping DNS Content to JNDI

The DNS service provider maps DNS names, nodes, and resource records onto JNDI data types as follows.

Names

DNS domain names are represented by JNDI compound Nameobjects with right-to-left, dot-separated syntax, and with backslash (\) as the escape character. Escape sequences of the form \DDDmay also be used, where DDDis a three-digit decimal value. Names are case-insensitive. A fully-qualified name ending with an explicit root domain label (".") is represented by a compound Nameobject with an empty component in the most-significant position.

Host names are a subset of domain names. Their labels contain only US-ASCII letters, digits, and hyphens, and none may begin or end with a hyphen. While names not conforming to these rules may be valid domain names, they will not be usable by a number of DNS applications, and should in most cases be avoided.

DNS does not specify an encoding (such as UTF-8) to use for characters other than those of US-ASCII. As a consequence, no character in a DNS name will ever have a non-zero high-order byte. When work on internationalizing domain names is finalized, the DNS service provider may be updated to conform to that work.

Nodes and Resource Records

A DNS node is represented by a DirContextobject. The resource records of the node are represented by attributes of the context. For example, if the DNS node example.com contains an A record with the address 192.0.2.33 and an MX record with the data "10 example.com", the corresponding JNDI context will have an attribute with identifier "A" and string value "192.0.2.33" and an attribute with identifier "MX" and string value "10 example.com".

Multiple records of the same type are represented as multi-valued attributes. Records of unsupported types are represented by attributes with numeric identifiers and with byte arrays as values.

Attribute Identifiers

DNS resource record class and type names are mapped onto JNDI attribute identifiers. If a record is in the internet class, the corresponding attribute ID is simply the record's type name. If the type is an unsupported one, its integer value is used instead. If the record is not in the internet class, the class name (or integer class value) is prepended to the attribute ID, separated by a space. For example, the attribute identifier "AAAA" represents an IPv6 address record, and the attribute identifier "HS 97" represents a resource record of type 97 in the Hesiod class.

Superclass attribute identifiers are also defined. These may be useful when querying records using the DirContext.getAttributes() method. If an attribute name has "*" in place of a type name (or class name), it represents records of any type (or class). For example, the attribute identifier "IN *" may be passed to the getAttributes() method to find all internet class records. The attribute identifier "* *" represents records of any class or type.

Attribute identifiers are case-insensitive.


DNS Pseudo-URLs

A URL-like notation is used to represent a DNS server, port, and domain in the java.naming.provider.url property and in URL names passed to the initial context. The format of this pseudo-URL is:
   dns:[//host[:port]][/domain]
The host and port indicate the DNS server to use. If only a host is given, the port defaults to 53; if only a port is given, the host defaults to "localhost". If neither is given, the provider will attempt to determine and use the server(s) configured for the underlying platform, and if successful, will set the java.naming.provider.urlproperty to a space-separated list of URLs constructed using the server(s). (For example, on Solaris or Linux, the provider will read the /etc/resolv.conffile.) If DNS has not been configured on the underlying platform, the host and port default to "localhost" and 53.

NOTE: On systems earlier than the Java 2 SDK, v 1.4.1, the provider does not attempt to use the underlying platform's DNS configuration. If neither host nor port is specified, they default to "localhost" and 53, respectively.

The domain is the DNS domain name of the context, and is not necessarily related to the domain of the server. It defaults to "." (the root domain).


API Mapping

The DNS service provider implements the DirContextinterface. Methods are mapped onto DNS operations as described below. Methods not listed are not supported.
addToEnvironment()

Adds a new property to the environment, or changes an existing property.

close()

Releases internal data structures.

composeName()

Composes two names.

getAttributes()

Returns attributes representing DNS resource records.

getEnvironment()

Returns the environment properties associated with this context.

getNameInNamespace()

Returns the fully-qualified domain name of this node.

getNameParser()

Returns a name parser for DNS domain names.

lookup()
lookupLink()

Returns a DirContext that represents the named node. The DirectoryManager.getObjectInstance() method is invoked on the object before it is returned, in case the application or user has supplied object factories.

list()
listBindings()

The listing of the DNS namespace is implemented using zone transfers, so these operations are potentially compute- and network-intensive, and they may not be supported by all DNS installations. The DirectoryManager.getObjectInstance() method is invoked on an object before it is returned, in case the application or user has supplied object factories; no attributes are passed in.

removeFromEnvironment()

Removes a property from the environment.


Usage Examples

Example 1

In this example we create an initial context representing the example.com domain, then read the IP addresses (the A records) of two hosts in that domain.
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"});

Example 2

Instead of using the properties as above, we may pass a DNS pseudo-URL to the methods of the default initial context. In this example we read the MX record of a host in the example.com domain.

DirContext ictx = new InitialDirContext();
Attributes attrs3 = ictx.getAttributes("dns://server1.example.com/host3.example.com",
                                       new String[] {"MX"});


Security Considerations

When a security manager has been installed, the DNS service provider and the application using it must both be granted the following permissions:

permission java.net.SocketPermission "host[:port]", "connect,accept";

for each host/port identified in the java.naming.provider.urlproperty, in URL string names supplied to context methods, and in object references.


Federation

The DNS service provider treats composite names as strongly separated. That is, it processes the first component of the composite name as a DNS domain name and the rest of the components as names in the next naming system(s)(nns). The implicit next naming system is determined dynamically.

For example, here is an example that lists the root of the next naming system federated beyond a DNS context, and one that looks up a name using a multi-component composite name:

// 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");

Class Where Specified
IN RFC 1035
HS RFC 1035

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