Check the bindFuture before writing a DNS query
Related: #3149 Motivation: DnsQueryContext, using the DatagramChannel bound in DnsNameResolver, blindly writes to the channel without checking the bind future for success. Modifications: Check the bindFuture before writing a DNS query to a DatagramChannel Result: Bug fixed
This commit is contained in:
parent
e9bcc518fc
commit
7b39968f57
@ -87,6 +87,7 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
||||
private static final DnsQueryEncoder ENCODER = new DnsQueryEncoder();
|
||||
|
||||
final Iterable<InetSocketAddress> nameServerAddresses;
|
||||
final ChannelFuture bindFuture;
|
||||
final DatagramChannel ch;
|
||||
|
||||
/**
|
||||
@ -248,12 +249,13 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
||||
}
|
||||
|
||||
this.nameServerAddresses = nameServerAddresses;
|
||||
ch = newChannel(channelFactory, localAddress);
|
||||
bindFuture = newChannel(channelFactory, localAddress);
|
||||
ch = (DatagramChannel) bindFuture.channel();
|
||||
|
||||
setMaxPayloadSize(4096);
|
||||
}
|
||||
|
||||
private DatagramChannel newChannel(
|
||||
private ChannelFuture newChannel(
|
||||
ChannelFactory<? extends DatagramChannel> channelFactory, InetSocketAddress localAddress) {
|
||||
|
||||
Bootstrap b = new Bootstrap();
|
||||
@ -266,15 +268,15 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
||||
}
|
||||
});
|
||||
|
||||
DatagramChannel ch = (DatagramChannel) b.bind(localAddress).channel();
|
||||
ch.closeFuture().addListener(new ChannelFutureListener() {
|
||||
ChannelFuture bindFuture = b.bind(localAddress);
|
||||
bindFuture.channel().closeFuture().addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
clearCache();
|
||||
}
|
||||
});
|
||||
|
||||
return ch;
|
||||
return bindFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,6 @@ package io.netty.resolver.dns;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.socket.DatagramChannel;
|
||||
import io.netty.handler.codec.dns.DnsQuery;
|
||||
import io.netty.handler.codec.dns.DnsQuestion;
|
||||
import io.netty.handler.codec.dns.DnsResource;
|
||||
@ -131,13 +130,32 @@ final class DnsQueryContext {
|
||||
query.header().setRecursionDesired(recursionDesired);
|
||||
query.addAdditionalResource(optResource);
|
||||
|
||||
final DatagramChannel ch = parent.ch;
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{} WRITE: [{}: {}], {}", ch, id, nameServerAddr, question);
|
||||
logger.debug("{} WRITE: [{}: {}], {}", parent.ch, id, nameServerAddr, question);
|
||||
}
|
||||
|
||||
final ChannelFuture writeFuture = ch.writeAndFlush(query);
|
||||
sendQuery(query, nameServerAddr);
|
||||
}
|
||||
|
||||
private void sendQuery(final DnsQuery query, final InetSocketAddress nameServerAddr) {
|
||||
if (parent.bindFuture.isDone()) {
|
||||
writeQuery(query, nameServerAddr);
|
||||
} else {
|
||||
parent.bindFuture.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
writeQuery(query, nameServerAddr);
|
||||
} else {
|
||||
promise.tryFailure(future.cause());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void writeQuery(final DnsQuery query, final InetSocketAddress nameServerAddr) {
|
||||
final ChannelFuture writeFuture = parent.ch.writeAndFlush(query);
|
||||
if (writeFuture.isDone()) {
|
||||
onQueryWriteCompletion(writeFuture, nameServerAddr);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user