Dns resolver: honor resolv.conf timeout, rotate and attempts options (#10207)
Motivations ----------- DnsNameResolverBuilder and DnsNameResolver do not auto-configure themselves uing default options define in /etc/resolv.conf. In particular, rotate, timeout and attempts options are ignored. Modifications ------------- - Modified UnixResolverDnsServerAddressStreamProvider to parse ndots, attempts and timeout options all at once and use these defaults to configure DnsNameResolver when values are not provided by the DnsNameResolverBuilder. - When rotate option is specified, the DnsServerAddresses returned by UnixResolverDnsServerAddressStreamProvider is rotational. - Amend resolv.conf options with the RES_OPTIONS environment variable when present. Result: Fixes https://github.com/netty/netty/issues/10202
This commit is contained in:
parent
391cdcdd77
commit
0c7a01503a
@ -77,9 +77,9 @@ import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.DNS_PORT;
|
||||
import static io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider.parseEtcResolverFirstNdots;
|
||||
import static io.netty.util.internal.ObjectUtil.checkPositive;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@ -111,7 +111,7 @@ public class DnsNameResolver extends InetNameResolver {
|
||||
|
||||
static final ResolvedAddressTypes DEFAULT_RESOLVE_ADDRESS_TYPES;
|
||||
static final String[] DEFAULT_SEARCH_DOMAINS;
|
||||
private static final int DEFAULT_NDOTS;
|
||||
private static final UnixResolverOptions DEFAULT_OPTIONS;
|
||||
|
||||
static {
|
||||
if (NetUtil.isIpV4StackPreferred() || !anyInterfaceSupportsIpV6()) {
|
||||
@ -141,13 +141,13 @@ public class DnsNameResolver extends InetNameResolver {
|
||||
}
|
||||
DEFAULT_SEARCH_DOMAINS = searchDomains;
|
||||
|
||||
int ndots;
|
||||
UnixResolverOptions options;
|
||||
try {
|
||||
ndots = parseEtcResolverFirstNdots();
|
||||
options = UnixResolverDnsServerAddressStreamProvider.parseEtcResolverOptions();
|
||||
} catch (Exception ignore) {
|
||||
ndots = UnixResolverDnsServerAddressStreamProvider.DEFAULT_NDOTS;
|
||||
options = UnixResolverOptions.newBuilder().build();
|
||||
}
|
||||
DEFAULT_NDOTS = ndots;
|
||||
DEFAULT_OPTIONS = options;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -383,10 +383,12 @@ public class DnsNameResolver extends InetNameResolver {
|
||||
boolean decodeIdn,
|
||||
boolean completeOncePreferredResolved) {
|
||||
super(eventLoop);
|
||||
this.queryTimeoutMillis = checkPositive(queryTimeoutMillis, "queryTimeoutMillis");
|
||||
this.queryTimeoutMillis = queryTimeoutMillis > 0
|
||||
? queryTimeoutMillis
|
||||
: TimeUnit.SECONDS.toMillis(DEFAULT_OPTIONS.timeout());
|
||||
this.resolvedAddressTypes = resolvedAddressTypes != null ? resolvedAddressTypes : DEFAULT_RESOLVE_ADDRESS_TYPES;
|
||||
this.recursionDesired = recursionDesired;
|
||||
this.maxQueriesPerResolve = checkPositive(maxQueriesPerResolve, "maxQueriesPerResolve");
|
||||
this.maxQueriesPerResolve = maxQueriesPerResolve > 0 ? maxQueriesPerResolve : DEFAULT_OPTIONS.attempts();
|
||||
this.maxPayloadSize = checkPositive(maxPayloadSize, "maxPayloadSize");
|
||||
this.optResourceEnabled = optResourceEnabled;
|
||||
this.hostsFileEntriesResolver = requireNonNull(hostsFileEntriesResolver, "hostsFileEntriesResolver");
|
||||
@ -401,7 +403,7 @@ public class DnsNameResolver extends InetNameResolver {
|
||||
dnsQueryLifecycleObserverFactory) :
|
||||
requireNonNull(dnsQueryLifecycleObserverFactory, "dnsQueryLifecycleObserverFactory");
|
||||
this.searchDomains = searchDomains != null ? searchDomains.clone() : DEFAULT_SEARCH_DOMAINS;
|
||||
this.ndots = ndots >= 0 ? ndots : DEFAULT_NDOTS;
|
||||
this.ndots = ndots >= 0 ? ndots : DEFAULT_OPTIONS.ndots();
|
||||
this.decodeIdn = decodeIdn;
|
||||
this.completeOncePreferredResolved = completeOncePreferredResolved;
|
||||
this.socketChannelFactory = socketChannelFactory;
|
||||
|
@ -29,7 +29,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static io.netty.resolver.dns.DnsServerAddressStreamProviders.platformDefault;
|
||||
import static io.netty.util.internal.ObjectUtil.intValue;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@ -46,16 +45,17 @@ public final class DnsNameResolverBuilder {
|
||||
private Integer minTtl;
|
||||
private Integer maxTtl;
|
||||
private Integer negativeTtl;
|
||||
private long queryTimeoutMillis = 5000;
|
||||
private long queryTimeoutMillis = -1;
|
||||
private ResolvedAddressTypes resolvedAddressTypes = DnsNameResolver.DEFAULT_RESOLVE_ADDRESS_TYPES;
|
||||
private boolean completeOncePreferredResolved;
|
||||
private boolean recursionDesired = true;
|
||||
private int maxQueriesPerResolve = 16;
|
||||
private int maxQueriesPerResolve = -1;
|
||||
private boolean traceEnabled;
|
||||
private int maxPayloadSize = 4096;
|
||||
private boolean optResourceEnabled = true;
|
||||
private HostsFileEntriesResolver hostsFileEntriesResolver = HostsFileEntriesResolver.DEFAULT;
|
||||
private DnsServerAddressStreamProvider dnsServerAddressStreamProvider = platformDefault();
|
||||
private DnsServerAddressStreamProvider dnsServerAddressStreamProvider =
|
||||
DnsServerAddressStreamProviders.platformDefault();
|
||||
private DnsQueryLifecycleObserverFactory dnsQueryLifecycleObserverFactory =
|
||||
NoopDnsQueryLifecycleObserverFactory.INSTANCE;
|
||||
private String[] searchDomains;
|
||||
|
@ -47,19 +47,22 @@ import static java.util.Objects.requireNonNull;
|
||||
public final class UnixResolverDnsServerAddressStreamProvider implements DnsServerAddressStreamProvider {
|
||||
private static final InternalLogger logger =
|
||||
InternalLoggerFactory.getInstance(UnixResolverDnsServerAddressStreamProvider.class);
|
||||
|
||||
private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
|
||||
private static final String RES_OPTIONS = System.getenv("RES_OPTIONS");
|
||||
|
||||
private static final String ETC_RESOLV_CONF_FILE = "/etc/resolv.conf";
|
||||
private static final String ETC_RESOLVER_DIR = "/etc/resolver";
|
||||
private static final String NAMESERVER_ROW_LABEL = "nameserver";
|
||||
private static final String SORTLIST_ROW_LABEL = "sortlist";
|
||||
private static final String OPTIONS_ROW_LABEL = "options";
|
||||
private static final String OPTIONS_ROW_LABEL = "options ";
|
||||
private static final String OPTIONS_ROTATE_FLAG = "rotate";
|
||||
private static final String DOMAIN_ROW_LABEL = "domain";
|
||||
private static final String SEARCH_ROW_LABEL = "search";
|
||||
private static final String PORT_ROW_LABEL = "port";
|
||||
private static final String NDOTS_LABEL = "ndots:";
|
||||
static final int DEFAULT_NDOTS = 1;
|
||||
|
||||
private final DnsServerAddresses defaultNameServerAddresses;
|
||||
private final Map<String, DnsServerAddresses> domainToNameServerStreamMap;
|
||||
private static final Pattern SEARCH_DOMAIN_PATTERN = Pattern.compile("\\s+");
|
||||
|
||||
/**
|
||||
* Attempt to parse {@code /etc/resolv.conf} and files in the {@code /etc/resolver} directory by default.
|
||||
@ -155,6 +158,7 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
private static Map<String, DnsServerAddresses> parse(File... etcResolverFiles) throws IOException {
|
||||
Map<String, DnsServerAddresses> domainToNameServerStreamMap =
|
||||
new HashMap<>(etcResolverFiles.length << 1);
|
||||
boolean rotateGlobal = RES_OPTIONS != null && RES_OPTIONS.contains(OPTIONS_ROTATE_FLAG);
|
||||
for (File etcResolverFile : etcResolverFiles) {
|
||||
if (!etcResolverFile.isFile()) {
|
||||
continue;
|
||||
@ -165,6 +169,7 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
br = new BufferedReader(fr);
|
||||
List<InetSocketAddress> addresses = new ArrayList<>(2);
|
||||
String domainName = etcResolverFile.getName();
|
||||
boolean rotate = rotateGlobal;
|
||||
int port = DNS_PORT;
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
@ -174,7 +179,9 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
if (line.isEmpty() || (c = line.charAt(0)) == '#' || c == ';') {
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith(NAMESERVER_ROW_LABEL)) {
|
||||
if (!rotate && line.startsWith(OPTIONS_ROW_LABEL)) {
|
||||
rotate = line.contains(OPTIONS_ROTATE_FLAG);
|
||||
} else if (line.startsWith(NAMESERVER_ROW_LABEL)) {
|
||||
int i = indexOfNonWhiteSpace(line, NAMESERVER_ROW_LABEL.length());
|
||||
if (i < 0) {
|
||||
throw new IllegalArgumentException("error parsing label " + NAMESERVER_ROW_LABEL +
|
||||
@ -214,7 +221,7 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
}
|
||||
domainName = line.substring(i);
|
||||
if (!addresses.isEmpty()) {
|
||||
putIfAbsent(domainToNameServerStreamMap, domainName, addresses);
|
||||
putIfAbsent(domainToNameServerStreamMap, domainName, addresses, rotate);
|
||||
}
|
||||
addresses = new ArrayList<>(2);
|
||||
} else if (line.startsWith(PORT_ROW_LABEL)) {
|
||||
@ -232,7 +239,7 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
}
|
||||
}
|
||||
if (!addresses.isEmpty()) {
|
||||
putIfAbsent(domainToNameServerStreamMap, domainName, addresses);
|
||||
putIfAbsent(domainToNameServerStreamMap, domainName, addresses, rotate);
|
||||
}
|
||||
} finally {
|
||||
if (br == null) {
|
||||
@ -247,9 +254,13 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
|
||||
private static void putIfAbsent(Map<String, DnsServerAddresses> domainToNameServerStreamMap,
|
||||
String domainName,
|
||||
List<InetSocketAddress> addresses) {
|
||||
List<InetSocketAddress> addresses,
|
||||
boolean rotate) {
|
||||
// TODO(scott): sortlist is being ignored.
|
||||
putIfAbsent(domainToNameServerStreamMap, domainName, DnsServerAddresses.sequential(addresses));
|
||||
DnsServerAddresses addrs = rotate
|
||||
? DnsServerAddresses.rotational(addresses)
|
||||
: DnsServerAddresses.sequential(addresses);
|
||||
putIfAbsent(domainToNameServerStreamMap, domainName, addrs);
|
||||
}
|
||||
|
||||
private static void putIfAbsent(Map<String, DnsServerAddresses> domainToNameServerStreamMap,
|
||||
@ -266,25 +277,25 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a file of the format <a href="https://linux.die.net/man/5/resolver">/etc/resolv.conf</a> and return the
|
||||
* value corresponding to the first ndots in an options configuration.
|
||||
* @return the value corresponding to the first ndots in an options configuration, or {@link #DEFAULT_NDOTS} if not
|
||||
* found.
|
||||
* Parse <a href="https://linux.die.net/man/5/resolver">/etc/resolv.conf</a> and return options of interest, namely:
|
||||
* timeout, attempts and ndots.
|
||||
* @return The options values provided by /etc/resolve.conf.
|
||||
* @throws IOException If a failure occurs parsing the file.
|
||||
*/
|
||||
static int parseEtcResolverFirstNdots() throws IOException {
|
||||
return parseEtcResolverFirstNdots(new File(ETC_RESOLV_CONF_FILE));
|
||||
static UnixResolverOptions parseEtcResolverOptions() throws IOException {
|
||||
return parseEtcResolverOptions(new File(ETC_RESOLV_CONF_FILE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a file of the format <a href="https://linux.die.net/man/5/resolver">/etc/resolv.conf</a> and return the
|
||||
* value corresponding to the first ndots in an options configuration.
|
||||
* Parse a file of the format <a href="https://linux.die.net/man/5/resolver">/etc/resolv.conf</a> and return options
|
||||
* of interest, namely: timeout, attempts and ndots.
|
||||
* @param etcResolvConf a file of the format <a href="https://linux.die.net/man/5/resolver">/etc/resolv.conf</a>.
|
||||
* @return the value corresponding to the first ndots in an options configuration, or {@link #DEFAULT_NDOTS} if not
|
||||
* found.
|
||||
* @return The options values provided by /etc/resolve.conf.
|
||||
* @throws IOException If a failure occurs parsing the file.
|
||||
*/
|
||||
static int parseEtcResolverFirstNdots(File etcResolvConf) throws IOException {
|
||||
static UnixResolverOptions parseEtcResolverOptions(File etcResolvConf) throws IOException {
|
||||
UnixResolverOptions.Builder optionsBuilder = UnixResolverOptions.newBuilder();
|
||||
|
||||
FileReader fr = new FileReader(etcResolvConf);
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
@ -292,12 +303,7 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (line.startsWith(OPTIONS_ROW_LABEL)) {
|
||||
int i = line.indexOf(NDOTS_LABEL);
|
||||
if (i >= 0) {
|
||||
i += NDOTS_LABEL.length();
|
||||
final int j = line.indexOf(' ', i);
|
||||
return Integer.parseInt(line.substring(i, j < 0 ? line.length() : j));
|
||||
}
|
||||
parseResOptions(line.substring(OPTIONS_ROW_LABEL.length()), optionsBuilder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -308,7 +314,35 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
br.close();
|
||||
}
|
||||
}
|
||||
return DEFAULT_NDOTS;
|
||||
|
||||
// amend options
|
||||
if (RES_OPTIONS != null) {
|
||||
parseResOptions(RES_OPTIONS, optionsBuilder);
|
||||
}
|
||||
|
||||
return optionsBuilder.build();
|
||||
}
|
||||
|
||||
private static void parseResOptions(String line, UnixResolverOptions.Builder builder) {
|
||||
String[] opts = WHITESPACE_PATTERN.split(line);
|
||||
for (String opt : opts) {
|
||||
try {
|
||||
if (opt.startsWith("ndots:")) {
|
||||
builder.setNdots(parseResIntOption(opt, "ndots:"));
|
||||
} else if (opt.startsWith("attempts:")) {
|
||||
builder.setAttempts(parseResIntOption(opt, "attempts:"));
|
||||
} else if (opt.startsWith("timeout:")) {
|
||||
builder.setTimeout(parseResIntOption(opt, "timeout:"));
|
||||
}
|
||||
} catch (NumberFormatException ignore) {
|
||||
// skip bad int values from resolv.conf to keep value already set in UnixResolverOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int parseResIntOption(String opt, String fullLabel) {
|
||||
String optValue = opt.substring(fullLabel.length());
|
||||
return Integer.parseInt(optValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -348,7 +382,7 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
if (i >= 0) {
|
||||
// May contain more then one entry, either seperated by whitespace or tab.
|
||||
// See https://linux.die.net/man/5/resolver
|
||||
String[] domains = SEARCH_DOMAIN_PATTERN.split(line.substring(i));
|
||||
String[] domains = WHITESPACE_PATTERN.split(line.substring(i));
|
||||
Collections.addAll(searchDomains, domains);
|
||||
}
|
||||
}
|
||||
@ -366,4 +400,5 @@ public final class UnixResolverDnsServerAddressStreamProvider implements DnsServ
|
||||
? Collections.singletonList(localDomain)
|
||||
: searchDomains;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2020 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.resolver.dns;
|
||||
|
||||
/**
|
||||
* Represents options defined in a file of the format <a href=https://linux.die.net/man/5/resolver>etc/resolv.conf</a>.
|
||||
*/
|
||||
final class UnixResolverOptions {
|
||||
|
||||
private final int ndots;
|
||||
private final int timeout;
|
||||
private final int attempts;
|
||||
|
||||
UnixResolverOptions(int ndots, int timeout, int attempts) {
|
||||
this.ndots = ndots;
|
||||
this.timeout = timeout;
|
||||
this.attempts = attempts;
|
||||
}
|
||||
|
||||
static UnixResolverOptions.Builder newBuilder() {
|
||||
return new UnixResolverOptions.Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of dots which must appear in a name before an initial absolute query is made.
|
||||
* The default value is {@code 1}.
|
||||
*/
|
||||
int ndots() {
|
||||
return ndots;
|
||||
}
|
||||
|
||||
/**
|
||||
* The timeout of each DNS query performed by this resolver (in seconds).
|
||||
* The default value is {@code 5}.
|
||||
*/
|
||||
int timeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum allowed number of DNS queries to send when resolving a host name.
|
||||
* The default value is {@code 16}.
|
||||
*/
|
||||
int attempts() {
|
||||
return attempts;
|
||||
}
|
||||
|
||||
static final class Builder {
|
||||
|
||||
private int ndots = 1;
|
||||
private int timeout = 5;
|
||||
private int attempts = 16;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
void setNdots(int ndots) {
|
||||
this.ndots = ndots;
|
||||
}
|
||||
|
||||
void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
void setAttempts(int attempts) {
|
||||
this.attempts = attempts;
|
||||
}
|
||||
|
||||
UnixResolverOptions build() {
|
||||
return new UnixResolverOptions(ndots, timeout, attempts);
|
||||
}
|
||||
}
|
||||
}
|
@ -29,8 +29,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider.DEFAULT_NDOTS;
|
||||
import static io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider.parseEtcResolverFirstNdots;
|
||||
import static io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider.parseEtcResolverOptions;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class UnixResolverDnsServerAddressStreamProviderTest {
|
||||
@ -50,6 +49,62 @@ public class UnixResolverDnsServerAddressStreamProviderTest {
|
||||
assertHostNameEquals("127.0.0.3", stream.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameServerAddressStreamShouldBeRotationalWhenRotationOptionsIsPresent() throws Exception {
|
||||
File f = buildFile("options rotate\n" +
|
||||
"domain linecorp.local\n" +
|
||||
"nameserver 127.0.0.2\n" +
|
||||
"nameserver 127.0.0.3\n" +
|
||||
"nameserver 127.0.0.4\n");
|
||||
UnixResolverDnsServerAddressStreamProvider p =
|
||||
new UnixResolverDnsServerAddressStreamProvider(f, null);
|
||||
|
||||
DnsServerAddressStream stream = p.nameServerAddressStream("");
|
||||
assertHostNameEquals("127.0.0.2", stream.next());
|
||||
assertHostNameEquals("127.0.0.3", stream.next());
|
||||
assertHostNameEquals("127.0.0.4", stream.next());
|
||||
|
||||
stream = p.nameServerAddressStream("");
|
||||
assertHostNameEquals("127.0.0.3", stream.next());
|
||||
assertHostNameEquals("127.0.0.4", stream.next());
|
||||
assertHostNameEquals("127.0.0.2", stream.next());
|
||||
|
||||
stream = p.nameServerAddressStream("");
|
||||
assertHostNameEquals("127.0.0.4", stream.next());
|
||||
assertHostNameEquals("127.0.0.2", stream.next());
|
||||
assertHostNameEquals("127.0.0.3", stream.next());
|
||||
|
||||
stream = p.nameServerAddressStream("");
|
||||
assertHostNameEquals("127.0.0.2", stream.next());
|
||||
assertHostNameEquals("127.0.0.3", stream.next());
|
||||
assertHostNameEquals("127.0.0.4", stream.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameServerAddressStreamShouldAlwaysStartFromTheTopWhenRotationOptionsIsAbsent() throws Exception {
|
||||
File f = buildFile("domain linecorp.local\n" +
|
||||
"nameserver 127.0.0.2\n" +
|
||||
"nameserver 127.0.0.3\n" +
|
||||
"nameserver 127.0.0.4\n");
|
||||
UnixResolverDnsServerAddressStreamProvider p =
|
||||
new UnixResolverDnsServerAddressStreamProvider(f, null);
|
||||
|
||||
DnsServerAddressStream stream = p.nameServerAddressStream("");
|
||||
assertHostNameEquals("127.0.0.2", stream.next());
|
||||
assertHostNameEquals("127.0.0.3", stream.next());
|
||||
assertHostNameEquals("127.0.0.4", stream.next());
|
||||
|
||||
stream = p.nameServerAddressStream("");
|
||||
assertHostNameEquals("127.0.0.2", stream.next());
|
||||
assertHostNameEquals("127.0.0.3", stream.next());
|
||||
assertHostNameEquals("127.0.0.4", stream.next());
|
||||
|
||||
stream = p.nameServerAddressStream("");
|
||||
assertHostNameEquals("127.0.0.2", stream.next());
|
||||
assertHostNameEquals("127.0.0.3", stream.next());
|
||||
assertHostNameEquals("127.0.0.4", stream.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultReturnedWhenNoBetterMatch() throws Exception {
|
||||
File f = buildFile("domain linecorp.local\n" +
|
||||
@ -83,23 +138,63 @@ public class UnixResolverDnsServerAddressStreamProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ndotsIsParsedIfPresent() throws IOException {
|
||||
public void ndotsOptionIsParsedIfPresent() throws IOException {
|
||||
File f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n" +
|
||||
"options ndots:0\n");
|
||||
assertEquals(0, parseEtcResolverFirstNdots(f));
|
||||
"nameserver 127.0.0.11\n" +
|
||||
"options ndots:0\n");
|
||||
assertEquals(0, parseEtcResolverOptions(f).ndots());
|
||||
|
||||
f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n" +
|
||||
"options ndots:123 foo:goo\n");
|
||||
assertEquals(123, parseEtcResolverFirstNdots(f));
|
||||
"nameserver 127.0.0.11\n" +
|
||||
"options ndots:123 foo:goo\n");
|
||||
assertEquals(123, parseEtcResolverOptions(f).ndots());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultValueReturnedIfNdotsNotPresent() throws IOException {
|
||||
public void defaultValueReturnedIfNdotsOptionsNotPresent() throws IOException {
|
||||
File f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n");
|
||||
assertEquals(DEFAULT_NDOTS, parseEtcResolverFirstNdots(f));
|
||||
"nameserver 127.0.0.11\n");
|
||||
assertEquals(1, parseEtcResolverOptions(f).ndots());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void timeoutOptionIsParsedIfPresent() throws IOException {
|
||||
File f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n" +
|
||||
"options timeout:0\n");
|
||||
assertEquals(0, parseEtcResolverOptions(f).timeout());
|
||||
|
||||
f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n" +
|
||||
"options foo:bar timeout:124\n");
|
||||
assertEquals(124, parseEtcResolverOptions(f).timeout());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultValueReturnedIfTimeoutOptionsIsNotPresent() throws IOException {
|
||||
File f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n");
|
||||
assertEquals(5, parseEtcResolverOptions(f).timeout());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attemptsOptionIsParsedIfPresent() throws IOException {
|
||||
File f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n" +
|
||||
"options attempts:0\n");
|
||||
assertEquals(0, parseEtcResolverOptions(f).attempts());
|
||||
|
||||
f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n" +
|
||||
"options foo:bar attempts:12\n");
|
||||
assertEquals(12, parseEtcResolverOptions(f).attempts());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultValueReturnedIfAttemptsOptionsIsNotPresent() throws IOException {
|
||||
File f = buildFile("search localdomain\n" +
|
||||
"nameserver 127.0.0.11\n");
|
||||
assertEquals(16, parseEtcResolverOptions(f).attempts());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user