Package org.jnode.net.ipv4.util

Source Code of org.jnode.net.ipv4.util.ResolverImpl

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.net.ipv4.util;

import java.net.UnknownHostException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.Map;
import java.util.Collection;

import org.jnode.driver.net.NetworkException;
import org.jnode.net.ProtocolAddress;
import org.jnode.net.Resolver;
import org.jnode.net.ipv4.IPv4Address;
import org.jnode.annotation.SharedStatics;
import org.xbill.DNS.ExtendedResolver;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.SimpleResolver;
import org.xbill.DNS.TextParseException;

/**
* @author Martin Hartvig
*/
@SharedStatics
public class ResolverImpl implements Resolver {
    // FIXME ... upgrade to a more recent version of xbill?

    // FIXME ... this class looks like it is supposed to implement
    // the Singleton pattern. So how come the management methods
    // and a lot of the state is 'static'?
    private static ExtendedResolver resolver;

    private static Map<String, org.xbill.DNS.Resolver> resolvers;

    private static Map<String, ProtocolAddress[]> hosts;

    private static Resolver res = null;

    static {
        // FIXME should this come from a hosts file?
        hosts = new HashMap<String, ProtocolAddress[]>();
        final String localhost = "localhost";
        ProtocolAddress[] protocolAddresses = new ProtocolAddress[] {new IPv4Address("127.0.0.1")};
        hosts.put(localhost, protocolAddresses);
        resolvers = new HashMap<String, org.xbill.DNS.Resolver>();
    }

    private ResolverImpl() {
    }

    /**
     * Singleton
     *
     * @return the singleton of the resolver
     */
    public static Resolver getInstance() {
        if (res == null) {
            // FIXME ... do we REALLY have to do this???
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    System.setProperty("dns.server", "127.0.0.1");
                    System.setProperty("dns.search", "localdomain");
                    return null;
                }
            });
            res = new ResolverImpl();
        }
        return res;
    }

    /**
     * Get list all the dns servers
     */
    public static Collection<String> getDnsServers() {
        return resolvers.keySet();
    }

    /**
     * Add a dns server
     *
     * @param _dnsserver
     * @throws NetworkException
     */
    public static void addDnsServer(ProtocolAddress _dnsserver) throws NetworkException {
        try {
            if (resolver == null) {
                final String[] server = new String[] {_dnsserver.toString()};
                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                        public Object run() throws Exception {
                            resolver = new ExtendedResolver(server);
                            Lookup.setDefaultResolver(resolver);
                            return null;
                        }
                    });
                } catch (PrivilegedActionException x) {
                    Exception ee = x.getException();
                    if (ee instanceof UnknownHostException) {
                        throw (UnknownHostException) ee;
                    } else {
                        throw new RuntimeException(ee);
                    }
                }
                resolvers.put(_dnsserver.toString(), resolver);
            }
        } catch (UnknownHostException e) {
            throw new NetworkException("Can't add DNS server", e);
        }

        try {
            String key = _dnsserver.toString();
            if (!resolvers.containsKey(key)) {
                SimpleResolver simpleResolver = new SimpleResolver(key);
                resolver.addResolver(simpleResolver);
                resolvers.put(key, simpleResolver);
            }
        } catch (UnknownHostException e) {
            throw new NetworkException("Can't add DNS server", e);
        }
    }

    /**
     * removes a dns server
     *
     * @param _dnsserver
     */
    public static void removeDnsServer(ProtocolAddress _dnsserver) {
        if (resolver == null) {
            return;
        }
        String key = _dnsserver.toString();
        if (resolvers.containsKey(key)) {
            org.xbill.DNS.Resolver resolv = resolvers.remove(key);
            if (resolver.getResolvers().length == 1) {
                resolver = null;
            } else {
                resolver.deleteResolver(resolv);
            }
        }
    }

    /**
     * Get from hosts file.
     *
     * @param _hostname
     * @return
     */
    private ProtocolAddress[] getFromHostsFile(String _hostname) {
        // FIXME ... check for changes to the hosts file?
        return (ProtocolAddress[]) hosts.get(_hostname);
    }

    /**
     * Gets the address(es) of the given hostname.
     *
     * @param hostname
     * @return All addresses of the given hostname. The returned array is at
     *         least 1 address long.
     * @throws java.net.UnknownHostException
     */
    public ProtocolAddress[] getByName(final String hostname) throws UnknownHostException {
        if (hostname == null) {
            throw new UnknownHostException("null");
        }
        if (hostname.equals("*")) {
            // FIXME ... why is this a special case? Comment please or fix it.
            throw new UnknownHostException("*");
        }
        if (resolver == null) {
            throw new UnknownHostException(hostname);
        }

        final PrivilegedExceptionAction<ProtocolAddress[]> action =
                new PrivilegedExceptionAction<ProtocolAddress[]>() {
                    public ProtocolAddress[] run() throws UnknownHostException {
                        ProtocolAddress[] protocolAddresses;

                        // FIXME ... hard-wired policy that 'hosts' file would
                        // be consulted
                        // first. Should be configurable.
                        protocolAddresses = getFromHostsFile(hostname);
                        if (protocolAddresses != null) {
                            return protocolAddresses;
                        }

                        Lookup.setDefaultResolver(resolver);

                        final Lookup lookup;
                        try {
                            lookup = new Lookup(hostname);
                        } catch (TextParseException e) {
                            throw new UnknownHostException(hostname);
                        }

                        lookup.run();

                        if (lookup.getResult() == Lookup.SUCCESSFUL) {
                            final Record[] records = lookup.getAnswers();
                            final int recordCount = records.length;

                            protocolAddresses = new ProtocolAddress[recordCount];

                            for (int i = 0; i < recordCount; i++) {
                                final Record record = records[i];
                                protocolAddresses[i] = new IPv4Address(record.rdataToString());
                            }
                        } else {
                            throw new UnknownHostException(lookup.getErrorString());
                        }

                        return protocolAddresses;
                    }
                };
        try {
            return AccessController.doPrivileged(action);
        } catch (PrivilegedActionException ex) {
            if (ex.getException() instanceof UnknownHostException) {
                throw (UnknownHostException) ex.getException();
            } else {
                throw (UnknownHostException) new UnknownHostException().initCause(ex.getException());
            }
        }
    }

    /**
     * Gets the hostname of the given address.
     *
     * @param address
     * @return All hostnames of the given hostname. The returned array is at
     *         least 1 hostname long.
     * @throws java.net.UnknownHostException
     */

    public String[] getByAddress(ProtocolAddress address) throws UnknownHostException {
        // FIXME ... implement this method properly.
        return new String[0];
    }
}
TOP

Related Classes of org.jnode.net.ipv4.util.ResolverImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.