feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,395 @@
/*
* Copyright (c) 2003, 2013, 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 sun.net.spi;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.StringJoiner;
import java.util.regex.Pattern;
import sun.net.NetProperties;
import sun.net.SocksProxy;
import static java.util.regex.Pattern.quote;
/**
* Supports proxy settings using system properties This proxy selector
* provides backward compatibility with the old http protocol handler
* as far as how proxy is set
*
* Most of the implementation copied from the old http protocol handler
*
* Supports http/https/ftp.proxyHost, http/https/ftp.proxyPort,
* proxyHost, proxyPort, and http/https/ftp.nonProxyHost, and socks.
* NOTE: need to do gopher as well
*/
public class DefaultProxySelector extends ProxySelector {
/**
* This is where we define all the valid System Properties we have to
* support for each given protocol.
* The format of this 2 dimensional array is :
* - 1 row per protocol (http, ftp, ...)
* - 1st element of each row is the protocol name
* - subsequent elements are prefixes for Host & Port properties
* listed in order of priority.
* Example:
* {"ftp", "ftp.proxy", "ftpProxy", "proxy", "socksProxy"},
* means for FTP we try in that oder:
* + ftp.proxyHost & ftp.proxyPort
* + ftpProxyHost & ftpProxyPort
* + proxyHost & proxyPort
* + socksProxyHost & socksProxyPort
*
* Note that the socksProxy should *always* be the last on the list
*/
final static String[][] props = {
/*
* protocol, Property prefix 1, Property prefix 2, ...
*/
{"http", "http.proxy", "proxy", "socksProxy"},
{"https", "https.proxy", "proxy", "socksProxy"},
{"ftp", "ftp.proxy", "ftpProxy", "proxy", "socksProxy"},
{"gopher", "gopherProxy", "socksProxy"},
{"socket", "socksProxy"}
};
private static final String SOCKS_PROXY_VERSION = "socksProxyVersion";
private static boolean hasSystemProxies = false;
static {
final String key = "java.net.useSystemProxies";
Boolean b = AccessController.doPrivileged(
new PrivilegedAction<Boolean>() {
public Boolean run() {
return NetProperties.getBoolean(key);
}});
if (b != null && b.booleanValue()) {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("net");
return null;
}
});
hasSystemProxies = init();
}
}
/**
* How to deal with "non proxy hosts":
* since we do have to generate a pattern we don't want to do that if
* it's not necessary. Therefore we do cache the result, on a per-protocol
* basis, and change it only when the "source", i.e. the system property,
* did change.
*/
static class NonProxyInfo {
// Default value for nonProxyHosts, this provides backward compatibility
// by excluding localhost and its litteral notations.
static final String defStringVal = "localhost|127.*|[::1]|0.0.0.0|[::0]";
String hostsSource;
Pattern pattern;
final String property;
final String defaultVal;
static NonProxyInfo ftpNonProxyInfo = new NonProxyInfo("ftp.nonProxyHosts", null, null, defStringVal);
static NonProxyInfo httpNonProxyInfo = new NonProxyInfo("http.nonProxyHosts", null, null, defStringVal);
static NonProxyInfo socksNonProxyInfo = new NonProxyInfo("socksNonProxyHosts", null, null, defStringVal);
NonProxyInfo(String p, String s, Pattern pattern, String d) {
property = p;
hostsSource = s;
this.pattern = pattern;
defaultVal = d;
}
}
/**
* select() method. Where all the hard work is done.
* Build a list of proxies depending on URI.
* Since we're only providing compatibility with the system properties
* from previous releases (see list above), that list will always
* contain 1 single proxy, default being NO_PROXY.
*/
public java.util.List<Proxy> select(URI uri) {
if (uri == null) {
throw new IllegalArgumentException("URI can't be null.");
}
String protocol = uri.getScheme();
String host = uri.getHost();
if (host == null) {
// This is a hack to ensure backward compatibility in two
// cases: 1. hostnames contain non-ascii characters,
// internationalized domain names. in which case, URI will
// return null, see BugID 4957669; 2. Some hostnames can
// contain '_' chars even though it's not supposed to be
// legal, in which case URI will return null for getHost,
// but not for getAuthority() See BugID 4913253
String auth = uri.getAuthority();
if (auth != null) {
int i;
i = auth.indexOf('@');
if (i >= 0) {
auth = auth.substring(i+1);
}
i = auth.lastIndexOf(':');
if (i >= 0) {
auth = auth.substring(0,i);
}
host = auth;
}
}
if (protocol == null || host == null) {
throw new IllegalArgumentException("protocol = "+protocol+" host = "+host);
}
List<Proxy> proxyl = new ArrayList<Proxy>(1);
NonProxyInfo pinfo = null;
if ("http".equalsIgnoreCase(protocol)) {
pinfo = NonProxyInfo.httpNonProxyInfo;
} else if ("https".equalsIgnoreCase(protocol)) {
// HTTPS uses the same property as HTTP, for backward
// compatibility
pinfo = NonProxyInfo.httpNonProxyInfo;
} else if ("ftp".equalsIgnoreCase(protocol)) {
pinfo = NonProxyInfo.ftpNonProxyInfo;
} else if ("socket".equalsIgnoreCase(protocol)) {
pinfo = NonProxyInfo.socksNonProxyInfo;
}
/**
* Let's check the System properties for that protocol
*/
final String proto = protocol;
final NonProxyInfo nprop = pinfo;
final String urlhost = host.toLowerCase();
/**
* This is one big doPrivileged call, but we're trying to optimize
* the code as much as possible. Since we're checking quite a few
* System properties it does help having only 1 call to doPrivileged.
* Be mindful what you do in here though!
*/
Proxy p = AccessController.doPrivileged(
new PrivilegedAction<Proxy>() {
public Proxy run() {
int i, j;
String phost = null;
int pport = 0;
String nphosts = null;
InetSocketAddress saddr = null;
// Then let's walk the list of protocols in our array
for (i=0; i<props.length; i++) {
if (props[i][0].equalsIgnoreCase(proto)) {
for (j = 1; j < props[i].length; j++) {
/* System.getProp() will give us an empty
* String, "" for a defined but "empty"
* property.
*/
phost = NetProperties.get(props[i][j]+"Host");
if (phost != null && phost.length() != 0)
break;
}
if (phost == null || phost.length() == 0) {
/**
* No system property defined for that
* protocol. Let's check System Proxy
* settings (Gnome & Windows) if we were
* instructed to.
*/
if (hasSystemProxies) {
String sproto;
if (proto.equalsIgnoreCase("socket"))
sproto = "socks";
else
sproto = proto;
Proxy sproxy = getSystemProxy(sproto, urlhost);
if (sproxy != null) {
return sproxy;
}
}
return Proxy.NO_PROXY;
}
// If a Proxy Host is defined for that protocol
// Let's get the NonProxyHosts property
if (nprop != null) {
nphosts = NetProperties.get(nprop.property);
synchronized (nprop) {
if (nphosts == null) {
if (nprop.defaultVal != null) {
nphosts = nprop.defaultVal;
} else {
nprop.hostsSource = null;
nprop.pattern = null;
}
} else if (nphosts.length() != 0) {
// add the required default patterns
// but only if property no set. If it
// is empty, leave empty.
nphosts += "|" + NonProxyInfo
.defStringVal;
}
if (nphosts != null) {
if (!nphosts.equals(nprop.hostsSource)) {
nprop.pattern = toPattern(nphosts);
nprop.hostsSource = nphosts;
}
}
if (shouldNotUseProxyFor(nprop.pattern, urlhost)) {
return Proxy.NO_PROXY;
}
}
}
// We got a host, let's check for port
pport = NetProperties.getInteger(props[i][j]+"Port", 0).intValue();
if (pport == 0 && j < (props[i].length - 1)) {
// Can't find a port with same prefix as Host
// AND it's not a SOCKS proxy
// Let's try the other prefixes for that proto
for (int k = 1; k < (props[i].length - 1); k++) {
if ((k != j) && (pport == 0))
pport = NetProperties.getInteger(props[i][k]+"Port", 0).intValue();
}
}
// Still couldn't find a port, let's use default
if (pport == 0) {
if (j == (props[i].length - 1)) // SOCKS
pport = defaultPort("socket");
else
pport = defaultPort(proto);
}
// We did find a proxy definition.
// Let's create the address, but don't resolve it
// as this will be done at connection time
saddr = InetSocketAddress.createUnresolved(phost, pport);
// Socks is *always* the last on the list.
if (j == (props[i].length - 1)) {
int version = NetProperties.getInteger(SOCKS_PROXY_VERSION, 5).intValue();
return SocksProxy.create(saddr, version);
} else {
return new Proxy(Proxy.Type.HTTP, saddr);
}
}
}
return Proxy.NO_PROXY;
}});
proxyl.add(p);
/*
* If no specific property was set for that URI, we should be
* returning an iterator to an empty List.
*/
return proxyl;
}
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
if (uri == null || sa == null || ioe == null) {
throw new IllegalArgumentException("Arguments can't be null.");
}
// ignored
}
private int defaultPort(String protocol) {
if ("http".equalsIgnoreCase(protocol)) {
return 80;
} else if ("https".equalsIgnoreCase(protocol)) {
return 443;
} else if ("ftp".equalsIgnoreCase(protocol)) {
return 80;
} else if ("socket".equalsIgnoreCase(protocol)) {
return 1080;
} else if ("gopher".equalsIgnoreCase(protocol)) {
return 80;
} else {
return -1;
}
}
private native static boolean init();
private synchronized native Proxy getSystemProxy(String protocol, String host);
/**
* @return {@code true} if given this pattern for non-proxy hosts and this
* urlhost the proxy should NOT be used to access this urlhost
*/
static boolean shouldNotUseProxyFor(Pattern pattern, String urlhost) {
if (pattern == null || urlhost.isEmpty())
return false;
boolean matches = pattern.matcher(urlhost).matches();
return matches;
}
/**
* @param mask non-null mask
* @return {@link java.util.regex.Pattern} corresponding to this mask
* or {@code null} in case mask should not match anything
*/
static Pattern toPattern(String mask) {
boolean disjunctionEmpty = true;
StringJoiner joiner = new StringJoiner("|");
for (String disjunct : mask.split("\\|")) {
if (disjunct.isEmpty())
continue;
disjunctionEmpty = false;
String regex = disjunctToRegex(disjunct.toLowerCase());
joiner.add(regex);
}
return disjunctionEmpty ? null : Pattern.compile(joiner.toString());
}
/**
* @param disjunct non-null mask disjunct
* @return java regex string corresponding to this mask
*/
static String disjunctToRegex(String disjunct) {
String regex;
if (disjunct.startsWith("*")) {
regex = ".*" + quote(disjunct.substring(1));
} else if (disjunct.endsWith("*")) {
regex = quote(disjunct.substring(0, disjunct.length() - 1)) + ".*";
} else {
regex = quote(disjunct);
}
return regex;
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2000, 2005, 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 sun.net.spi.nameservice;
import java.net.UnknownHostException;
public interface NameService {
public java.net.InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException;
public String getHostByAddr(byte[] addr) throws UnknownHostException;
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2000, 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 sun.net.spi.nameservice;
public interface NameServiceDescriptor {
/**
* Create a new instance of the corresponding name service.
*/
public NameService createNameService () throws Exception ;
/**
* Returns this service provider's name
*
*/
public String getProviderName();
/**
* Returns this name service type
* "dns" "nis" etc
*/
public String getType();
}

View File

@@ -0,0 +1,505 @@
/*
* Copyright (c) 2000, 2022, 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 sun.net.spi.nameservice.dns;
import java.lang.ref.SoftReference;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.spi.NamingManager;
import java.util.*;
import sun.net.util.IPAddressUtil;
import sun.net.dns.ResolverConfiguration;
import sun.net.spi.nameservice.*;
import java.security.AccessController;
import sun.security.action.*;
/*
* A name service provider based on JNDI-DNS.
*/
public final class DNSNameService implements NameService {
// List of domains specified by property
private LinkedList<String> domainList = null;
// JNDI-DNS URL for name servers specified via property
private String nameProviderUrl = null;
// Per-thread soft cache of the last temporary context
private static ThreadLocal<SoftReference<ThreadContext>> contextRef =
new ThreadLocal<>();
// Simple class to encapsulate the temporary context
private static class ThreadContext {
private DirContext dirCtxt;
private List<String> nsList;
public ThreadContext(DirContext dirCtxt, List<String> nsList) {
this.dirCtxt = dirCtxt;
this.nsList = nsList;
}
public DirContext dirContext() {
return dirCtxt;
}
public List<String> nameservers() {
return nsList;
}
}
// Returns a per-thread DirContext
private DirContext getTemporaryContext() throws NamingException {
SoftReference<ThreadContext> ref = contextRef.get();
ThreadContext thrCtxt = null;
List<String> nsList = null;
// if no property specified we need to obtain the list of servers
//
if (nameProviderUrl == null)
nsList = ResolverConfiguration.open().nameservers();
// if soft reference hasn't been gc'ed no property has been
// specified then we need to check if the DNS configuration
// has changed.
//
if ((ref != null) && ((thrCtxt = ref.get()) != null)) {
if (nameProviderUrl == null) {
if (!thrCtxt.nameservers().equals(nsList)) {
// DNS configuration has changed
thrCtxt = null;
}
}
}
// new thread context needs to be created
if (thrCtxt == null) {
final Hashtable<String,Object> env = new Hashtable<>();
env.put("java.naming.factory.initial",
"com.sun.jndi.dns.DnsContextFactory");
// If no nameservers property specified we create provider URL
// based on system configured name servers
//
String provUrl = nameProviderUrl;
if (provUrl == null) {
provUrl = createProviderURL(nsList);
if (provUrl.length() == 0) {
throw new RuntimeException("bad nameserver configuration");
}
}
env.put("java.naming.provider.url", provUrl);
// Need to create directory context in privileged block
// as JNDI-DNS needs to resolve the name servers.
//
DirContext dirCtxt;
try {
dirCtxt = java.security.AccessController.doPrivileged(
new java.security.PrivilegedExceptionAction<DirContext>() {
public DirContext run() throws NamingException {
// Create the DNS context using NamingManager rather than using
// the initial context constructor. This avoids having the initial
// context constructor call itself.
Context ctx = NamingManager.getInitialContext(env);
if (!(ctx instanceof DirContext)) {
return null; // cannot create a DNS context
}
return (DirContext)ctx;
}
});
} catch (java.security.PrivilegedActionException pae) {
throw (NamingException)pae.getException();
}
// create new soft reference to our thread context
//
thrCtxt = new ThreadContext(dirCtxt, nsList);
contextRef.set(new SoftReference<ThreadContext>(thrCtxt));
}
return thrCtxt.dirContext();
}
/**
* Resolves the specified entry in DNS.
*
* Canonical name records are recursively resolved (to a maximum
* of 5 to avoid performance hit and potential CNAME loops).
*
* @param ctx JNDI directory context
* @param name name to resolve
* @param ids record types to search
* @param depth call depth - pass as 0.
*
* @return array list with results (will have at least on entry)
*
* @throws UnknownHostException if lookup fails or other error.
*/
private ArrayList<String> resolve(final DirContext ctx, final String name,
final String[] ids, int depth)
throws UnknownHostException
{
ArrayList<String> results = new ArrayList<>();
Attributes attrs;
// do the query
try {
attrs = java.security.AccessController.doPrivileged(
new java.security.PrivilegedExceptionAction<Attributes>() {
public Attributes run() throws NamingException {
return ctx.getAttributes(name, ids);
}
});
} catch (java.security.PrivilegedActionException pae) {
throw new UnknownHostException(pae.getException().getMessage());
}
// non-requested type returned so enumeration is empty
NamingEnumeration<? extends Attribute> ne = attrs.getAll();
if (!ne.hasMoreElements()) {
throw new UnknownHostException("DNS record not found");
}
// iterate through the returned attributes
UnknownHostException uhe = null;
try {
while (ne.hasMoreElements()) {
Attribute attr = ne.next();
String attrID = attr.getID();
for (NamingEnumeration<?> e = attr.getAll(); e.hasMoreElements();) {
String addr = (String)e.next();
// for canoncical name records do recursive lookup
// - also check for CNAME loops to avoid stack overflow
if (attrID.equals("CNAME")) {
if (depth > 4) {
throw new UnknownHostException(name + ": possible CNAME loop");
}
try {
results.addAll(resolve(ctx, addr, ids, depth+1));
} catch (UnknownHostException x) {
// canonical name can't be resolved.
if (uhe == null)
uhe = x;
}
} else {
results.add(addr);
}
}
}
} catch (NamingException nx) {
throw new UnknownHostException(nx.getMessage());
}
// pending exception as canonical name could not be resolved.
if (results.isEmpty() && uhe != null) {
throw uhe;
}
return results;
}
public DNSNameService() throws Exception {
// default domain
String domain = AccessController.doPrivileged(
new GetPropertyAction("sun.net.spi.nameservice.domain"));
if (domain != null && domain.length() > 0) {
domainList = new LinkedList<String>();
domainList.add(domain);
}
// name servers
String nameservers = AccessController.doPrivileged(
new GetPropertyAction("sun.net.spi.nameservice.nameservers"));
if (nameservers != null && nameservers.length() > 0) {
nameProviderUrl = createProviderURL(nameservers);
if (nameProviderUrl.length() == 0) {
throw new RuntimeException("malformed nameservers property");
}
} else {
// no property specified so check host DNS resolver configured
// with at least one nameserver in dotted notation.
//
List<String> nsList = ResolverConfiguration.open().nameservers();
if (nsList.isEmpty()) {
throw new RuntimeException("no nameservers provided");
}
boolean found = false;
for (String addr: nsList) {
if (IPAddressUtil.isIPv4LiteralAddress(addr) ||
IPAddressUtil.isIPv6LiteralAddress(addr)) {
found = true;
break;
}
}
if (!found) {
throw new RuntimeException("bad nameserver configuration");
}
}
}
public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
// DNS records that we search for
String[] ids = {"A", "AAAA", "CNAME"};
// first get directory context
DirContext ctx;
try {
ctx = getTemporaryContext();
} catch (NamingException nx) {
throw new Error(nx);
}
ArrayList<String> results = null;
UnknownHostException uhe = null;
// If host already contains a domain name then just look it up
if (host.indexOf('.') >= 0) {
try {
results = resolve(ctx, host, ids, 0);
} catch (UnknownHostException x) {
uhe = x;
}
}
// Here we try to resolve the host using the domain suffix or
// the domain suffix search list. If the host cannot be resolved
// using the domain suffix then we attempt devolution of
// the suffix - eg: if we are searching for "foo" and our
// domain suffix is "eng.sun.com" we will try to resolve
// "foo.eng.sun.com" and "foo.sun.com".
// It's not normal to attempt devolation with domains on the
// domain suffix search list - however as ResolverConfiguration
// doesn't distinguish domain or search list in the list it
// returns we approximate by doing devolution on the domain
// suffix if the list has one entry.
if (results == null) {
List<String> searchList = null;
Iterator<String> i;
boolean usingSearchList = false;
if (domainList != null) {
i = domainList.iterator();
} else {
searchList = ResolverConfiguration.open().searchlist();
if (searchList.size() > 1) {
usingSearchList = true;
}
i = searchList.iterator();
}
// iterator through each domain suffix
while (i.hasNext()) {
String parentDomain = i.next();
int start = 0;
while ((start = parentDomain.indexOf(".")) != -1
&& start < parentDomain.length() -1) {
try {
results = resolve(ctx, host+"."+parentDomain, ids, 0);
break;
} catch (UnknownHostException x) {
uhe = x;
if (usingSearchList) {
break;
}
// devolve
parentDomain = parentDomain.substring(start+1);
}
}
if (results != null) {
break;
}
}
}
// finally try the host if it doesn't have a domain name
if (results == null && (host.indexOf('.') < 0)) {
results = resolve(ctx, host, ids, 0);
}
// if not found then throw the (last) exception thrown.
if (results == null) {
assert uhe != null;
throw uhe;
}
/**
* Convert the array list into a byte aray list - this
* filters out any invalid IPv4/IPv6 addresses.
*/
assert results.size() > 0;
InetAddress[] addrs = new InetAddress[results.size()];
int count = 0;
for (int i=0; i<results.size(); i++) {
String addrString = results.get(i);
byte[] addr = null;
try {
addr = IPAddressUtil.validateNumericFormatV4(addrString);
} catch (IllegalArgumentException ignored) {
}
if (addr == null) {
addr = IPAddressUtil.textToNumericFormatV6(addrString);
}
if (addr != null) {
addrs[count++] = InetAddress.getByAddress(host, addr);
}
}
/**
* If addresses are filtered then we need to resize the
* array. Additionally if all addresses are filtered then
* we throw an exception.
*/
if (count == 0) {
throw new UnknownHostException(host + ": no valid DNS records");
}
if (count < results.size()) {
InetAddress[] tmp = new InetAddress[count];
for (int i=0; i<count; i++) {
tmp[i] = addrs[i];
}
addrs = tmp;
}
return addrs;
}
/**
* Reverse lookup code. I.E: find a host name from an IP address.
* IPv4 addresses are mapped in the IN-ADDR.ARPA. top domain, while
* IPv6 addresses can be in IP6.ARPA or IP6.INT.
* In both cases the address has to be converted into a dotted form.
*/
public String getHostByAddr(byte[] addr) throws UnknownHostException {
String host = null;
try {
String literalip = "";
String[] ids = { "PTR" };
DirContext ctx;
ArrayList<String> results = null;
try {
ctx = getTemporaryContext();
} catch (NamingException nx) {
throw new Error(nx);
}
if (addr.length == 4) { // IPv4 Address
for (int i = addr.length-1; i >= 0; i--) {
literalip += (addr[i] & 0xff) +".";
}
literalip += "IN-ADDR.ARPA.";
results = resolve(ctx, literalip, ids, 0);
host = results.get(0);
} else if (addr.length == 16) { // IPv6 Address
/**
* Because RFC 3152 changed the root domain name for reverse
* lookups from IP6.INT. to IP6.ARPA., we need to check
* both. I.E. first the new one, IP6.ARPA, then if it fails
* the older one, IP6.INT
*/
for (int i = addr.length-1; i >= 0; i--) {
literalip += Integer.toHexString((addr[i] & 0x0f)) +"."
+Integer.toHexString((addr[i] & 0xf0) >> 4) +".";
}
String ip6lit = literalip + "IP6.ARPA.";
try {
results = resolve(ctx, ip6lit, ids, 0);
host = results.get(0);
} catch (UnknownHostException e) {
host = null;
}
if (host == null) {
// IP6.ARPA lookup failed, let's try the older IP6.INT
ip6lit = literalip + "IP6.INT.";
results = resolve(ctx, ip6lit, ids, 0);
host = results.get(0);
}
}
} catch (Exception e) {
throw new UnknownHostException(e.getMessage());
}
// Either we couldn't find it or the address was neither IPv4 or IPv6
if (host == null)
throw new UnknownHostException();
// remove trailing dot
if (host.endsWith(".")) {
host = host.substring(0, host.length() - 1);
}
return host;
}
// ---------
private static void appendIfLiteralAddress(String addr, StringBuffer sb) {
if (IPAddressUtil.isIPv4LiteralAddress(addr)) {
sb.append("dns://" + addr + " ");
} else {
if (IPAddressUtil.isIPv6LiteralAddress(addr)) {
sb.append("dns://[" + addr + "] ");
}
}
}
/*
* @return String containing the JNDI-DNS provider URL
* corresponding to the supplied List of nameservers.
*/
private static String createProviderURL(List<String> nsList) {
StringBuffer sb = new StringBuffer();
for (String s: nsList) {
appendIfLiteralAddress(s, sb);
}
return sb.toString();
}
/*
* @return String containing the JNDI-DNS provider URL
* corresponding to the list of nameservers
* contained in the provided str.
*/
private static String createProviderURL(String str) {
StringBuffer sb = new StringBuffer();
StringTokenizer st = new StringTokenizer(str, ",");
while (st.hasMoreTokens()) {
appendIfLiteralAddress(st.nextToken(), sb);
}
return sb.toString();
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2000, 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 sun.net.spi.nameservice.dns;
import sun.net.spi.nameservice.*;
public final class DNSNameServiceDescriptor implements NameServiceDescriptor {
/**
* Create a new instance of the corresponding name service.
*/
public NameService createNameService() throws Exception {
return new DNSNameService();
}
/**
* Returns this service provider's name
*
*/
public String getProviderName() {
return "sun";
}
/**
* Returns this name service type
* "dns" "nis" etc
*/
public String getType() {
return "dns";
}
}