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
f4d3f81d6c
commit
2769ad428a
@ -87,6 +87,7 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
|||||||
private static final DnsQueryEncoder ENCODER = new DnsQueryEncoder();
|
private static final DnsQueryEncoder ENCODER = new DnsQueryEncoder();
|
||||||
|
|
||||||
final Iterable<InetSocketAddress> nameServerAddresses;
|
final Iterable<InetSocketAddress> nameServerAddresses;
|
||||||
|
final ChannelFuture bindFuture;
|
||||||
final DatagramChannel ch;
|
final DatagramChannel ch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -248,12 +249,13 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.nameServerAddresses = nameServerAddresses;
|
this.nameServerAddresses = nameServerAddresses;
|
||||||
ch = newChannel(channelFactory, localAddress);
|
bindFuture = newChannel(channelFactory, localAddress);
|
||||||
|
ch = (DatagramChannel) bindFuture.channel();
|
||||||
|
|
||||||
setMaxPayloadSize(4096);
|
setMaxPayloadSize(4096);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatagramChannel newChannel(
|
private ChannelFuture newChannel(
|
||||||
ChannelFactory<? extends DatagramChannel> channelFactory, InetSocketAddress localAddress) {
|
ChannelFactory<? extends DatagramChannel> channelFactory, InetSocketAddress localAddress) {
|
||||||
|
|
||||||
Bootstrap b = new Bootstrap();
|
Bootstrap b = new Bootstrap();
|
||||||
@ -266,15 +268,15 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
DatagramChannel ch = (DatagramChannel) b.bind(localAddress).channel();
|
ChannelFuture bindFuture = b.bind(localAddress);
|
||||||
ch.closeFuture().addListener(new ChannelFutureListener() {
|
bindFuture.channel().closeFuture().addListener(new ChannelFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
clearCache();
|
clearCache();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return ch;
|
return bindFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,6 @@ package io.netty.resolver.dns;
|
|||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.socket.DatagramChannel;
|
|
||||||
import io.netty.handler.codec.dns.DnsQuery;
|
import io.netty.handler.codec.dns.DnsQuery;
|
||||||
import io.netty.handler.codec.dns.DnsQuestion;
|
import io.netty.handler.codec.dns.DnsQuestion;
|
||||||
import io.netty.handler.codec.dns.DnsResource;
|
import io.netty.handler.codec.dns.DnsResource;
|
||||||
@ -131,13 +130,32 @@ final class DnsQueryContext {
|
|||||||
query.header().setRecursionDesired(recursionDesired);
|
query.header().setRecursionDesired(recursionDesired);
|
||||||
query.addAdditionalResource(optResource);
|
query.addAdditionalResource(optResource);
|
||||||
|
|
||||||
final DatagramChannel ch = parent.ch;
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
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()) {
|
if (writeFuture.isDone()) {
|
||||||
onQueryWriteCompletion(writeFuture, nameServerAddr);
|
onQueryWriteCompletion(writeFuture, nameServerAddr);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user