|
35 | 35 | import io.netty.handler.codec.dns.DnsRecord;
|
36 | 36 | import io.netty.handler.codec.dns.DatagramDnsResponseDecoder;
|
37 | 37 | import io.netty.handler.codec.dns.DnsQuestion;
|
| 38 | +import io.netty.handler.codec.dns.DnsRecordType; |
38 | 39 | import io.netty.handler.codec.dns.DnsResponse;
|
39 | 40 | import io.netty.resolver.HostsFileEntriesResolver;
|
40 | 41 | import io.netty.resolver.InetNameResolver;
|
|
59 | 60 | import java.util.Collection;
|
60 | 61 | import java.util.Collections;
|
61 | 62 | import java.util.Iterator;
|
| 63 | +import java.util.LinkedHashSet; |
62 | 64 | import java.util.List;
|
| 65 | +import java.util.Set; |
63 | 66 |
|
64 | 67 | import static io.netty.util.internal.ObjectUtil2.*;
|
65 | 68 |
|
@@ -148,6 +151,10 @@ protected DnsServerAddressStream initialValue() throws Exception {
|
148 | 151 | private final HostsFileEntriesResolver hostsFileEntriesResolver;
|
149 | 152 | private final String[] searchDomains;
|
150 | 153 | private final int ndots;
|
| 154 | + private final boolean cnameFollowARecords; |
| 155 | + private final boolean cnameFollowAAAARecords; |
| 156 | + private final InternetProtocolFamily2 preferredAddressType; |
| 157 | + private final DnsRecordType[] resolveRecordTypes; |
151 | 158 |
|
152 | 159 | /**
|
153 | 160 | * Creates a new DNS-based name resolver that communicates with the specified list of DNS servers.
|
@@ -200,6 +207,32 @@ public DnsNameResolver(
|
200 | 207 | this.searchDomains = checkNotNull(searchDomains, "searchDomains").clone();
|
201 | 208 | this.ndots = checkPositiveOrZero(ndots, "ndots");
|
202 | 209 |
|
| 210 | + boolean cnameFollowARecords = false; |
| 211 | + boolean cnameFollowAAAARecords = false; |
| 212 | + // Use LinkedHashSet to maintain correct ordering. |
| 213 | + Set<DnsRecordType> recordTypes = new LinkedHashSet<DnsRecordType>(resolvedAddressTypes.length); |
| 214 | + for (InternetProtocolFamily2 family: resolvedAddressTypes) { |
| 215 | + switch (family) { |
| 216 | + case IPv4: |
| 217 | + cnameFollowARecords = true; |
| 218 | + recordTypes.add(DnsRecordType.A); |
| 219 | + break; |
| 220 | + case IPv6: |
| 221 | + cnameFollowAAAARecords = true; |
| 222 | + recordTypes.add(DnsRecordType.AAAA); |
| 223 | + break; |
| 224 | + default: |
| 225 | + throw new Error(); |
| 226 | + } |
| 227 | + } |
| 228 | + |
| 229 | + // One of both must be always true. |
| 230 | + assert cnameFollowARecords || cnameFollowAAAARecords; |
| 231 | + this.cnameFollowAAAARecords = cnameFollowAAAARecords; |
| 232 | + this.cnameFollowARecords = cnameFollowARecords; |
| 233 | + resolveRecordTypes = recordTypes.toArray(new DnsRecordType[recordTypes.size()]); |
| 234 | + preferredAddressType = resolvedAddressTypes[0]; |
| 235 | + |
203 | 236 | Bootstrap b = new Bootstrap();
|
204 | 237 | b.group(executor());
|
205 | 238 | b.channelFactory(channelFactory);
|
@@ -260,6 +293,22 @@ final int ndots() {
|
260 | 293 | return ndots;
|
261 | 294 | }
|
262 | 295 |
|
| 296 | + final boolean isCnameFollowAAAARecords() { |
| 297 | + return cnameFollowAAAARecords; |
| 298 | + } |
| 299 | + |
| 300 | + final boolean isCnameFollowARecords() { |
| 301 | + return cnameFollowARecords; |
| 302 | + } |
| 303 | + |
| 304 | + final InternetProtocolFamily2 preferredAddressType() { |
| 305 | + return preferredAddressType; |
| 306 | + } |
| 307 | + |
| 308 | + final DnsRecordType[] resolveRecordTypes() { |
| 309 | + return resolveRecordTypes; |
| 310 | + } |
| 311 | + |
263 | 312 | /**
|
264 | 313 | * Returns {@code true} if and only if this resolver sends a DNS query with the RD (recursion desired) flag set.
|
265 | 314 | * The default value is {@code true}.
|
|
0 commit comments