Use jndi-dns to obtain default name servers
Motivation: Using reflection to obtain the default name servers may fail in Java9 and also in previous Java versions if a SecurityManager is present. Modifications: Try using jndi-dns to obtain default name servers and only try using reflection if this fails. Result: Be able to detect default name servers in all cases. Fixes [#6347].
This commit is contained in:
parent
e482d933f7
commit
a0fcb72e5d
@ -20,10 +20,17 @@ import io.netty.util.internal.UnstableApi;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
|
||||
import static io.netty.resolver.dns.DnsServerAddresses.sequential;
|
||||
@ -47,22 +54,48 @@ public final class DefaultDnsServerAddressStreamProvider implements DnsServerAdd
|
||||
|
||||
static {
|
||||
final List<InetSocketAddress> defaultNameServers = new ArrayList<InetSocketAddress>(2);
|
||||
try {
|
||||
Class<?> configClass = Class.forName("sun.net.dns.ResolverConfiguration");
|
||||
Method open = configClass.getMethod("open");
|
||||
Method nameservers = configClass.getMethod("nameservers");
|
||||
Object instance = open.invoke(null);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<String> list = (List<String>) nameservers.invoke(instance);
|
||||
for (String a: list) {
|
||||
if (a != null) {
|
||||
defaultNameServers.add(new InetSocketAddress(SocketUtils.addressByName(a), DNS_PORT));
|
||||
// Using jndi-dns to obtain the default name servers.
|
||||
//
|
||||
// See:
|
||||
// - http://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-dns.html
|
||||
// - http://mail.openjdk.java.net/pipermail/net-dev/2017-March/010695.html
|
||||
Hashtable<String, String> env = new Hashtable<String, String>();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
|
||||
env.put("java.naming.provider.url", "dns://");
|
||||
try {
|
||||
DirContext ctx = new InitialDirContext(env);
|
||||
String dnsUrls = (String) ctx.getEnvironment().get("java.naming.provider.url");
|
||||
String[] servers = dnsUrls.split(" ");
|
||||
for (String server : servers) {
|
||||
try {
|
||||
defaultNameServers.add(SocketUtils.socketAddress(new URI(server).getHost(), DNS_PORT));
|
||||
} catch (URISyntaxException e) {
|
||||
logger.debug("Skipping a malformed nameserver URI: {}", server, e);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Failed to get the system name server list.
|
||||
// Will add the default name servers afterwards.
|
||||
} catch (NamingException ignore) {
|
||||
// Will try reflection if this fails.
|
||||
}
|
||||
|
||||
if (defaultNameServers.isEmpty()) {
|
||||
try {
|
||||
Class<?> configClass = Class.forName("sun.net.dns.ResolverConfiguration");
|
||||
Method open = configClass.getMethod("open");
|
||||
Method nameservers = configClass.getMethod("nameservers");
|
||||
Object instance = open.invoke(null);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<String> list = (List<String>) nameservers.invoke(instance);
|
||||
for (String a: list) {
|
||||
if (a != null) {
|
||||
defaultNameServers.add(new InetSocketAddress(SocketUtils.addressByName(a), DNS_PORT));
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Failed to get the system name server list via reflection.
|
||||
// Will add the default name servers afterwards.
|
||||
}
|
||||
}
|
||||
|
||||
if (!defaultNameServers.isEmpty()) {
|
||||
|
Loading…
Reference in New Issue
Block a user