DNS move JDK DNS resolution out of DnsServerAddresses static initialization
Motivation: DnsServerAddresses loads the default DNS servers used for DNS resolution in a static initialization block. This is subject to blocking and may cause unexpected delays. We can move this initialization to DefaultDnsServerAddressStreamProvider where it is more expected to load the JDK's default configuration. Modifications: - Move all the static initialization from DnsServerAddresses to DefaultDnsServerAddressStreamProvider - Deprecate static methods in DnsServerAddresses which have moved to DefaultDnsServerAddressStreamProvider - Remove usage of deprecated methods in DnsServerAddresses Result: Usage of JDK's blocking DNS resolver is not required to use resolver-dns.
This commit is contained in:
parent
08646afc1e
commit
155983f1a1
@ -15,23 +15,115 @@
|
||||
*/
|
||||
package io.netty.resolver.dns;
|
||||
|
||||
import io.netty.util.internal.SocketUtils;
|
||||
import io.netty.util.internal.UnstableApi;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import static io.netty.resolver.dns.DnsServerAddresses.defaultAddresses;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static io.netty.resolver.dns.DnsServerAddresses.sequential;
|
||||
|
||||
/**
|
||||
* A {@link DnsServerAddressStreamProvider} which will use predefined default DNS servers to use for DNS resolution.
|
||||
* These defaults do not respect your host's machines defaults.
|
||||
* <p>
|
||||
* This may use the JDK's blocking DNS resolution to bootstrap the default DNS server addresses.
|
||||
*/
|
||||
@UnstableApi
|
||||
public final class DefaultDnsServerAddressStreamProvider implements DnsServerAddressStreamProvider {
|
||||
private static final InternalLogger logger =
|
||||
InternalLoggerFactory.getInstance(DefaultDnsServerAddressStreamProvider.class);
|
||||
public static final DefaultDnsServerAddressStreamProvider INSTANCE = new DefaultDnsServerAddressStreamProvider();
|
||||
|
||||
private static final List<InetSocketAddress> DEFAULT_NAME_SERVER_LIST;
|
||||
private static final InetSocketAddress[] DEFAULT_NAME_SERVER_ARRAY;
|
||||
private static final DnsServerAddresses DEFAULT_NAME_SERVERS;
|
||||
static final int DNS_PORT = 53;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Failed to get the system name server list.
|
||||
// Will add the default name servers afterwards.
|
||||
}
|
||||
|
||||
if (!defaultNameServers.isEmpty()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Default DNS servers: {} (sun.net.dns.ResolverConfiguration)", defaultNameServers);
|
||||
}
|
||||
} else {
|
||||
Collections.addAll(
|
||||
defaultNameServers,
|
||||
SocketUtils.socketAddress("8.8.8.8", DNS_PORT),
|
||||
SocketUtils.socketAddress("8.8.4.4", DNS_PORT));
|
||||
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
"Default DNS servers: {} (Google Public DNS as a fallback)", defaultNameServers);
|
||||
}
|
||||
}
|
||||
|
||||
DEFAULT_NAME_SERVER_LIST = Collections.unmodifiableList(defaultNameServers);
|
||||
DEFAULT_NAME_SERVER_ARRAY = defaultNameServers.toArray(new InetSocketAddress[defaultNameServers.size()]);
|
||||
DEFAULT_NAME_SERVERS = sequential(DEFAULT_NAME_SERVER_ARRAY);
|
||||
}
|
||||
|
||||
private DefaultDnsServerAddressStreamProvider() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DnsServerAddressStream nameServerAddressStream(String hostname) {
|
||||
return defaultAddresses().stream();
|
||||
return DEFAULT_NAME_SERVERS.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of the system DNS server addresses. If it failed to retrieve the list of the system DNS server
|
||||
* addresses from the environment, it will return {@code "8.8.8.8"} and {@code "8.8.4.4"}, the addresses of the
|
||||
* Google public DNS servers.
|
||||
*/
|
||||
public static List<InetSocketAddress> defaultAddressList() {
|
||||
return DEFAULT_NAME_SERVER_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link DnsServerAddresses} that yields the system DNS server addresses sequentially. If it failed to
|
||||
* retrieve the list of the system DNS server addresses from the environment, it will use {@code "8.8.8.8"} and
|
||||
* {@code "8.8.4.4"}, the addresses of the Google public DNS servers.
|
||||
* <p>
|
||||
* This method has the same effect with the following code:
|
||||
* <pre>
|
||||
* DnsServerAddresses.sequential(DnsServerAddresses.defaultAddressList());
|
||||
* </pre>
|
||||
* </p>
|
||||
*/
|
||||
public static DnsServerAddresses defaultAddresses() {
|
||||
return DEFAULT_NAME_SERVERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array form of {@link #defaultAddressList()}.
|
||||
* @return The array form of {@link #defaultAddressList()}.
|
||||
*/
|
||||
static InetSocketAddress[] defaultAddressArray() {
|
||||
return DEFAULT_NAME_SERVER_ARRAY.clone();
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.DNS_PORT;
|
||||
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||
import static io.netty.util.internal.ObjectUtil.checkPositive;
|
||||
import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero;
|
||||
@ -288,7 +289,7 @@ public class DnsNameResolver extends InetNameResolver {
|
||||
|
||||
// Only here to override in unit tests.
|
||||
int dnsRedirectPort(@SuppressWarnings("unused") InetAddress server) {
|
||||
return DnsServerAddresses.DNS_PORT;
|
||||
return DNS_PORT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,84 +16,36 @@
|
||||
|
||||
package io.netty.resolver.dns;
|
||||
|
||||
import io.netty.util.internal.SocketUtils;
|
||||
import io.netty.util.internal.UnstableApi;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.defaultAddressArray;
|
||||
|
||||
/**
|
||||
* Provides an infinite sequence of DNS server addresses to {@link DnsNameResolver}.
|
||||
*/
|
||||
@UnstableApi
|
||||
@SuppressWarnings("IteratorNextCanNotThrowNoSuchElementException")
|
||||
public abstract class DnsServerAddresses {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsServerAddresses.class);
|
||||
|
||||
private static final List<InetSocketAddress> DEFAULT_NAME_SERVER_LIST;
|
||||
private static final InetSocketAddress[] DEFAULT_NAME_SERVER_ARRAY;
|
||||
private static final DnsServerAddresses DEFAULT_NAME_SERVERS;
|
||||
static final int DNS_PORT = 53;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Failed to get the system name server list.
|
||||
// Will add the default name servers afterwards.
|
||||
}
|
||||
|
||||
if (!defaultNameServers.isEmpty()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Default DNS servers: {} (sun.net.dns.ResolverConfiguration)", defaultNameServers);
|
||||
}
|
||||
} else {
|
||||
Collections.addAll(
|
||||
defaultNameServers,
|
||||
SocketUtils.socketAddress("8.8.8.8", DNS_PORT),
|
||||
SocketUtils.socketAddress("8.8.4.4", DNS_PORT));
|
||||
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
"Default DNS servers: {} (Google Public DNS as a fallback)", defaultNameServers);
|
||||
}
|
||||
}
|
||||
|
||||
DEFAULT_NAME_SERVER_LIST = Collections.unmodifiableList(defaultNameServers);
|
||||
DEFAULT_NAME_SERVER_ARRAY = defaultNameServers.toArray(new InetSocketAddress[defaultNameServers.size()]);
|
||||
DEFAULT_NAME_SERVERS = sequential(DEFAULT_NAME_SERVER_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link DefaultDnsServerAddressStreamProvider#defaultAddressList()}.
|
||||
* <p>
|
||||
* Returns the list of the system DNS server addresses. If it failed to retrieve the list of the system DNS server
|
||||
* addresses from the environment, it will return {@code "8.8.8.8"} and {@code "8.8.4.4"}, the addresses of the
|
||||
* Google public DNS servers.
|
||||
*/
|
||||
@Deprecated
|
||||
public static List<InetSocketAddress> defaultAddressList() {
|
||||
return DEFAULT_NAME_SERVER_LIST;
|
||||
return DefaultDnsServerAddressStreamProvider.defaultAddressList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link DefaultDnsServerAddressStreamProvider#defaultAddresses()}.
|
||||
* <p>
|
||||
* Returns the {@link DnsServerAddresses} that yields the system DNS server addresses sequentially. If it failed to
|
||||
* retrieve the list of the system DNS server addresses from the environment, it will use {@code "8.8.8.8"} and
|
||||
* {@code "8.8.4.4"}, the addresses of the Google public DNS servers.
|
||||
@ -104,8 +56,9 @@ public abstract class DnsServerAddresses {
|
||||
* </pre>
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
public static DnsServerAddresses defaultAddresses() {
|
||||
return DEFAULT_NAME_SERVERS;
|
||||
return DefaultDnsServerAddressStreamProvider.defaultAddresses();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,7 +207,7 @@ public abstract class DnsServerAddresses {
|
||||
}
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return DEFAULT_NAME_SERVER_ARRAY;
|
||||
return defaultAddressArray();
|
||||
}
|
||||
|
||||
return list.toArray(new InetSocketAddress[list.size()]);
|
||||
|
@ -31,7 +31,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.netty.resolver.dns.DnsServerAddresses.DNS_PORT;
|
||||
import static io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.DNS_PORT;
|
||||
import static io.netty.util.internal.StringUtil.indexOfNonWhiteSpace;
|
||||
|
||||
/**
|
||||
|
@ -69,6 +69,7 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.DNS_PORT;
|
||||
import static io.netty.resolver.dns.DnsServerAddresses.sequential;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
@ -774,7 +775,7 @@ public class DnsNameResolverTest {
|
||||
@Override
|
||||
int dnsRedirectPort(InetAddress server) {
|
||||
return server.equals(dnsServerAuthority.localAddress().getAddress()) ?
|
||||
dnsServerAuthority.localAddress().getPort() : DnsServerAddresses.DNS_PORT;
|
||||
dnsServerAuthority.localAddress().getPort() : DNS_PORT;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -24,6 +24,7 @@ import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import static io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.defaultAddressList;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@ -35,7 +36,7 @@ public class DnsServerAddressesTest {
|
||||
|
||||
@Test
|
||||
public void testDefaultAddresses() {
|
||||
assertThat(DnsServerAddresses.defaultAddressList().size(), is(greaterThan(0)));
|
||||
assertThat(defaultAddressList().size(), is(greaterThan(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user