diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java index a9edc8d5c864..fd2d76df7805 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java @@ -1372,6 +1372,11 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) { qCh, queryId, res.sender()); res.release(); return; + } else if (qCtx.isDone()) { + logger.debug("{} Received a DNS response for a query that was timed out or cancelled: UDP [{}: {}]", + qCh, queryId, res.sender()); + res.release(); + return; } // Check if the response was truncated and if we can fallback to TCP to retry. @@ -1419,7 +1424,11 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) { } DnsQueryContext foundCtx = queryContextManager.get(res.sender(), queryId); - if (foundCtx == tcpCtx) { + if (foundCtx != null && foundCtx.isDone()) { + logger.debug("{} Received a DNS response for a query that was timed out or cancelled " + + ": TCP [{}: {}]", tcpCh, queryId, res.sender()); + response.release(); + } else if (foundCtx == tcpCtx) { tcpCtx.finishSuccess(new AddressedEnvelopeAdapter( (InetSocketAddress) ctx.channel().remoteAddress(), (InetSocketAddress) ctx.channel().localAddress(), diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java index a2f4e6fae60b..e3db5f807f6d 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java @@ -32,10 +32,12 @@ import io.netty.util.concurrent.FutureListener; import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.Promise; +import io.netty.util.internal.SystemPropertyUtil; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; import java.net.InetSocketAddress; +import java.util.concurrent.CancellationException; import java.util.concurrent.TimeUnit; import static io.netty.util.internal.ObjectUtil.checkNotNull; @@ -43,6 +45,13 @@ abstract class DnsQueryContext { private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsQueryContext.class); + private static final long ID_REUSE_ON_TIMEOUT_DELAY_MILLIS; + + static { + ID_REUSE_ON_TIMEOUT_DELAY_MILLIS = + SystemPropertyUtil.getLong("io.netty.resolver.dns.idReuseOnTimeoutDelayMillis", 10000); + logger.debug("-Dio.netty.resolver.dns.idReuseOnTimeoutDelayMillis: {}", ID_REUSE_ON_TIMEOUT_DELAY_MILLIS); + } private final Future channelReadyFuture; private final Channel channel; @@ -101,6 +110,15 @@ private static boolean hasOptRecord(DnsRecord[] additionals) { return false; } + /** + * Returns {@code true} if the query was completed already. + * + * @return {@code true} if done. + */ + final boolean isDone() { + return promise.isDone(); + } + /** * Returns the {@link DnsQuestion} that will be written as part of the {@link DnsQuery}. * @@ -149,11 +167,22 @@ public void operationComplete(Future