netty5/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java

827 lines
32 KiB
Java
Raw Normal View History

/*
* Copyright 2014 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;
import io.netty.bootstrap.Bootstrap;
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
import io.netty.channel.AddressedEnvelope;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoop;
import io.netty.channel.FixedRecvByteBufAllocator;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.InternetProtocolFamily;
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
import io.netty.handler.codec.dns.DatagramDnsQueryEncoder;
import io.netty.handler.codec.dns.DatagramDnsResponse;
import io.netty.handler.codec.dns.DnsRawRecord;
import io.netty.handler.codec.dns.DnsRecord;
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
import io.netty.handler.codec.dns.DatagramDnsResponseDecoder;
import io.netty.handler.codec.dns.DnsQuestion;
import io.netty.handler.codec.dns.DnsResponse;
import io.netty.resolver.HostsFileEntriesResolver;
import io.netty.resolver.InetNameResolver;
import io.netty.util.NetUtil;
import io.netty.util.ReferenceCountUtil;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.Promise;
import io.netty.util.internal.EmptyArrays;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.StringUtil;
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.IDN;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import static io.netty.util.internal.ObjectUtil.*;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
/**
* A DNS-based {@link InetNameResolver}.
*/
@UnstableApi
public class DnsNameResolver extends InetNameResolver {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsNameResolver.class);
private static final String LOCALHOST = "localhost";
private static final InetAddress LOCALHOST_ADDRESS;
private static final DnsRecord[] EMTPY_ADDITIONALS = new DnsRecord[0];
static final InternetProtocolFamily[] DEFAULT_RESOLVE_ADDRESS_TYPES;
static final String[] DEFAULT_SEACH_DOMAINS;
static {
if (NetUtil.isIpV4StackPreferred()) {
DEFAULT_RESOLVE_ADDRESS_TYPES = new InternetProtocolFamily[] { InternetProtocolFamily.IPv4 };
LOCALHOST_ADDRESS = NetUtil.LOCALHOST4;
} else {
DEFAULT_RESOLVE_ADDRESS_TYPES = new InternetProtocolFamily[2];
if (NetUtil.isIpV6AddressesPreferred()) {
DEFAULT_RESOLVE_ADDRESS_TYPES[0] = InternetProtocolFamily.IPv6;
DEFAULT_RESOLVE_ADDRESS_TYPES[1] = InternetProtocolFamily.IPv4;
LOCALHOST_ADDRESS = NetUtil.LOCALHOST6;
} else {
DEFAULT_RESOLVE_ADDRESS_TYPES[0] = InternetProtocolFamily.IPv4;
DEFAULT_RESOLVE_ADDRESS_TYPES[1] = InternetProtocolFamily.IPv6;
LOCALHOST_ADDRESS = NetUtil.LOCALHOST4;
}
}
}
static {
String[] searchDomains;
try {
Class<?> configClass = Class.forName("sun.net.dns.ResolverConfiguration");
Method open = configClass.getMethod("open");
Method nameservers = configClass.getMethod("searchlist");
Object instance = open.invoke(null);
@SuppressWarnings("unchecked")
List<String> list = (List<String>) nameservers.invoke(instance);
searchDomains = list.toArray(new String[list.size()]);
} catch (Exception ignore) {
// Failed to get the system name search domain list.
searchDomains = EmptyArrays.EMPTY_STRINGS;
}
DEFAULT_SEACH_DOMAINS = searchDomains;
}
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
private static final DatagramDnsResponseDecoder DECODER = new DatagramDnsResponseDecoder();
private static final DatagramDnsQueryEncoder ENCODER = new DatagramDnsQueryEncoder();
final DnsServerAddresses nameServerAddresses;
final Future<Channel> channelFuture;
final DatagramChannel ch;
/**
* Manages the {@link DnsQueryContext}s in progress and their query IDs.
*/
final DnsQueryContextManager queryContextManager = new DnsQueryContextManager();
/**
* Cache for {@link #doResolve(String, Promise)} and {@link #doResolveAll(String, Promise)}.
*/
private final DnsCache resolveCache;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
private final FastThreadLocal<DnsServerAddressStream> nameServerAddrStream =
new FastThreadLocal<DnsServerAddressStream>() {
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
@Override
protected DnsServerAddressStream initialValue() throws Exception {
return nameServerAddresses.stream();
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
};
private final long queryTimeoutMillis;
private final int maxQueriesPerResolve;
private final boolean traceEnabled;
private final InternetProtocolFamily[] resolvedAddressTypes;
private final boolean recursionDesired;
private final int maxPayloadSize;
private final boolean optResourceEnabled;
private final HostsFileEntriesResolver hostsFileEntriesResolver;
private final String[] searchDomains;
private final int ndots;
/**
* Creates a new DNS-based name resolver that communicates with the specified list of DNS servers.
*
* @param eventLoop the {@link EventLoop} which will perform the communication with the DNS servers
* @param channelFactory the {@link ChannelFactory} that will create a {@link DatagramChannel}
* @param nameServerAddresses the addresses of the DNS server. For each DNS query, a new stream is created from
* this to determine which DNS server should be contacted for the next retry in case
* of failure.
* @param resolveCache the DNS resolved entries cache
* @param queryTimeoutMillis timeout of each DNS query in millis
* @param resolvedAddressTypes list of the protocol families
* @param recursionDesired if recursion desired flag must be set
* @param maxQueriesPerResolve the maximum allowed number of DNS queries for a given name resolution
* @param traceEnabled if trace is enabled
* @param maxPayloadSize the capacity of the datagram packet buffer
* @param optResourceEnabled if automatic inclusion of a optional records is enabled
* @param hostsFileEntriesResolver the {@link HostsFileEntriesResolver} used to check for local aliases
* @param searchDomains the list of search domain
* @param ndots the ndots value
*/
public DnsNameResolver(
EventLoop eventLoop,
ChannelFactory<? extends DatagramChannel> channelFactory,
DnsServerAddresses nameServerAddresses,
final DnsCache resolveCache,
long queryTimeoutMillis,
InternetProtocolFamily[] resolvedAddressTypes,
boolean recursionDesired,
int maxQueriesPerResolve,
boolean traceEnabled,
int maxPayloadSize,
boolean optResourceEnabled,
HostsFileEntriesResolver hostsFileEntriesResolver,
String[] searchDomains,
int ndots) {
super(eventLoop);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
checkNotNull(channelFactory, "channelFactory");
this.nameServerAddresses = checkNotNull(nameServerAddresses, "nameServerAddresses");
this.queryTimeoutMillis = checkPositive(queryTimeoutMillis, "queryTimeoutMillis");
this.resolvedAddressTypes = checkNonEmpty(resolvedAddressTypes, "resolvedAddressTypes");
this.recursionDesired = recursionDesired;
this.maxQueriesPerResolve = checkPositive(maxQueriesPerResolve, "maxQueriesPerResolve");
this.traceEnabled = traceEnabled;
this.maxPayloadSize = checkPositive(maxPayloadSize, "maxPayloadSize");
this.optResourceEnabled = optResourceEnabled;
this.hostsFileEntriesResolver = checkNotNull(hostsFileEntriesResolver, "hostsFileEntriesResolver");
this.resolveCache = resolveCache;
this.searchDomains = checkNotNull(searchDomains, "searchDomains").clone();
this.ndots = checkPositiveOrZero(ndots, "ndots");
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
Bootstrap b = new Bootstrap();
b.group(executor());
b.channelFactory(channelFactory);
b.option(ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION, true);
final DnsResponseHandler responseHandler = new DnsResponseHandler(executor().<Channel>newPromise());
b.handler(new ChannelInitializer<DatagramChannel>() {
@Override
protected void initChannel(DatagramChannel ch) throws Exception {
ch.pipeline().addLast(DECODER, ENCODER, responseHandler);
}
});
channelFuture = responseHandler.channelActivePromise;
ch = (DatagramChannel) b.register().channel();
ch.config().setRecvByteBufAllocator(new FixedRecvByteBufAllocator(maxPayloadSize));
ch.closeFuture().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
resolveCache.clear();
}
});
}
/**
* Returns the resolution cache.
*/
public DnsCache resolveCache() {
return resolveCache;
}
/**
* Returns the timeout of each DNS query performed by this resolver (in milliseconds).
* The default value is 5 seconds.
*/
public long queryTimeoutMillis() {
return queryTimeoutMillis;
}
/**
* Returns the list of the protocol families of the address resolved by {@link #resolve(String)}
* in the order of preference.
* The default value depends on the value of the system property {@code "java.net.preferIPv6Addresses"}.
*/
public List<InternetProtocolFamily> resolvedAddressTypes() {
return Arrays.asList(resolvedAddressTypes);
}
InternetProtocolFamily[] resolveAddressTypesUnsafe() {
return resolvedAddressTypes;
}
final String[] searchDomains() {
return searchDomains;
}
final int ndots() {
return ndots;
}
/**
* Returns {@code true} if and only if this resolver sends a DNS query with the RD (recursion desired) flag set.
* The default value is {@code true}.
*/
public boolean isRecursionDesired() {
return recursionDesired;
}
/**
* Returns the maximum allowed number of DNS queries to send when resolving a host name.
* The default value is {@code 8}.
*/
public int maxQueriesPerResolve() {
return maxQueriesPerResolve;
}
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
/**
* Returns if this resolver should generate the detailed trace information in an exception message so that
* it is easier to understand the cause of resolution failure. The default value if {@code true}.
*/
public boolean isTraceEnabled() {
return traceEnabled;
}
/**
* Returns the capacity of the datagram packet buffer (in bytes). The default value is {@code 4096} bytes.
*/
public int maxPayloadSize() {
return maxPayloadSize;
}
/**
* Returns the automatic inclusion of a optional records that tries to give the remote DNS server a hint about how
* much data the resolver can read per response is enabled.
*/
public boolean isOptResourceEnabled() {
return optResourceEnabled;
}
/**
* Returns the component that tries to resolve hostnames against the hosts file prior to asking to
* remotes DNS servers.
*/
public HostsFileEntriesResolver hostsFileEntriesResolver() {
return hostsFileEntriesResolver;
}
/**
* Closes the internal datagram channel used for sending and receiving DNS messages, and clears all DNS resource
* records from the cache. Attempting to send a DNS query or to resolve a domain name will fail once this method
* has been called.
*/
@Override
public void close() {
if (ch.isOpen()) {
ch.close();
}
}
@Override
protected EventLoop executor() {
return (EventLoop) super.executor();
}
private InetAddress resolveHostsFileEntry(String hostname) {
if (hostsFileEntriesResolver == null) {
return null;
} else {
InetAddress address = hostsFileEntriesResolver.address(hostname);
if (address == null && PlatformDependent.isWindows() && LOCALHOST.equalsIgnoreCase(hostname)) {
// If we tried to resolve localhost we need workaround that windows removed localhost from its
// hostfile in later versions.
// See https://github.com/netty/netty/issues/5386
return LOCALHOST_ADDRESS;
}
return address;
}
}
/**
* Resolves the specified name into an address.
*
* @param inetHost the name to resolve
* @param additionals additional records ({@code OPT})
*
* @return the address as the result of the resolution
*/
public final Future<InetAddress> resolve(String inetHost, Iterable<DnsRecord> additionals) {
return resolve(inetHost, additionals, executor().<InetAddress>newPromise());
}
/**
* Resolves the specified name into an address.
*
* @param inetHost the name to resolve
* @param additionals additional records ({@code OPT})
* @param promise the {@link Promise} which will be fulfilled when the name resolution is finished
*
* @return the address as the result of the resolution
*/
public final Future<InetAddress> resolve(String inetHost, Iterable<DnsRecord> additionals,
Promise<InetAddress> promise) {
checkNotNull(inetHost, "inetHost");
checkNotNull(promise, "promise");
DnsRecord[] additionalsArray = toArray(additionals, true);
try {
doResolve(inetHost, additionalsArray, promise, resolveCache);
return promise;
} catch (Exception e) {
return promise.setFailure(e);
}
}
/**
* Resolves the specified host name and port into a list of address.
*
* @param inetHost the name to resolve
* @param additionals additional records ({@code OPT})
*
* @return the list of the address as the result of the resolution
*/
public final Future<List<InetAddress>> resolveAll(String inetHost, Iterable<DnsRecord> additionals) {
return resolveAll(inetHost, additionals, executor().<List<InetAddress>>newPromise());
}
/**
* Resolves the specified host name and port into a list of address.
*
* @param inetHost the name to resolve
* @param additionals additional records ({@code OPT})
* @param promise the {@link Promise} which will be fulfilled when the name resolution is finished
*
* @return the list of the address as the result of the resolution
*/
public final Future<List<InetAddress>> resolveAll(String inetHost, Iterable<DnsRecord> additionals,
Promise<List<InetAddress>> promise) {
checkNotNull(inetHost, "inetHost");
checkNotNull(promise, "promise");
DnsRecord[] additionalsArray = toArray(additionals, true);
try {
doResolveAll(inetHost, additionalsArray, promise, resolveCache);
return promise;
} catch (Exception e) {
return promise.setFailure(e);
}
}
@Override
protected void doResolve(String inetHost, Promise<InetAddress> promise) throws Exception {
doResolve(inetHost, EMTPY_ADDITIONALS, promise, resolveCache);
}
private static DnsRecord[] toArray(Iterable<DnsRecord> additionals, boolean validateType) {
checkNotNull(additionals, "additionals");
if (additionals instanceof Collection) {
Collection<DnsRecord> records = (Collection<DnsRecord>) additionals;
for (DnsRecord r: additionals) {
validateAdditional(r, validateType);
}
return records.toArray(new DnsRecord[records.size()]);
}
Iterator<DnsRecord> additionalsIt = additionals.iterator();
if (!additionalsIt.hasNext()) {
return EMTPY_ADDITIONALS;
}
List<DnsRecord> records = new ArrayList<DnsRecord>();
do {
DnsRecord r = additionalsIt.next();
validateAdditional(r, validateType);
records.add(r);
} while (additionalsIt.hasNext());
return records.toArray(new DnsRecord[records.size()]);
}
private static void validateAdditional(DnsRecord record, boolean validateType) {
checkNotNull(record, "record");
if (validateType && record instanceof DnsRawRecord) {
throw new IllegalArgumentException("DnsRawRecord implementations not allowed: " + record);
}
}
/**
* Hook designed for extensibility so one can pass a different cache on each resolution attempt
* instead of using the global one.
*/
protected void doResolve(String inetHost,
DnsRecord[] additionals,
Promise<InetAddress> promise,
DnsCache resolveCache) throws Exception {
final byte[] bytes = NetUtil.createByteArrayFromIpAddressString(inetHost);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
if (bytes != null) {
// The inetHost is actually an ipaddress.
promise.setSuccess(InetAddress.getByAddress(bytes));
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
return;
}
final String hostname = hostname(inetHost);
InetAddress hostsFileEntry = resolveHostsFileEntry(hostname);
if (hostsFileEntry != null) {
promise.setSuccess(hostsFileEntry);
return;
}
if (!doResolveCached(hostname, additionals, promise, resolveCache)) {
doResolveUncached(hostname, additionals, promise, resolveCache);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
}
private boolean doResolveCached(String hostname,
DnsRecord[] additionals,
Promise<InetAddress> promise,
DnsCache resolveCache) {
final List<DnsCacheEntry> cachedEntries = resolveCache.get(hostname, additionals);
if (cachedEntries == null || cachedEntries.isEmpty()) {
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
return false;
}
InetAddress address = null;
Throwable cause = null;
synchronized (cachedEntries) {
final int numEntries = cachedEntries.size();
assert numEntries > 0;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
if (cachedEntries.get(0).cause() != null) {
cause = cachedEntries.get(0).cause();
} else {
// Find the first entry with the preferred address type.
for (InternetProtocolFamily f : resolvedAddressTypes) {
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
for (int i = 0; i < numEntries; i++) {
final DnsCacheEntry e = cachedEntries.get(i);
if (f.addressType().isInstance(e.address())) {
address = e.address();
break;
}
}
}
}
}
if (address != null) {
trySuccess(promise, address);
return true;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
if (cause != null) {
tryFailure(promise, cause);
return true;
}
return false;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
private static <T> void trySuccess(Promise<T> promise, T result) {
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
if (!promise.trySuccess(result)) {
logger.warn("Failed to notify success ({}) to a promise: {}", result, promise);
}
}
private static void tryFailure(Promise<?> promise, Throwable cause) {
if (!promise.tryFailure(cause)) {
logger.warn("Failed to notify failure to a promise: {}", promise, cause);
}
}
private void doResolveUncached(String hostname,
DnsRecord[] additionals,
Promise<InetAddress> promise,
DnsCache resolveCache) {
SingleResolverContext ctx = new SingleResolverContext(this, hostname, additionals, resolveCache);
ctx.resolve(promise);
}
static final class SingleResolverContext extends DnsNameResolverContext<InetAddress> {
SingleResolverContext(DnsNameResolver parent, String hostname,
DnsRecord[] additionals, DnsCache resolveCache) {
super(parent, hostname, additionals, resolveCache);
}
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
@Override
DnsNameResolverContext<InetAddress> newResolverContext(DnsNameResolver parent, String hostname,
DnsRecord[] additionals, DnsCache resolveCache) {
return new SingleResolverContext(parent, hostname, additionals, resolveCache);
}
@Override
boolean finishResolve(
Class<? extends InetAddress> addressType, List<DnsCacheEntry> resolvedEntries,
Promise<InetAddress> promise) {
final int numEntries = resolvedEntries.size();
for (int i = 0; i < numEntries; i++) {
final InetAddress a = resolvedEntries.get(i).address();
if (addressType.isInstance(a)) {
trySuccess(promise, a);
return true;
}
}
return false;
}
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
@Override
protected void doResolveAll(String inetHost, Promise<List<InetAddress>> promise) throws Exception {
doResolveAll(inetHost, EMTPY_ADDITIONALS, promise, resolveCache);
}
/**
* Hook designed for extensibility so one can pass a different cache on each resolution attempt
* instead of using the global one.
*/
protected void doResolveAll(String inetHost,
DnsRecord[] additionals,
Promise<List<InetAddress>> promise,
DnsCache resolveCache) throws Exception {
final byte[] bytes = NetUtil.createByteArrayFromIpAddressString(inetHost);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
if (bytes != null) {
// The unresolvedAddress was created via a String that contains an ipaddress.
promise.setSuccess(Collections.singletonList(InetAddress.getByAddress(bytes)));
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
return;
}
final String hostname = hostname(inetHost);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
InetAddress hostsFileEntry = resolveHostsFileEntry(hostname);
if (hostsFileEntry != null) {
promise.setSuccess(Collections.singletonList(hostsFileEntry));
return;
}
if (!doResolveAllCached(hostname, additionals, promise, resolveCache)) {
doResolveAllUncached(hostname, additionals, promise, resolveCache);
}
}
private boolean doResolveAllCached(String hostname,
DnsRecord[] additionals,
Promise<List<InetAddress>> promise,
DnsCache resolveCache) {
final List<DnsCacheEntry> cachedEntries = resolveCache.get(hostname, additionals);
if (cachedEntries == null || cachedEntries.isEmpty()) {
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
return false;
}
List<InetAddress> result = null;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
Throwable cause = null;
synchronized (cachedEntries) {
final int numEntries = cachedEntries.size();
assert numEntries > 0;
if (cachedEntries.get(0).cause() != null) {
cause = cachedEntries.get(0).cause();
} else {
for (InternetProtocolFamily f : resolvedAddressTypes) {
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
for (int i = 0; i < numEntries; i++) {
final DnsCacheEntry e = cachedEntries.get(i);
if (f.addressType().isInstance(e.address())) {
if (result == null) {
result = new ArrayList<InetAddress>(numEntries);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
result.add(e.address());
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
}
}
}
}
if (result != null) {
trySuccess(promise, result);
return true;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
if (cause != null) {
tryFailure(promise, cause);
return true;
}
return false;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
static final class ListResolverContext extends DnsNameResolverContext<List<InetAddress>> {
ListResolverContext(DnsNameResolver parent, String hostname,
DnsRecord[] additionals, DnsCache resolveCache) {
super(parent, hostname, additionals, resolveCache);
}
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
@Override
DnsNameResolverContext<List<InetAddress>> newResolverContext(
DnsNameResolver parent, String hostname, DnsRecord[] additionals, DnsCache resolveCache) {
return new ListResolverContext(parent, hostname, additionals, resolveCache);
}
@Override
boolean finishResolve(
Class<? extends InetAddress> addressType, List<DnsCacheEntry> resolvedEntries,
Promise<List<InetAddress>> promise) {
List<InetAddress> result = null;
final int numEntries = resolvedEntries.size();
for (int i = 0; i < numEntries; i++) {
final InetAddress a = resolvedEntries.get(i).address();
if (addressType.isInstance(a)) {
if (result == null) {
result = new ArrayList<InetAddress>(numEntries);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
result.add(a);
}
}
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
if (result != null) {
promise.trySuccess(result);
return true;
}
return false;
}
}
private void doResolveAllUncached(String hostname,
DnsRecord[] additionals,
Promise<List<InetAddress>> promise,
DnsCache resolveCache) {
DnsNameResolverContext<List<InetAddress>> ctx = new ListResolverContext(
this, hostname, additionals, resolveCache);
ctx.resolve(promise);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
private static String hostname(String inetHost) {
String hostname = IDN.toASCII(inetHost);
// Check for http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6894622
if (StringUtil.endsWith(inetHost, '.') && !StringUtil.endsWith(hostname, '.')) {
hostname += ".";
}
return hostname;
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
/**
* Sends a DNS query with the specified question.
*/
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(DnsQuestion question) {
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
return query(nextNameServerAddress(), question);
}
/**
* Sends a DNS query with the specified question with additional records.
*/
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
DnsQuestion question, Iterable<DnsRecord> additionals) {
return query(nextNameServerAddress(), question, additionals);
}
/**
* Sends a DNS query with the specified question.
*/
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
DnsQuestion question, Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
return query(nextNameServerAddress(), question, Collections.<DnsRecord>emptyList(), promise);
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
}
private InetSocketAddress nextNameServerAddress() {
return nameServerAddrStream.get().next();
}
/**
* Sends a DNS query with the specified question using the specified name server list.
*/
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
InetSocketAddress nameServerAddr, DnsQuestion question) {
return query0(nameServerAddr, question, EMTPY_ADDITIONALS,
ch.eventLoop().<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>>newPromise());
}
/**
* Sends a DNS query with the specified question with additional records using the specified name server list.
*/
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
InetSocketAddress nameServerAddr, DnsQuestion question, Iterable<DnsRecord> additionals) {
return query0(nameServerAddr, question, toArray(additionals, false),
ch.eventLoop().<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>>newPromise());
}
/**
* Sends a DNS query with the specified question using the specified name server list.
*/
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
InetSocketAddress nameServerAddr, DnsQuestion question,
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
return query0(nameServerAddr, question, EMTPY_ADDITIONALS, promise);
}
/**
* Sends a DNS query with the specified question with additional records using the specified name server list.
*/
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
InetSocketAddress nameServerAddr, DnsQuestion question,
Iterable<DnsRecord> additionals,
Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
return query0(nameServerAddr, question, toArray(additionals, false), promise);
}
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query0(
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
InetSocketAddress nameServerAddr, DnsQuestion question,
DnsRecord[] additionals,
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
final Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> castPromise = cast(
checkNotNull(promise, "promise"));
try {
new DnsQueryContext(this, nameServerAddr, question, additionals, castPromise).query();
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
return castPromise;
} catch (Exception e) {
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
return castPromise.setFailure(e);
}
}
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
@SuppressWarnings("unchecked")
private static Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> cast(Promise<?> promise) {
return (Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>>) promise;
}
private final class DnsResponseHandler extends ChannelInboundHandlerAdapter {
private final Promise<Channel> channelActivePromise;
DnsResponseHandler(Promise<Channel> channelActivePromise) {
this.channelActivePromise = channelActivePromise;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
Revamp DNS codec Motivation: There are various known issues in netty-codec-dns: - Message types are not interfaces, which can make it difficult for a user to implement his/her own message implementation. - Some class names and field names do not match with the terms in the RFC. - The support for decoding a DNS record was limited. A user had to encode and decode by him/herself. - The separation of DnsHeader from DnsMessage was unnecessary, although it is fine conceptually. - Buffer leak caused by DnsMessage was difficult to analyze, because the leak detector tracks down the underlying ByteBuf rather than the DnsMessage itself. - DnsMessage assumes DNS-over-UDP. - To send an EDNS message, a user have to create a new DNS record class instance unnecessarily. Modifications: - Make all message types interfaces and add default implementations - Rename some classes, properties, and constants to match the RFCs - DnsResource -> DnsRecord - DnsType -> DnsRecordType - and many more - Remove DnsClass and use an integer to support EDNS better - Add DnsRecordEncoder/DnsRecordDecoder and their default implementations - DnsRecord does not require RDATA to be ByteBuf anymore. - Add DnsRawRecord as the catch-all record type - Merge DnsHeader into DnsMessage - Make ResourceLeakDetector track AbstractDnsMessage - Remove DnsMessage.sender/recipient properties - Wrap DnsMessage with AddressedEnvelope - Add DatagramDnsQuest and DatagramDnsResponse for ease of use - Rename DnsQueryEncoder to DatagramDnsQueryEncoder - Rename DnsResponseDecoder to DatagramDnsResponseDecoder - Miscellaneous changes - Add StringUtil.TAB Result: - Cleaner APi - Can support DNS-over-TCP more easily in the future - Reduced memory footprint in the default DnsQuery/Response implementations - Better leak tracking for DnsMessages - Possibility to introduce new DnsRecord types in the future and provide full record encoder/decoder implementation. - No unnecessary instantiation for an EDNS pseudo resource record
2015-03-16 07:46:14 +01:00
final DatagramDnsResponse res = (DatagramDnsResponse) msg;
final int queryId = res.id();
if (logger.isDebugEnabled()) {
logger.debug("{} RECEIVED: [{}: {}], {}", ch, queryId, res.sender(), res);
}
final DnsQueryContext qCtx = queryContextManager.get(res.sender(), queryId);
if (qCtx == null) {
logger.warn("{} Received a DNS response with an unknown ID: {}", ch, queryId);
return;
}
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
qCtx.finish(res);
} finally {
2014-10-16 10:56:12 +02:00
ReferenceCountUtil.safeRelease(msg);
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
channelActivePromise.setSuccess(ctx.channel());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
Provide more control over DnsNameResolver.query() / Add NameResolver.resolveAll() Related issues: - #3971 - #3973 - #3976 - #4035 Motivation: 1. Previously, DnsNameResolver.query() retried the request query by its own. It prevents a user from deciding when to retry or stop. It is also impossible to get the response object whose code is not NOERROR. 2. NameResolver does not have an operation that resolves a host name into multiple addresses, like InetAddress.getAllByName() Modifications: - Changes related with DnsNameResolver.query() - Make query() not retry - Move the retry logic to DnsNameResolver.resolve() instead. - Make query() fail the promise only when I/O error occurred or it failed to get a response - Add DnsNameResolverException and use it when query() fails so that the resolver can give more information about the failure - query() does not cache anymore. - Changes related with NameResolver.resolveAll() - Add NameResolver.resolveAll() - Add SimpleNameResolver.doResolveAll() - Changes related with DnsNameResolver.resolve() and resolveAll() - Make DnsNameResolveContext abstract so that DnsNameResolver can decide to get single or multiple addresses from it - Re-implement cache so that the cache works for resolve() and resolveAll() - Add 'traceEnabled' property to enable/disable trace information - Miscellaneous changes - Use ObjectUtil.checkNotNull() wherever possible - Add InternetProtocolFamily.addressType() to remove repetitive switch-case blocks in DnsNameResolver(Context) - Do not raise an exception when decoding a truncated DNS response Result: - Full control over query() - A user can now retrieve all addresses via (Dns)NameResolver.resolveAll() - DNS cache works only for resolve() and resolveAll() now.
2015-07-12 12:34:05 +02:00
logger.warn("{} Unexpected exception: ", ch, cause);
}
}
}