/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* A DnsContext is a directory context representing a DNS node.
*
* @author Scott Seligman
*/
// with a root (empty) label at position 0
// and so must be copied on write
// another? see composeName()
// Timeouts for UDP queries use exponential backoff: each retry
// is for twice as long as the last. The following constants set
// the defaults for the initial timeout (in ms) and the number of
// retries, and name the environment properties used to override
// these defaults.
"com.sun.jndi.dns.timeout.initial";
// The resource record type and class to use for lookups, and the
// property used to modify them
// Property used to disallow recursion on queries
// ANY == ResourceRecord.QCLASS_STAR == ResourceRecord.QTYPE_STAR
// The zone tree used for list operations
/**
* Returns a DNS context for a given domain and servers.
* Each server is of the form "server[:port]".
* IPv6 literal host names include delimiting brackets.
* There must be at least one server.
* The environment must not be null; it is cloned before being stored.
*/
throws NamingException {
? domain
: domain + ".");
envShared = false;
parentIsDns = false;
}
/*
* Returns a clone of a DNS context, just like DnsContext(DnsContext)
* but with a different domain name and with parentIsDns set to true.
*/
this(ctx);
parentIsDns = true;
}
/*
* Returns a clone of a DNS context. The context's modifiable
* private state is independent of the original's (so closing one
* context, for example, won't close the other). The two contexts
* share <tt>environment</tt>, but it's copy-on-write so there's
* no conflict.
*/
}
public void close() {
}
}
//---------- Environment operations
/*
* Override default with a noncloning version.
*/
return environment;
}
}
throws NamingException {
}
}
}
if (!envShared) {
// copy on write
envShared = false;
} else {
return propVal;
}
}
throws NamingException {
authoritative = false;
recursion = true;
if (timeout != DEFAULT_INIT_TIMEOUT) {
}
if (retries != DEFAULT_RETRIES) {
}
}
if (!envShared) {
// copy-on-write
envShared = false;
} else {
return null;
}
}
/*
* Update PROVIDER_URL property. Call this only when environment
* is not being shared.
*/
// assert !envShared;
}
/*
* Read environment properties and set parameters.
*/
private void initFromEnvironment()
throws InvalidAttributeIdentifierException {
}
throws InvalidAttributeIdentifierException {
: fromAttrId(attrId);
}
//---------- Naming operations
throws NamingException {
cont.setSuccess();
// clone for parallelism
return ctx;
}
try {
environment, attrs);
} catch (NamingException e) {
throw cont.fillInException(e);
} catch (Exception e) {
"Problem generating object using object factory");
ne.setRootCause(e);
}
}
throws NamingException {
}
throws NamingException {
cont.setSuccess();
try {
} catch (NamingException e) {
throw cont.fillInException(e);
}
}
throws NamingException {
cont.setSuccess();
try {
} catch (NamingException e) {
throw cont.fillInException(e);
}
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
cont.setSuccess();
return nameParser;
}
//---------- Directory operations
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
cont.setSuccess();
try {
} catch (NamingException e) {
throw cont.fillInException(e);
}
}
int mod_op,
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw new OperationNotSupportedException();
}
throws NamingException {
throw new OperationNotSupportedException();
}
Object[] filterArgs,
throws NamingException {
throw new OperationNotSupportedException();
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
throws NamingException {
throw cont.fillInException(
new OperationNotSupportedException());
}
//---------- Name-related operations
}
// Any name that's not a CompositeName is assumed to be a DNS
// compound name. Convert each to a DnsName for syntax checking.
}
}
// Each of prefix and name is now either a DnsName or a CompositeName.
// If we have two DnsNames, simply join them together.
}
// Wrap compound names in composite names.
? prefix
? name
// Let toolkit do the work at namespace boundaries.
}
: prefixC; // prefixC is already a clone
if (parentIsDns) {
? name
}
return result;
}
//---------- Helper methods
/*
* Resolver is not created until needed, to allow time for updates
* to the environment.
*/
}
return resolver;
}
/*
* Returns the fully-qualified domain name of a name given
* relative to this context. Result includes a root label (an
* empty component at position 0).
*/
return domain;
}
if (dnsName.hasRootLabel()) {
// Be overly generous and allow root label if we're in root domain.
return dnsName;
} else {
throw new InvalidNameException(
}
}
}
/*
* Converts resource records to an attribute set. Only resource
* records in the answer section are used, and only those that
* match the classes and types in cts (see classAndTypeMatch()
* for matching rules).
*/
continue;
}
}
}
return attrs;
}
/*
* Returns true if rrclass and rrtype match some element of cts.
* A match occurs if corresponding classes and types are equal,
* or if the array value is ANY. If cts is null, then any class
* and type match.
*/
return true;
}
if (classMatch && typeMatch) {
return true;
}
}
return false;
}
/*
* Returns the attribute ID for a resource record given its class
* and type. If the record is in the internet class, the
* corresponding attribute ID is the record's type name (or the
* integer type value if the name is not known). 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.
*
* A class or type value of ANY represents an indeterminate class
* or type, and is represented within the attribute ID by "*".
* For example, the attribute ID "IN *" represents
* any type in the internet class, and "* NS" represents an NS
* record of any class.
*/
}
return attrId;
}
/*
* Returns the class and type values corresponding to an attribute
* ID. An indeterminate class or type is represented by ANY. See
* toAttrId() for the format of attribute IDs.
*
* @throws InvalidAttributeIdentifierException
* if class or type is unknown
*/
throws InvalidAttributeIdentifierException {
throw new InvalidAttributeIdentifierException(
"Attribute ID cannot be empty");
}
int rrclass;
int rrtype;
// class
if (space < 0) {
} else {
if (rrclass < 0) {
throw new InvalidAttributeIdentifierException(
}
}
// type
if (rrtype < 0) {
throw new InvalidAttributeIdentifierException(
}
}
/*
* Returns an array of the classes and types corresponding to a
* set of attribute IDs. See toAttrId() for the format of
* attribute IDs, and classAndTypeMatch() for the format of the
* array returned.
*/
throws InvalidAttributeIdentifierException {
return null;
}
}
return cts;
}
/*
* Returns the most restrictive resource record class and type
* that may be used to query for records matching cts.
* See classAndTypeMatch() for matching rules.
*/
int rrclass;
int rrtype;
// Query all records.
// No records are requested, but we need to ask for something.
} else {
}
}
}
}
}
//---------- Support for list operations
/*
* Synchronization notes:
*
* Any access to zoneTree that walks the tree, whether it modifies
* the tree or not, is synchronized on zoneTree.
* The depth of a ZoneNode can thereafter be accessed without
* further synchronization. Access to other fields and methods
* should be synchronized on the node itself.
*
* A zone's contents is a NameNode tree that, once created, is never
* modified. The only synchronization needed is to ensure that it
* gets flushed into shared memory after being created, which is
* accomplished by ZoneNode.populate(). The contents are accessed
* via a soft reference, so a ZoneNode may be seen to be populated
* one moment and unpopulated the next.
*/
/*
* Returns the node in the zone tree corresponding to a
* fully-qualified domain name. If the desired portion of the
* tree has not yet been populated or has been outdated, a zone
* transfer is done to populate the tree.
*/
// Find deepest related zone in zone tree.
synchronized (zoneTree) {
}
dprint("Deepest related zone in zone tree: " +
synchronized (znode) {
}
// If fqdn is in znode's zone, is not at a zone cut, and
// is current, we're done.
boolean restart = false;
synchronized (znode) {
// Zone was modified while we were examining it.
// All bets are off.
restart = true;
} else if (!current) {
znode.depopulate();
} else {
return nnode; // cache hit!
}
}
dprint("Zone not current; discarding node");
if (restart) {
return getNameNode(fqdn);
}
}
}
}
// Cache miss... do it the expensive way.
// Find fqdn's zone and add it to the tree.
synchronized (zoneTree) {
}
// If znode is now populated we know -- because the first half of
// getNodeName() didn't find it -- that it was populated by another
// thread during this method call. Assume then that it's current.
synchronized (znode) {
? znode.getContents()
}
// Desired node should now be in znode's populated zone. Find it.
throw new ConfigurationException(
"DNS error: node not found in its own zone");
}
dprint("Found node in newly-populated zone");
return nnode;
}
/*
* Does a zone transfer to [re]populate a zone in the zone tree.
* Returns the zone's new contents.
*/
throws NamingException {
// assert Thread.holdsLock(znode);
}
/*
* Determine if a ZoneNode's data is current.
* We base this on a comparison between the cached serial
* number and the latest SOA record.
*
* If there is no SOA record, znode is not (or is no longer) a zone:
* depopulate znode and return false.
*
* Since this method may perform a network operation, it is best
* to call it with znode unlocked. Caller must then note that the
* result may be outdated by the time this method returns.
*/
throws NamingException {
// former version: return !znode.isExpired();
if (!znode.isPopulated()) {
return false;
}
synchronized (znode) {
znode.depopulate();
}
return (znode.isPopulated() &&
}
}
//---------- Debugging
private static final boolean debug = false;
if (debug) {
}
}
}
//----------
/*
* A pairing of a resource record class and a resource record type.
* A value of ANY in either field represents an indeterminate value.
*/
class CT {
int rrclass;
int rrtype;
}
}
//----------
/*
*
* Nodes that have children or that are zone cuts are returned with
* classname DirContext. Other nodes are returned with classname
* Object even though they are DirContexts as well, since this might
* make the namespace easier to browse.
*/
: null;
}
/*
* ctx will be set to null when no longer needed by the enumeration.
*/
public void close() {
}
public boolean hasMore() {
if (!more) {
close();
}
return more;
}
if (!hasMore()) {
}
? "javax.naming.directory.DirContext"
: "java.lang.Object";
return ncp;
}
public boolean hasMoreElements() {
return hasMore();
}
try {
return next();
} catch (NamingException e) {
"javax.naming.NamingException was thrown: " +
e.getMessage()));
}
}
}
/*
* An enumeration of Bindings.
*/
}
// Finalizer not needed since it's safe to leave ctx unclosed.
// protected void finalize() {
// close();
// }
if (!hasMore()) {
}
// Clone ctx to create the child context.
try {
return binding;
} catch (Exception e) {
"Problem generating object using object factory");
ne.setRootCause(e);
throw ne;
}
}
}