1068 lines · 36.5 KB · Java
RawDownload
/* * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * 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. */ package com.sun.jndi.dns;  import java.util.Enumeration;import java.util.Hashtable; import javax.naming.*;import javax.naming.directory.*;import javax.naming.spi.DirectoryManager; import com.sun.jndi.toolkit.ctx.*;  /** * A DnsContext is a directory context representing a DNS node. * * @author Scott Seligman */  public class DnsContext extends ComponentDirContext {     DnsName domain;             // fully-qualified domain name of this context,                                // with a root (empty) label at position 0    Hashtable environment;    private boolean envShared;  // true if environment is possibly shared                                // and so must be copied on write    private boolean parentIsDns;        // was this DnsContext created by                                        // another?  see composeName()    private String[] servers;    private Resolver resolver;     private boolean authoritative;      // must all responses be authoritative?    private boolean recursion;          // request recursion on queries?    private int timeout;                // initial timeout on UDP queries in ms    private int retries;                // number of UDP retries     static final NameParser nameParser = new DnsNameParser();     // 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.    private static final int DEFAULT_INIT_TIMEOUT = 1000;    private static final int DEFAULT_RETRIES = 4;    private static final String INIT_TIMEOUT =                                          "com.sun.jndi.dns.timeout.initial";    private static final String RETRIES = "com.sun.jndi.dns.timeout.retries";     // The resource record type and class to use for lookups, and the    // property used to modify them    private CT lookupCT;    private static final String LOOKUP_ATTR = "com.sun.jndi.dns.lookup.attr";     // Property used to disallow recursion on queries    private static final String RECURSION = "com.sun.jndi.dns.recursion";     // ANY == ResourceRecord.QCLASS_STAR == ResourceRecord.QTYPE_STAR    private static final int ANY = ResourceRecord.QTYPE_STAR;     // The zone tree used for list operations    private static final ZoneNode zoneTree = new ZoneNode(null);      /**     * 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.     */    public DnsContext(String domain, String[] servers, Hashtable environment)            throws NamingException {         this.domain = new DnsName(domain.endsWith(".")                                  ? domain                                  : domain + ".");        this.servers = servers;        this.environment = (Hashtable) environment.clone();        envShared = false;        parentIsDns = false;        resolver = null;         initFromEnvironment();    }     /*     * Returns a clone of a DNS context, just like DnsContext(DnsContext)     * but with a different domain name and with parentIsDns set to true.     */    DnsContext(DnsContext ctx, DnsName domain) {        this(ctx);        this.domain = domain;        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.     */    private DnsContext(DnsContext ctx) {        environment = ctx.environment;        envShared = ctx.envShared = true;        parentIsDns = ctx.parentIsDns;        domain = ctx.domain;        servers = ctx.servers;        resolver = ctx.resolver;        authoritative = ctx.authoritative;        recursion = ctx.recursion;        timeout = ctx.timeout;        retries = ctx.retries;        lookupCT = ctx.lookupCT;    }     public void close() {        if (resolver != null) {            resolver.close();            resolver = null;        }    }      //---------- Environment operations     /*     * Override default with a noncloning version.     */    protected Hashtable p_getEnvironment() {        return environment;    }     public Hashtable getEnvironment() throws NamingException {        return (Hashtable) environment.clone();    }     public Object addToEnvironment(String propName, Object propVal)            throws NamingException {         if (propName.equals(LOOKUP_ATTR)) {            lookupCT = getLookupCT((String) propVal);        } else if (propName.equals(Context.AUTHORITATIVE)) {            authoritative = "true".equalsIgnoreCase((String) propVal);        } else if (propName.equals(RECURSION)) {            recursion = "true".equalsIgnoreCase((String) propVal);        } else if (propName.equals(INIT_TIMEOUT)) {            int val = Integer.parseInt((String) propVal);            if (timeout != val) {                timeout = val;                resolver = null;            }        } else if (propName.equals(RETRIES)) {            int val = Integer.parseInt((String) propVal);            if (retries != val) {                retries = val;                resolver = null;            }        }         if (!envShared) {            return environment.put(propName, propVal);        } else if (environment.get(propName) != propVal) {            // copy on write            environment = (Hashtable) environment.clone();            envShared = false;            return environment.put(propName, propVal);        } else {            return propVal;        }    }     public Object removeFromEnvironment(String propName)            throws NamingException {         if (propName.equals(LOOKUP_ATTR)) {            lookupCT = getLookupCT(null);        } else if (propName.equals(Context.AUTHORITATIVE)) {            authoritative = false;        } else if (propName.equals(RECURSION)) {            recursion = true;        } else if (propName.equals(INIT_TIMEOUT)) {            if (timeout != DEFAULT_INIT_TIMEOUT) {                timeout = DEFAULT_INIT_TIMEOUT;                resolver = null;            }        } else if (propName.equals(RETRIES)) {            if (retries != DEFAULT_RETRIES) {                retries = DEFAULT_RETRIES;                resolver = null;            }        }         if (!envShared) {            return environment.remove(propName);        } else if (environment.get(propName) != null) {            // copy-on-write            environment = (Hashtable) environment.clone();            envShared = false;            return environment.remove(propName);        } else {            return null;        }    }     /*     * Update PROVIDER_URL property.  Call this only when environment     * is not being shared.     */    void setProviderUrl(String url) {        // assert !envShared;        environment.put(Context.PROVIDER_URL, url);    }     /*     * Read environment properties and set parameters.     */    private void initFromEnvironment()            throws InvalidAttributeIdentifierException {         lookupCT = getLookupCT((String) environment.get(LOOKUP_ATTR));        authoritative = "true".equalsIgnoreCase((String)                                       environment.get(Context.AUTHORITATIVE));        String val = (String) environment.get(RECURSION);        recursion = ((val == null) ||                     "true".equalsIgnoreCase(val));        val = (String) environment.get(INIT_TIMEOUT);        timeout = (val == null)            ? DEFAULT_INIT_TIMEOUT            : Integer.parseInt(val);        val = (String) environment.get(RETRIES);        retries = (val == null)            ? DEFAULT_RETRIES            : Integer.parseInt(val);    }     private CT getLookupCT(String attrId)            throws InvalidAttributeIdentifierException {        return (attrId == null)            ? new CT(ResourceRecord.CLASS_INTERNET, ResourceRecord.TYPE_TXT)            : fromAttrId(attrId);    }      //---------- Naming operations     public Object c_lookup(Name name, Continuation cont)            throws NamingException {         cont.setSuccess();        if (name.isEmpty()) {            DnsContext ctx = new DnsContext(this);            ctx.resolver = new Resolver(servers, timeout, retries);                                                // clone for parallelism            return ctx;        }        try {            DnsName fqdn = fullyQualify(name);            ResourceRecords rrs =                getResolver().query(fqdn, lookupCT.rrclass, lookupCT.rrtype,                                    recursion, authoritative);            Attributes attrs = rrsToAttrs(rrs, null);            DnsContext ctx = new DnsContext(this, fqdn);            return DirectoryManager.getObjectInstance(ctx, name, this,                                                      environment, attrs);        } catch (NamingException e) {            cont.setError(this, name);            throw cont.fillInException(e);        } catch (Exception e) {            cont.setError(this, name);            NamingException ne = new NamingException(                    "Problem generating object using object factory");            ne.setRootCause(e);            throw cont.fillInException(ne);        }    }     public Object c_lookupLink(Name name, Continuation cont)            throws NamingException {        return c_lookup(name, cont);    }     public NamingEnumeration c_list(Name name, Continuation cont)            throws NamingException {        cont.setSuccess();        try {            DnsName fqdn = fullyQualify(name);            NameNode nnode = getNameNode(fqdn);            DnsContext ctx = new DnsContext(this, fqdn);            return new NameClassPairEnumeration(ctx, nnode.getChildren());         } catch (NamingException e) {            cont.setError(this, name);            throw cont.fillInException(e);        }    }     public NamingEnumeration c_listBindings(Name name, Continuation cont)            throws NamingException {        cont.setSuccess();        try {            DnsName fqdn = fullyQualify(name);            NameNode nnode = getNameNode(fqdn);            DnsContext ctx = new DnsContext(this, fqdn);            return new BindingEnumeration(ctx, nnode.getChildren());         } catch (NamingException e) {            cont.setError(this, name);            throw cont.fillInException(e);        }    }     public void c_bind(Name name, Object obj, Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public void c_rebind(Name name, Object obj, Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public void c_unbind(Name name, Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public void c_rename(Name oldname, Name newname, Continuation cont)            throws NamingException {        cont.setError(this, oldname);        throw cont.fillInException(                new OperationNotSupportedException());    }     public Context c_createSubcontext(Name name, Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public void c_destroySubcontext(Name name, Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public NameParser c_getNameParser(Name name, Continuation cont)            throws NamingException {        cont.setSuccess();        return nameParser;    }      //---------- Directory operations     public void c_bind(Name name,                       Object obj,                       Attributes attrs,                       Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public void c_rebind(Name name,                         Object obj,                         Attributes attrs,                         Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public DirContext c_createSubcontext(Name name,                                         Attributes attrs,                                         Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public Attributes c_getAttributes(Name name,                                      String[] attrIds,                                      Continuation cont)            throws NamingException {         cont.setSuccess();        try {            DnsName fqdn = fullyQualify(name);            CT[] cts = attrIdsToClassesAndTypes(attrIds);            CT ct = getClassAndTypeToQuery(cts);            ResourceRecords rrs =                getResolver().query(fqdn, ct.rrclass, ct.rrtype,                                    recursion, authoritative);            return rrsToAttrs(rrs, cts);         } catch (NamingException e) {            cont.setError(this, name);            throw cont.fillInException(e);        }    }     public void c_modifyAttributes(Name name,                                   int mod_op,                                   Attributes attrs,                                   Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public void c_modifyAttributes(Name name,                                   ModificationItem[] mods,                                   Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public NamingEnumeration c_search(Name name,                                      Attributes matchingAttributes,                                      String[] attributesToReturn,                                      Continuation cont)            throws NamingException {        throw new OperationNotSupportedException();    }     public NamingEnumeration c_search(Name name,                                      String filter,                                      SearchControls cons,                                      Continuation cont)            throws NamingException {        throw new OperationNotSupportedException();    }     public NamingEnumeration c_search(Name name,                                      String filterExpr,                                      Object[] filterArgs,                                      SearchControls cons,                                      Continuation cont)            throws NamingException {        throw new OperationNotSupportedException();    }     public DirContext c_getSchema(Name name, Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }     public DirContext c_getSchemaClassDefinition(Name name, Continuation cont)            throws NamingException {        cont.setError(this, name);        throw cont.fillInException(                new OperationNotSupportedException());    }      //---------- Name-related operations

Lines 1–500 of 1068.