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.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
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.lang.reflect.Method;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Hashtable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static io.netty.resolver.dns.DnsServerAddresses.sequential;
|
import static io.netty.resolver.dns.DnsServerAddresses.sequential;
|
||||||
@ -47,22 +54,48 @@ public final class DefaultDnsServerAddressStreamProvider implements DnsServerAdd
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
final List<InetSocketAddress> defaultNameServers = new ArrayList<InetSocketAddress>(2);
|
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")
|
// Using jndi-dns to obtain the default name servers.
|
||||||
final List<String> list = (List<String>) nameservers.invoke(instance);
|
//
|
||||||
for (String a: list) {
|
// See:
|
||||||
if (a != null) {
|
// - http://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-dns.html
|
||||||
defaultNameServers.add(new InetSocketAddress(SocketUtils.addressByName(a), DNS_PORT));
|
// - 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) {
|
} catch (NamingException ignore) {
|
||||||
// Failed to get the system name server list.
|
// Will try reflection if this fails.
|
||||||
// Will add the default name servers afterwards.
|
}
|
||||||
|
|
||||||
|
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()) {
|
if (!defaultNameServers.isEmpty()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user