Simplified resolver via DnsResponse->DnsEnvelope for all promise types
This commit is contained in:
parent
dc54c9b226
commit
12c7c9f0a5
109
src/dorkbox/network/dns/DnsEnvelope.java
Normal file
109
src/dorkbox/network/dns/DnsEnvelope.java
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 dorkbox, llc.
|
||||||
|
*
|
||||||
|
* Licensed 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 dorkbox.network.dns;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
import dorkbox.network.dns.records.DnsMessage;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.AddressedEnvelope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public
|
||||||
|
class DnsEnvelope extends DnsMessage implements AddressedEnvelope<DnsEnvelope, InetSocketAddress> {
|
||||||
|
|
||||||
|
private InetSocketAddress localAddress;
|
||||||
|
private InetSocketAddress remoteAddress;
|
||||||
|
|
||||||
|
public
|
||||||
|
DnsEnvelope() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
DnsEnvelope(final ByteBuf buffer, final InetSocketAddress localAddress, final InetSocketAddress remoteAddress) throws IOException {
|
||||||
|
super(buffer);
|
||||||
|
|
||||||
|
this.localAddress = localAddress;
|
||||||
|
this.remoteAddress = remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public
|
||||||
|
DnsEnvelope(final DnsInput input, final InetSocketAddress localAddress, final InetSocketAddress remoteAddress) throws IOException {
|
||||||
|
super(input);
|
||||||
|
|
||||||
|
this.localAddress = localAddress;
|
||||||
|
this.remoteAddress = remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
void setLocalAddress(final InetSocketAddress localAddress) {
|
||||||
|
this.localAddress = localAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
void setRemoteAddress(final InetSocketAddress remoteAddress) {
|
||||||
|
this.remoteAddress = remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
DnsEnvelope content() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final
|
||||||
|
InetSocketAddress sender() {
|
||||||
|
return localAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final
|
||||||
|
InetSocketAddress recipient() {
|
||||||
|
return remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
DnsEnvelope touch() {
|
||||||
|
return (DnsEnvelope) super.touch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
DnsEnvelope touch(Object hint) {
|
||||||
|
return (DnsEnvelope) super.touch(hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
DnsEnvelope retain() {
|
||||||
|
return (DnsEnvelope) super.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
DnsEnvelope retain(int increment) {
|
||||||
|
return (DnsEnvelope) super.retain(increment);
|
||||||
|
}
|
||||||
|
}
|
@ -6,12 +6,7 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import dorkbox.network.dns.constants.DnsClass;
|
import dorkbox.network.dns.constants.*;
|
||||||
import dorkbox.network.dns.constants.DnsOpCode;
|
|
||||||
import dorkbox.network.dns.constants.DnsRecordType;
|
|
||||||
import dorkbox.network.dns.constants.DnsSection;
|
|
||||||
import dorkbox.network.dns.constants.Flags;
|
|
||||||
import dorkbox.network.dns.records.DnsMessage;
|
|
||||||
import dorkbox.network.dns.records.DnsRecord;
|
import dorkbox.network.dns.records.DnsRecord;
|
||||||
import io.netty.channel.AddressedEnvelope;
|
import io.netty.channel.AddressedEnvelope;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
@ -20,29 +15,7 @@ import io.netty.util.internal.StringUtil;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class DnsQuestion extends DnsMessage implements AddressedEnvelope<DnsQuestion, InetSocketAddress> {
|
class DnsQuestion extends DnsEnvelope {
|
||||||
private InetSocketAddress recipient;
|
|
||||||
private final boolean isResolveQuestion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance.
|
|
||||||
*
|
|
||||||
* @param isResolveQuestion true if it's a resolve question, which means we ALSO are going to keep resolving names until we get an IP
|
|
||||||
* address.
|
|
||||||
*/
|
|
||||||
private
|
|
||||||
DnsQuestion(final boolean isResolveQuestion) {
|
|
||||||
this.isResolveQuestion = isResolveQuestion;
|
|
||||||
this.recipient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public
|
|
||||||
boolean isResolveQuestion() {
|
|
||||||
return isResolveQuestion;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static
|
public static
|
||||||
DnsQuestion newResolveQuestion(final String inetHost, final int type, final boolean isRecursionDesired) {
|
DnsQuestion newResolveQuestion(final String inetHost, final int type, final boolean isRecursionDesired) {
|
||||||
return newQuestion(inetHost, type, isRecursionDesired, true);
|
return newQuestion(inetHost, type, isRecursionDesired, true);
|
||||||
@ -53,7 +26,6 @@ class DnsQuestion extends DnsMessage implements AddressedEnvelope<DnsQuestion, I
|
|||||||
return newQuestion(inetHost, type, isRecursionDesired, false);
|
return newQuestion(inetHost, type, isRecursionDesired, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static
|
private static
|
||||||
DnsQuestion newQuestion(final String inetHost, final int type, final boolean isRecursionDesired, boolean isResolveQuestion) {
|
DnsQuestion newQuestion(final String inetHost, final int type, final boolean isRecursionDesired, boolean isResolveQuestion) {
|
||||||
|
|
||||||
@ -63,6 +35,11 @@ class DnsQuestion extends DnsMessage implements AddressedEnvelope<DnsQuestion, I
|
|||||||
// - https://github.com/netty/netty/issues/4935
|
// - https://github.com/netty/netty/issues/4935
|
||||||
String hostName = hostNameAsciiFix(checkNotNull(inetHost, "hostname"));
|
String hostName = hostNameAsciiFix(checkNotNull(inetHost, "hostname"));
|
||||||
|
|
||||||
|
if (hostName == null) {
|
||||||
|
// hostNameAsciiFix can throw a TextParseException if it fails to parse
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
hostName = hostName.toLowerCase(Locale.US);
|
hostName = hostName.toLowerCase(Locale.US);
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +80,7 @@ class DnsQuestion extends DnsMessage implements AddressedEnvelope<DnsQuestion, I
|
|||||||
public static
|
public static
|
||||||
String hostNameAsciiFix(String inetHost) {
|
String hostNameAsciiFix(String inetHost) {
|
||||||
try {
|
try {
|
||||||
String hostName = java.net.IDN.toASCII(inetHost);
|
String hostName = java.net.IDN.toASCII(inetHost); // can throw IllegalArgumentException
|
||||||
|
|
||||||
// Check for http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6894622
|
// Check for http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6894622
|
||||||
if (StringUtil.endsWith(inetHost, '.') && !StringUtil.endsWith(hostName, '.')) {
|
if (StringUtil.endsWith(inetHost, '.') && !StringUtil.endsWith(hostName, '.')) {
|
||||||
@ -118,54 +95,46 @@ class DnsQuestion extends DnsMessage implements AddressedEnvelope<DnsQuestion, I
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final boolean isResolveQuestion;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param isResolveQuestion true if it's a resolve question, which means we ALSO are going to keep resolving names until we get an IP
|
||||||
|
* address.
|
||||||
|
*/
|
||||||
|
private
|
||||||
|
DnsQuestion(final boolean isResolveQuestion) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.isResolveQuestion = isResolveQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
boolean isResolveQuestion() {
|
||||||
|
return isResolveQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
void init(int id, InetSocketAddress recipient) {
|
void init(int id, InetSocketAddress recipient) {
|
||||||
getHeader().setID(id);
|
getHeader().setID(id);
|
||||||
this.recipient = recipient;
|
setRemoteAddress(recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
DnsQuestion content() {
|
int hashCode() {
|
||||||
return this;
|
int hashCode = super.hashCode();
|
||||||
|
if (sender() != null) {
|
||||||
|
hashCode = hashCode * 31 + sender().hashCode();
|
||||||
}
|
}
|
||||||
|
if (recipient() != null) {
|
||||||
@Override
|
hashCode = hashCode * 31 + recipient().hashCode();
|
||||||
public
|
|
||||||
InetSocketAddress sender() {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return hashCode;
|
||||||
@Override
|
|
||||||
public
|
|
||||||
InetSocketAddress recipient() {
|
|
||||||
return recipient;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
DnsQuestion touch() {
|
|
||||||
return (DnsQuestion) super.touch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
DnsQuestion touch(Object hint) {
|
|
||||||
return (DnsQuestion) super.touch(hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
DnsQuestion retain() {
|
|
||||||
return (DnsQuestion) super.retain();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
DnsQuestion retain(int increment) {
|
|
||||||
return (DnsQuestion) super.retain(increment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -205,18 +174,5 @@ class DnsQuestion extends DnsMessage implements AddressedEnvelope<DnsQuestion, I
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
int hashCode() {
|
|
||||||
int hashCode = super.hashCode();
|
|
||||||
if (sender() != null) {
|
|
||||||
hashCode = hashCode * 31 + sender().hashCode();
|
|
||||||
}
|
|
||||||
if (recipient() != null) {
|
|
||||||
hashCode = hashCode * 31 + recipient().hashCode();
|
|
||||||
}
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
import dorkbox.network.dns.records.DnsMessage;
|
|
||||||
import io.netty.channel.AddressedEnvelope;
|
import io.netty.channel.AddressedEnvelope;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
@ -27,74 +26,40 @@ import io.netty.util.internal.UnstableApi;
|
|||||||
* A {@link DnsResponse} implementation for UDP/IP.
|
* A {@link DnsResponse} implementation for UDP/IP.
|
||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public class DnsResponse extends DnsMessage implements AddressedEnvelope<DnsResponse, InetSocketAddress> {
|
public
|
||||||
|
class DnsResponse extends DnsEnvelope {
|
||||||
private final InetSocketAddress sender;
|
|
||||||
private final InetSocketAddress recipient;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
* @param sender the address of the sender
|
* @param localAddress the address of the sender
|
||||||
* @param recipient the address of the recipient
|
* @param remoteAddress the address of the recipient
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
DnsResponse(InetSocketAddress sender, InetSocketAddress recipient, final DnsInput dnsInput) throws IOException {
|
DnsResponse(final DnsInput dnsInput, InetSocketAddress localAddress, InetSocketAddress remoteAddress) throws IOException {
|
||||||
super(dnsInput);
|
super(dnsInput, localAddress, remoteAddress);
|
||||||
|
|
||||||
if (recipient == null && sender == null) {
|
if (remoteAddress == null && localAddress == null) {
|
||||||
throw new NullPointerException("recipient and sender");
|
throw new NullPointerException("localAddress and remoteAddress");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sender = sender;
|
|
||||||
this.recipient = recipient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
DnsResponse content() {
|
int hashCode() {
|
||||||
return this;
|
int hashCode = super.hashCode();
|
||||||
|
if (sender() != null) {
|
||||||
|
hashCode = hashCode * 31 + sender().hashCode();
|
||||||
}
|
}
|
||||||
|
if (recipient() != null) {
|
||||||
@Override
|
hashCode = hashCode * 31 + recipient().hashCode();
|
||||||
public InetSocketAddress sender() {
|
|
||||||
return sender;
|
|
||||||
}
|
}
|
||||||
|
return hashCode;
|
||||||
@Override
|
|
||||||
public InetSocketAddress recipient() {
|
|
||||||
return recipient;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
DnsResponse touch() {
|
|
||||||
return (DnsResponse) super.touch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
DnsResponse touch(Object hint) {
|
boolean equals(Object obj) {
|
||||||
return (DnsResponse) super.touch(hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
DnsResponse retain() {
|
|
||||||
return (DnsResponse) super.retain();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
DnsResponse retain(int increment) {
|
|
||||||
return (DnsResponse) super.retain(increment);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -113,7 +78,8 @@ public class DnsResponse extends DnsMessage implements AddressedEnvelope<DnsResp
|
|||||||
if (that.sender() != null) {
|
if (that.sender() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!sender().equals(that.sender())) {
|
}
|
||||||
|
else if (!sender().equals(that.sender())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,22 +87,11 @@ public class DnsResponse extends DnsMessage implements AddressedEnvelope<DnsResp
|
|||||||
if (that.recipient() != null) {
|
if (that.recipient() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!recipient().equals(that.recipient())) {
|
}
|
||||||
|
else if (!recipient().equals(that.recipient())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hashCode = super.hashCode();
|
|
||||||
if (sender() != null) {
|
|
||||||
hashCode = hashCode * 31 + sender().hashCode();
|
|
||||||
}
|
|
||||||
if (recipient() != null) {
|
|
||||||
hashCode = hashCode * 31 + recipient().hashCode();
|
|
||||||
}
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -28,29 +28,16 @@ import java.util.List;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import dorkbox.network.dns.DatagramDnsQueryEncoder;
|
|
||||||
import dorkbox.network.dns.DatagramDnsResponseDecoder;
|
|
||||||
import dorkbox.network.dns.DnsQuestion;
|
import dorkbox.network.dns.DnsQuestion;
|
||||||
import dorkbox.network.dns.DnsResponse;
|
import dorkbox.network.dns.DnsResponse;
|
||||||
|
import dorkbox.network.dns.clientHandlers.DatagramDnsQueryEncoder;
|
||||||
|
import dorkbox.network.dns.clientHandlers.DatagramDnsResponseDecoder;
|
||||||
import dorkbox.network.dns.constants.DnsRecordType;
|
import dorkbox.network.dns.constants.DnsRecordType;
|
||||||
import dorkbox.network.dns.resolver.addressProvider.DefaultDnsServerAddressStreamProvider;
|
import dorkbox.network.dns.resolver.addressProvider.*;
|
||||||
import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStream;
|
|
||||||
import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStreamProvider;
|
|
||||||
import dorkbox.network.dns.resolver.addressProvider.DnsServerAddresses;
|
|
||||||
import dorkbox.network.dns.resolver.addressProvider.UnixResolverDnsServerAddressStreamProvider;
|
|
||||||
import dorkbox.network.dns.resolver.cache.DnsCache;
|
import dorkbox.network.dns.resolver.cache.DnsCache;
|
||||||
import dorkbox.network.dns.resolver.cache.DnsCacheEntry;
|
import dorkbox.network.dns.resolver.cache.DnsCacheEntry;
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.channel.AddressedEnvelope;
|
import io.netty.channel.*;
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.ChannelFactory;
|
|
||||||
import io.netty.channel.ChannelFuture;
|
|
||||||
import io.netty.channel.ChannelFutureListener;
|
|
||||||
import io.netty.channel.ChannelInitializer;
|
|
||||||
import io.netty.channel.ChannelOption;
|
|
||||||
import io.netty.channel.ChannelPromise;
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.FixedRecvByteBufAllocator;
|
|
||||||
import io.netty.channel.socket.DatagramChannel;
|
import io.netty.channel.socket.DatagramChannel;
|
||||||
import io.netty.channel.socket.InternetProtocolFamily;
|
import io.netty.channel.socket.InternetProtocolFamily;
|
||||||
import io.netty.resolver.HostsFileEntriesResolver;
|
import io.netty.resolver.HostsFileEntriesResolver;
|
||||||
@ -750,7 +737,7 @@ class DnsNameResolver extends InetNameResolver {
|
|||||||
* Sends a DNS query with the specified question.
|
* Sends a DNS query with the specified question.
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(DnsQuestion question) {
|
Future<DnsResponse> query(DnsQuestion question) {
|
||||||
return query(nextNameServerAddress(), question);
|
return query(nextNameServerAddress(), question);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,48 +751,39 @@ class DnsNameResolver extends InetNameResolver {
|
|||||||
* Sends a DNS query with the specified question using the specified name server list.
|
* Sends a DNS query with the specified question using the specified name server list.
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(InetSocketAddress nameServerAddr, DnsQuestion question) {
|
Future<DnsResponse> query(InetSocketAddress nameServerAddr, DnsQuestion question) {
|
||||||
return query0(nameServerAddr,
|
return query0(nameServerAddr,
|
||||||
question,
|
question,
|
||||||
ch.eventLoop().<AddressedEnvelope<DnsResponse, InetSocketAddress>>newPromise());
|
ch.eventLoop().<DnsResponse>newPromise());
|
||||||
}
|
}
|
||||||
|
|
||||||
final
|
final
|
||||||
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query0(InetSocketAddress nameServerAddr,
|
Future<DnsResponse> query0(InetSocketAddress nameServerAddr,
|
||||||
DnsQuestion question,
|
DnsQuestion question,
|
||||||
Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) {
|
Promise<DnsResponse> promise) {
|
||||||
return query0(nameServerAddr, question, ch.newPromise(), promise);
|
return query0(nameServerAddr, question, ch.newPromise(), promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
final
|
final
|
||||||
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query0(InetSocketAddress nameServerAddr,
|
Future<DnsResponse> query0(InetSocketAddress nameServerAddr,
|
||||||
DnsQuestion question,
|
DnsQuestion question,
|
||||||
ChannelPromise writePromise,
|
ChannelPromise writePromise,
|
||||||
Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) {
|
Promise<DnsResponse> promise) {
|
||||||
assert !writePromise.isVoid();
|
assert !writePromise.isVoid();
|
||||||
|
|
||||||
final Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> castPromise = cast(checkNotNull(promise, "promise"));
|
|
||||||
try {
|
try {
|
||||||
new DnsQueryContext(this, nameServerAddr, question, castPromise).query(writePromise);
|
new DnsQueryContext(this, nameServerAddr, question, promise).query(writePromise);
|
||||||
return castPromise;
|
return promise;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return castPromise.setFailure(e);
|
return promise.setFailure(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static
|
|
||||||
Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> cast(Promise<?> promise) {
|
|
||||||
return (Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>>) promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a DNS query with the specified question.
|
* Sends a DNS query with the specified question.
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(DnsQuestion question,
|
Future<DnsResponse> query(DnsQuestion question, Promise<DnsResponse> promise) {
|
||||||
Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) {
|
|
||||||
return query(nextNameServerAddress(), question, promise);
|
return query(nextNameServerAddress(), question, promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,10 +791,7 @@ class DnsNameResolver extends InetNameResolver {
|
|||||||
* Sends a DNS query with the specified question using the specified name server list.
|
* Sends a DNS query with the specified question using the specified name server list.
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(InetSocketAddress nameServerAddr,
|
Future<DnsResponse> query(InetSocketAddress nameServerAddr, DnsQuestion question, Promise<DnsResponse> promise) {
|
||||||
DnsQuestion question,
|
|
||||||
Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) {
|
|
||||||
|
|
||||||
return query0(nameServerAddr, question, null, promise);
|
return query0(nameServerAddr, question, null, promise);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,32 +22,18 @@ import static java.util.Collections.unmodifiableList;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import dorkbox.network.dns.DnsQuestion;
|
import dorkbox.network.dns.DnsQuestion;
|
||||||
import dorkbox.network.dns.DnsResponse;
|
import dorkbox.network.dns.DnsResponse;
|
||||||
import dorkbox.network.dns.constants.DnsRecordType;
|
import dorkbox.network.dns.constants.DnsRecordType;
|
||||||
import dorkbox.network.dns.constants.DnsResponseCode;
|
import dorkbox.network.dns.constants.DnsResponseCode;
|
||||||
import dorkbox.network.dns.constants.DnsSection;
|
import dorkbox.network.dns.constants.DnsSection;
|
||||||
import dorkbox.network.dns.records.AAAARecord;
|
import dorkbox.network.dns.records.*;
|
||||||
import dorkbox.network.dns.records.ARecord;
|
|
||||||
import dorkbox.network.dns.records.CNAMERecord;
|
|
||||||
import dorkbox.network.dns.records.DnsMessage;
|
|
||||||
import dorkbox.network.dns.records.DnsRecord;
|
|
||||||
import dorkbox.network.dns.records.NSRecord;
|
|
||||||
import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStream;
|
import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStream;
|
||||||
import dorkbox.network.dns.resolver.addressProvider.DnsServerAddresses;
|
import dorkbox.network.dns.resolver.addressProvider.DnsServerAddresses;
|
||||||
import dorkbox.network.dns.resolver.cache.DnsCache;
|
import dorkbox.network.dns.resolver.cache.DnsCache;
|
||||||
import dorkbox.network.dns.resolver.cache.DnsCacheEntry;
|
import dorkbox.network.dns.resolver.cache.DnsCacheEntry;
|
||||||
import io.netty.channel.AddressedEnvelope;
|
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.socket.InternetProtocolFamily;
|
import io.netty.channel.socket.InternetProtocolFamily;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
@ -61,10 +47,10 @@ import io.netty.util.internal.ThrowableUtil;
|
|||||||
abstract
|
abstract
|
||||||
class DnsNameResolverContext<T> {
|
class DnsNameResolverContext<T> {
|
||||||
|
|
||||||
private static final FutureListener<AddressedEnvelope<DnsResponse, InetSocketAddress>> RELEASE_RESPONSE = new FutureListener<AddressedEnvelope<DnsResponse, InetSocketAddress>>() {
|
private static final FutureListener<DnsResponse> RELEASE_RESPONSE = new FutureListener<DnsResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void operationComplete(Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> future) {
|
void operationComplete(Future<DnsResponse> future) {
|
||||||
if (future.isSuccess()) {
|
if (future.isSuccess()) {
|
||||||
future.getNow()
|
future.getNow()
|
||||||
.release();
|
.release();
|
||||||
@ -104,7 +90,7 @@ class DnsNameResolverContext<T> {
|
|||||||
private final int maxAllowedQueries;
|
private final int maxAllowedQueries;
|
||||||
private final InternetProtocolFamily[] resolvedInternetProtocolFamilies;
|
private final InternetProtocolFamily[] resolvedInternetProtocolFamilies;
|
||||||
|
|
||||||
private final Set<Future<AddressedEnvelope<DnsResponse, InetSocketAddress>>> queriesInProgress = Collections.newSetFromMap(new IdentityHashMap<Future<AddressedEnvelope<DnsResponse, InetSocketAddress>>, Boolean>());
|
private final Set<Future<DnsResponse>> queriesInProgress = Collections.newSetFromMap(new IdentityHashMap<Future<DnsResponse>, Boolean>());
|
||||||
|
|
||||||
private List<DnsCacheEntry> resolvedEntries;
|
private List<DnsCacheEntry> resolvedEntries;
|
||||||
private int allowedQueries;
|
private int allowedQueries;
|
||||||
@ -323,20 +309,20 @@ class DnsNameResolverContext<T> {
|
|||||||
|
|
||||||
final InetSocketAddress nameServerAddr = nameServerAddrStream.next();
|
final InetSocketAddress nameServerAddr = nameServerAddrStream.next();
|
||||||
final ChannelPromise writePromise = parent.ch.newPromise();
|
final ChannelPromise writePromise = parent.ch.newPromise();
|
||||||
final Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> f =
|
final Future<DnsResponse> f =
|
||||||
parent.query0(nameServerAddr,
|
parent.query0(nameServerAddr,
|
||||||
question,
|
question,
|
||||||
writePromise,
|
writePromise,
|
||||||
parent.ch.eventLoop().<AddressedEnvelope<DnsResponse, InetSocketAddress>>newPromise());
|
parent.ch.eventLoop().<DnsResponse>newPromise());
|
||||||
|
|
||||||
queriesInProgress.add(f);
|
queriesInProgress.add(f);
|
||||||
|
|
||||||
queryLifecycleObserver.queryWritten(nameServerAddr, writePromise);
|
queryLifecycleObserver.queryWritten(nameServerAddr, writePromise);
|
||||||
|
|
||||||
f.addListener(new FutureListener<AddressedEnvelope<DnsResponse, InetSocketAddress>>() {
|
f.addListener(new FutureListener<DnsResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void operationComplete(Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> future) {
|
void operationComplete(Future<DnsResponse> future) {
|
||||||
// future.result() should have refCnt=2
|
// future.result() should have refCnt=2
|
||||||
// question should have refCnt=1
|
// question should have refCnt=1
|
||||||
queriesInProgress.remove(future);
|
queriesInProgress.remove(future);
|
||||||
@ -346,7 +332,7 @@ class DnsNameResolverContext<T> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressedEnvelope<DnsResponse, InetSocketAddress> envelope = future.getNow();
|
DnsResponse envelope = future.getNow();
|
||||||
try {
|
try {
|
||||||
if (future.isSuccess()) {
|
if (future.isSuccess()) {
|
||||||
onResponse(nameServerAddrStream,
|
onResponse(nameServerAddrStream,
|
||||||
@ -378,17 +364,15 @@ class DnsNameResolverContext<T> {
|
|||||||
|
|
||||||
void onResponse(final DnsServerAddressStream nameServerAddrStream,
|
void onResponse(final DnsServerAddressStream nameServerAddrStream,
|
||||||
final int nameServerAddrStreamIndex,
|
final int nameServerAddrStreamIndex,
|
||||||
final DnsQuestion question,
|
final DnsQuestion question, DnsResponse response,
|
||||||
AddressedEnvelope<DnsResponse, InetSocketAddress> envelope,
|
|
||||||
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
||||||
Promise<T> promise) {
|
Promise<T> promise) {
|
||||||
|
|
||||||
final DnsResponse res = envelope.content();
|
final int code = response.getHeader()
|
||||||
final int code = res.getHeader()
|
|
||||||
.getRcode();
|
.getRcode();
|
||||||
|
|
||||||
if (code == DnsResponseCode.NOERROR) {
|
if (code == DnsResponseCode.NOERROR) {
|
||||||
if (handleRedirect(question, envelope, queryLifecycleObserver, promise)) {
|
if (handleRedirect(question, response, queryLifecycleObserver, promise)) {
|
||||||
// Was a redirect so return here as everything else is handled in handleRedirect(...)
|
// Was a redirect so return here as everything else is handled in handleRedirect(...)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -396,10 +380,10 @@ class DnsNameResolverContext<T> {
|
|||||||
.getType();
|
.getType();
|
||||||
|
|
||||||
if (type == DnsRecordType.A || type == DnsRecordType.AAAA) {
|
if (type == DnsRecordType.A || type == DnsRecordType.AAAA) {
|
||||||
onResponseAorAAAA(type, question, envelope, queryLifecycleObserver, promise);
|
onResponseAorAAAA(type, question, response, queryLifecycleObserver, promise);
|
||||||
}
|
}
|
||||||
else if (type == DnsRecordType.CNAME) {
|
else if (type == DnsRecordType.CNAME) {
|
||||||
onResponseCNAME(question, envelope, queryLifecycleObserver, promise);
|
onResponseCNAME(question, response, queryLifecycleObserver, promise);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
queryLifecycleObserver.queryFailed(UNRECOGNIZED_TYPE_QUERY_FAILED_EXCEPTION);
|
queryLifecycleObserver.queryFailed(UNRECOGNIZED_TYPE_QUERY_FAILED_EXCEPTION);
|
||||||
@ -424,23 +408,20 @@ class DnsNameResolverContext<T> {
|
|||||||
* Handles a redirect answer if needed and returns {@code true} if a redirect query has been made.
|
* Handles a redirect answer if needed and returns {@code true} if a redirect query has been made.
|
||||||
*/
|
*/
|
||||||
private
|
private
|
||||||
boolean handleRedirect(DnsQuestion question,
|
boolean handleRedirect(DnsQuestion question, DnsResponse response,
|
||||||
AddressedEnvelope<DnsResponse, InetSocketAddress> envelope,
|
|
||||||
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
||||||
Promise<T> promise) {
|
Promise<T> promise) {
|
||||||
|
|
||||||
final DnsResponse res = envelope.content();
|
|
||||||
|
|
||||||
// Check if we have answers, if not this may be an non authority NS and so redirects must be handled.
|
// Check if we have answers, if not this may be an non authority NS and so redirects must be handled.
|
||||||
DnsRecord[] answerArray = res.getSectionArray(DnsSection.ANSWER);
|
DnsRecord[] answerArray = response.getSectionArray(DnsSection.ANSWER);
|
||||||
if (answerArray.length == 0) {
|
if (answerArray.length == 0) {
|
||||||
AuthoritativeNameServerList serverNames = extractAuthoritativeNameServers(question.getQuestion()
|
AuthoritativeNameServerList serverNames = extractAuthoritativeNameServers(question.getQuestion()
|
||||||
.getName()
|
.getName()
|
||||||
.toString(), res);
|
.toString(), response);
|
||||||
|
|
||||||
if (serverNames != null) {
|
if (serverNames != null) {
|
||||||
List<InetSocketAddress> nameServers = new ArrayList<InetSocketAddress>(serverNames.size());
|
List<InetSocketAddress> nameServers = new ArrayList<InetSocketAddress>(serverNames.size());
|
||||||
DnsRecord[] additionalArray = res.getSectionArray(DnsSection.ADDITIONAL);
|
DnsRecord[] additionalArray = response.getSectionArray(DnsSection.ADDITIONAL);
|
||||||
|
|
||||||
for (int i = 0; i < additionalArray.length; i++) {
|
for (int i = 0; i < additionalArray.length; i++) {
|
||||||
final DnsRecord r = additionalArray[i];
|
final DnsRecord r = additionalArray[i];
|
||||||
@ -505,13 +486,11 @@ class DnsNameResolverContext<T> {
|
|||||||
|
|
||||||
private
|
private
|
||||||
void onResponseAorAAAA(int qType,
|
void onResponseAorAAAA(int qType,
|
||||||
DnsMessage question,
|
DnsMessage question, DnsResponse response,
|
||||||
AddressedEnvelope<DnsResponse, InetSocketAddress> envelope,
|
|
||||||
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
||||||
Promise<T> promise) {
|
Promise<T> promise) {
|
||||||
|
|
||||||
// We often get a bunch of CNAMES as well when we asked for A/AAAA.
|
// We often get a bunch of CNAMES as well when we asked for A/AAAA.
|
||||||
final DnsResponse response = envelope.content();
|
|
||||||
final Map<String, String> cnames = buildAliasMap(response);
|
final Map<String, String> cnames = buildAliasMap(response);
|
||||||
|
|
||||||
DnsRecord[] answerArray = response.getSectionArray(DnsSection.ANSWER);
|
DnsRecord[] answerArray = response.getSectionArray(DnsSection.ANSWER);
|
||||||
@ -573,7 +552,7 @@ class DnsNameResolverContext<T> {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// We asked for A/AAAA but we got only CNAME.
|
// We asked for A/AAAA but we got only CNAME.
|
||||||
onResponseCNAME(question, envelope, cnames, queryLifecycleObserver, promise);
|
onResponseCNAME(question, response, cnames, queryLifecycleObserver, promise);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,16 +574,14 @@ class DnsNameResolverContext<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private
|
private
|
||||||
void onResponseCNAME(DnsMessage question,
|
void onResponseCNAME(DnsMessage question, DnsResponse response,
|
||||||
AddressedEnvelope<DnsResponse, InetSocketAddress> envelope,
|
|
||||||
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
||||||
Promise<T> promise) {
|
Promise<T> promise) {
|
||||||
onResponseCNAME(question, envelope, buildAliasMap(envelope.content()), queryLifecycleObserver, promise);
|
onResponseCNAME(question, response, buildAliasMap(response), queryLifecycleObserver, promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
private
|
private
|
||||||
void onResponseCNAME(DnsMessage question,
|
void onResponseCNAME(DnsMessage question, DnsResponse response,
|
||||||
AddressedEnvelope<DnsResponse, InetSocketAddress> response,
|
|
||||||
Map<String, String> cnames,
|
Map<String, String> cnames,
|
||||||
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
final DnsQueryLifecycleObserver queryLifecycleObserver,
|
||||||
Promise<T> promise) {
|
Promise<T> promise) {
|
||||||
@ -748,8 +725,8 @@ class DnsNameResolverContext<T> {
|
|||||||
|
|
||||||
if (!queriesInProgress.isEmpty()) {
|
if (!queriesInProgress.isEmpty()) {
|
||||||
// If there are queries in progress, we should cancel it because we already finished the resolution.
|
// If there are queries in progress, we should cancel it because we already finished the resolution.
|
||||||
for (Iterator<Future<AddressedEnvelope<DnsResponse, InetSocketAddress>>> i = queriesInProgress.iterator(); i.hasNext(); ) {
|
for (Iterator<Future<DnsResponse>> i = queriesInProgress.iterator(); i.hasNext(); ) {
|
||||||
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> f = i.next();
|
Future<DnsResponse> f = i.next();
|
||||||
i.remove();
|
i.remove();
|
||||||
|
|
||||||
if (!f.cancel(false)) {
|
if (!f.cancel(false)) {
|
||||||
|
@ -24,7 +24,6 @@ import dorkbox.network.dns.DnsQuestion;
|
|||||||
import dorkbox.network.dns.DnsResponse;
|
import dorkbox.network.dns.DnsResponse;
|
||||||
import dorkbox.network.dns.constants.DnsSection;
|
import dorkbox.network.dns.constants.DnsSection;
|
||||||
import dorkbox.network.dns.records.DnsRecord;
|
import dorkbox.network.dns.records.DnsRecord;
|
||||||
import io.netty.channel.AddressedEnvelope;
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
@ -42,7 +41,7 @@ class DnsQueryContext {
|
|||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsQueryContext.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsQueryContext.class);
|
||||||
|
|
||||||
private final DnsNameResolver parent;
|
private final DnsNameResolver parent;
|
||||||
private final Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise;
|
private final Promise<DnsResponse> promise;
|
||||||
private final int id;
|
private final int id;
|
||||||
private final DnsQuestion question;
|
private final DnsQuestion question;
|
||||||
|
|
||||||
@ -53,7 +52,7 @@ class DnsQueryContext {
|
|||||||
DnsQueryContext(DnsNameResolver parent,
|
DnsQueryContext(DnsNameResolver parent,
|
||||||
InetSocketAddress nameServerAddr,
|
InetSocketAddress nameServerAddr,
|
||||||
DnsQuestion question,
|
DnsQuestion question,
|
||||||
Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) {
|
Promise<DnsResponse> promise) {
|
||||||
|
|
||||||
this.parent = checkNotNull(parent, "parent");
|
this.parent = checkNotNull(parent, "parent");
|
||||||
this.nameServerAddr = checkNotNull(nameServerAddr, "nameServerAddr");
|
this.nameServerAddr = checkNotNull(nameServerAddr, "nameServerAddr");
|
||||||
@ -175,29 +174,28 @@ class DnsQueryContext {
|
|||||||
promise.tryFailure(e);
|
promise.tryFailure(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void finish(AddressedEnvelope<DnsResponse, InetSocketAddress> envelope) {
|
void finish(DnsResponse response) {
|
||||||
final DnsResponse response = envelope.content();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DnsRecord[] sectionArray = response.getSectionArray(DnsSection.QUESTION);
|
DnsRecord[] sectionArray = response.getSectionArray(DnsSection.QUESTION);
|
||||||
if (sectionArray.length != 1) {
|
if (sectionArray.length != 1) {
|
||||||
logger.warn("Received a DNS response with invalid number of questions: {}", envelope);
|
logger.warn("Received a DNS response with invalid number of questions: {}", response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DnsRecord[] questionArray = question.getSectionArray(DnsSection.QUESTION);
|
DnsRecord[] questionArray = question.getSectionArray(DnsSection.QUESTION);
|
||||||
if (questionArray.length != 1) {
|
if (questionArray.length != 1) {
|
||||||
logger.warn("Received a DNS response with invalid number of query questions: {}", envelope);
|
logger.warn("Received a DNS response with invalid number of query questions: {}", response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!questionArray[0].equals(sectionArray[0])) {
|
if (!questionArray[0].equals(sectionArray[0])) {
|
||||||
logger.warn("Received a mismatching DNS response: {}", envelope);
|
logger.warn("Received a mismatching DNS response: {}", response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSuccess(envelope);
|
setSuccess(response);
|
||||||
} finally {
|
} finally {
|
||||||
if (question.isResolveQuestion()) {
|
if (question.isResolveQuestion()) {
|
||||||
// for resolve questions (always A/AAAA), we convert the answer into InetAddress, however with OTHER TYPES, we pass
|
// for resolve questions (always A/AAAA), we convert the answer into InetAddress, however with OTHER TYPES, we pass
|
||||||
@ -208,7 +206,7 @@ class DnsQueryContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private
|
private
|
||||||
void setSuccess(AddressedEnvelope<DnsResponse, InetSocketAddress> envelope) {
|
void setSuccess(DnsResponse response) {
|
||||||
parent.queryContextManager.remove(nameServerAddr(), id);
|
parent.queryContextManager.remove(nameServerAddr(), id);
|
||||||
|
|
||||||
// Cancel the timeout task.
|
// Cancel the timeout task.
|
||||||
@ -217,17 +215,16 @@ class DnsQueryContext {
|
|||||||
timeoutFuture.cancel(false);
|
timeoutFuture.cancel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise = this.promise;
|
Promise<DnsResponse> promise = this.promise;
|
||||||
if (promise.setUncancellable()) {
|
if (promise.setUncancellable()) {
|
||||||
@SuppressWarnings("unchecked")
|
response.retain();
|
||||||
AddressedEnvelope<DnsResponse, InetSocketAddress> castResponse = envelope.retain();
|
// response now has a refCnt = 2
|
||||||
// envelope now has a refCnt = 2
|
if (!promise.trySuccess(response)) { // question is used here!
|
||||||
if (!promise.trySuccess(castResponse)) { // question is used here!
|
|
||||||
// We failed to notify the promise as it was failed before, thus we need to release the envelope
|
// We failed to notify the promise as it was failed before, thus we need to release the envelope
|
||||||
envelope.release();
|
response.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
envelope.release();
|
response.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user