View Javadoc
1   /*
2    * Copyright 2018 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty5.resolver.dns;
17  
18  import io.netty5.channel.EventLoop;
19  import io.netty5.handler.codec.dns.DnsRecord;
20  import io.netty5.handler.codec.dns.DnsRecordType;
21  import io.netty5.util.concurrent.Promise;
22  
23  import java.net.InetAddress;
24  import java.net.UnknownHostException;
25  import java.util.List;
26  
27  import static io.netty5.resolver.dns.DnsAddressDecoder.decodeAddress;
28  import static io.netty5.util.NetUtil.isFamilySupported;
29  
30  final class DnsAddressResolveContext extends DnsResolveContext<InetAddress> {
31  
32      private final DnsCache resolveCache;
33      private final AuthoritativeDnsServerCache authoritativeDnsServerCache;
34      private final boolean completeEarlyIfPossible;
35  
36      DnsAddressResolveContext(DnsNameResolver parent, Promise<?> originalPromise,
37                               String hostname, DnsRecord[] additionals,
38                               DnsServerAddressStream nameServerAddrs, int allowedQueries, DnsCache resolveCache,
39                               AuthoritativeDnsServerCache authoritativeDnsServerCache,
40                               boolean completeEarlyIfPossible) {
41          super(parent, originalPromise, hostname, DnsRecord.CLASS_IN,
42                parent.resolveRecordTypes(), additionals, nameServerAddrs, allowedQueries);
43          this.resolveCache = resolveCache;
44          this.authoritativeDnsServerCache = authoritativeDnsServerCache;
45          this.completeEarlyIfPossible = completeEarlyIfPossible;
46      }
47  
48      @Override
49      DnsResolveContext<InetAddress> newResolverContext(DnsNameResolver parent, Promise<?> originalPromise,
50                                                        String hostname,
51                                                        int dnsClass, DnsRecordType[] expectedTypes,
52                                                        DnsRecord[] additionals,
53                                                        DnsServerAddressStream nameServerAddrs, int allowedQueries) {
54          return new DnsAddressResolveContext(parent, originalPromise, hostname, additionals, nameServerAddrs,
55                  allowedQueries, resolveCache, authoritativeDnsServerCache, completeEarlyIfPossible);
56      }
57  
58      @Override
59      InetAddress convertRecord(DnsRecord record, String hostname, DnsRecord[] additionals, EventLoop eventLoop) {
60          return decodeAddress(record, hostname, parent.isDecodeIdn());
61      }
62  
63      @Override
64      List<InetAddress> filterResults(List<InetAddress> unfiltered) {
65          unfiltered.sort(PreferredAddressTypeComparator.comparator(parent.preferredAddressType()));
66          return unfiltered;
67      }
68  
69      @Override
70      boolean isCompleteEarly(InetAddress resolved) {
71          return completeEarlyIfPossible && isFamilySupported(resolved, parent.preferredAddressType());
72      }
73  
74      @Override
75      boolean isDuplicateAllowed() {
76          // We don't want include duplicates to mimic JDK behaviour.
77          return false;
78      }
79  
80      @Override
81      void cache(String hostname, DnsRecord[] additionals,
82                 DnsRecord result, InetAddress convertedResult) {
83          resolveCache.cache(hostname, additionals, convertedResult, result.timeToLive(), parent.ch.executor());
84      }
85  
86      @Override
87      void cache(String hostname, DnsRecord[] additionals, UnknownHostException cause) {
88          resolveCache.cache(hostname, additionals, cause, parent.ch.executor());
89      }
90  
91      @Override
92      void doSearchDomainQuery(String hostname, Promise<List<InetAddress>> nextPromise) {
93          // Query the cache for the hostname first and only do a query if we could not find it in the cache.
94          if (!DnsNameResolver.doResolveAllCached(
95                  hostname, additionals, nextPromise, resolveCache, parent.resolvedProtocolFamiliesUnsafe())) {
96              super.doSearchDomainQuery(hostname, nextPromise);
97          }
98      }
99  
100     @Override
101     DnsCache resolveCache() {
102         return resolveCache;
103     }
104 
105     @Override
106     AuthoritativeDnsServerCache authoritativeDnsServerCache() {
107         return authoritativeDnsServerCache;
108     }
109 }