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:
Jay 2014-11-18 12:28:45 -08:00 committed by Trustin Lee
parent f4d3f81d6c
commit 2769ad428a
2 changed files with 30 additions and 10 deletions

View File

@ -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;
}
/**

View File

@ -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 {