1818import io .netty .bootstrap .Bootstrap ;
1919import io .netty .bootstrap .ChannelFactory ;
2020import io .netty .channel .AddressedEnvelope ;
21+ import io .netty .channel .Channel ;
2122import io .netty .channel .ChannelFuture ;
2223import io .netty .channel .ChannelFutureListener ;
2324import io .netty .channel .ChannelHandlerContext ;
2425import io .netty .channel .ChannelInboundHandlerAdapter ;
2526import io .netty .channel .ChannelInitializer ;
27+ import io .netty .channel .ChannelOption ;
2628import io .netty .channel .EventLoop ;
2729import io .netty .channel .FixedRecvByteBufAllocator ;
2830import io .netty .channel .socket .DatagramChannel ;
@@ -64,8 +66,6 @@ public class DnsNameResolver extends InetNameResolver {
6466 private static final String LOCALHOST = "localhost" ;
6567 private static final InetAddress LOCALHOST_ADDRESS ;
6668
67- static final InetSocketAddress ANY_LOCAL_ADDR = new InetSocketAddress (0 );
68-
6969 static final InternetProtocolFamily [] DEFAULT_RESOLVE_ADDRESS_TYPES = new InternetProtocolFamily [2 ];
7070
7171 static {
@@ -87,7 +87,7 @@ public class DnsNameResolver extends InetNameResolver {
8787 private static final DatagramDnsQueryEncoder ENCODER = new DatagramDnsQueryEncoder ();
8888
8989 final DnsServerAddresses nameServerAddresses ;
90- final ChannelFuture bindFuture ;
90+ final Future < Channel > channelFuture ;
9191 final DatagramChannel ch ;
9292
9393 /**
@@ -122,7 +122,6 @@ protected DnsServerAddressStream initialValue() throws Exception {
122122 *
123123 * @param eventLoop the {@link EventLoop} which will perform the communication with the DNS servers
124124 * @param channelFactory the {@link ChannelFactory} that will create a {@link DatagramChannel}
125- * @param localAddress the local address of the {@link DatagramChannel}
126125 * @param nameServerAddresses the addresses of the DNS server. For each DNS query, a new stream is created from
127126 * this to determine which DNS server should be contacted for the next retry in case
128127 * of failure.
@@ -139,9 +138,8 @@ protected DnsServerAddressStream initialValue() throws Exception {
139138 public DnsNameResolver (
140139 EventLoop eventLoop ,
141140 ChannelFactory <? extends DatagramChannel > channelFactory ,
142- InetSocketAddress localAddress ,
143141 DnsServerAddresses nameServerAddresses ,
144- DnsCache resolveCache ,
142+ final DnsCache resolveCache ,
145143 long queryTimeoutMillis ,
146144 InternetProtocolFamily [] resolvedAddressTypes ,
147145 boolean recursionDesired ,
@@ -153,7 +151,6 @@ public DnsNameResolver(
153151
154152 super (eventLoop );
155153 checkNotNull (channelFactory , "channelFactory" );
156- checkNotNull (localAddress , "localAddress" );
157154 this .nameServerAddresses = checkNotNull (nameServerAddresses , "nameServerAddresses" );
158155 this .queryTimeoutMillis = checkPositive (queryTimeoutMillis , "queryTimeoutMillis" );
159156 this .resolvedAddressTypes = checkNonEmpty (resolvedAddressTypes , "resolvedAddressTypes" );
@@ -165,34 +162,28 @@ public DnsNameResolver(
165162 this .hostsFileEntriesResolver = checkNotNull (hostsFileEntriesResolver , "hostsFileEntriesResolver" );
166163 this .resolveCache = resolveCache ;
167164
168- bindFuture = newChannel (channelFactory , localAddress );
169- ch = (DatagramChannel ) bindFuture .channel ();
170- ch .config ().setRecvByteBufAllocator (new FixedRecvByteBufAllocator (maxPayloadSize ));
171- }
172-
173- private ChannelFuture newChannel (
174- ChannelFactory <? extends DatagramChannel > channelFactory , InetSocketAddress localAddress ) {
175-
176165 Bootstrap b = new Bootstrap ();
177166 b .group (executor ());
178167 b .channelFactory (channelFactory );
179- final DnsResponseHandler responseHandler = new DnsResponseHandler ();
168+ b .option (ChannelOption .DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION , true );
169+ final DnsResponseHandler responseHandler = new DnsResponseHandler (executor ().<Channel >newPromise ());
180170 b .handler (new ChannelInitializer <DatagramChannel >() {
181171 @ Override
182172 protected void initChannel (DatagramChannel ch ) throws Exception {
183173 ch .pipeline ().addLast (DECODER , ENCODER , responseHandler );
184174 }
185175 });
186176
187- ChannelFuture bindFuture = b .bind (localAddress );
188- bindFuture .channel ().closeFuture ().addListener (new ChannelFutureListener () {
177+ channelFuture = responseHandler .channelActivePromise ;
178+ ch = (DatagramChannel ) b .register ().channel ();
179+ ch .config ().setRecvByteBufAllocator (new FixedRecvByteBufAllocator (maxPayloadSize ));
180+
181+ ch .closeFuture ().addListener (new ChannelFutureListener () {
189182 @ Override
190183 public void operationComplete (ChannelFuture future ) throws Exception {
191184 resolveCache .clear ();
192185 }
193186 });
194-
195- return bindFuture ;
196187 }
197188
198189 /**
@@ -336,7 +327,7 @@ private boolean doResolveCached(String hostname,
336327 Promise <InetAddress > promise ,
337328 DnsCache resolveCache ) {
338329 final List <DnsCacheEntry > cachedEntries = resolveCache .get (hostname );
339- if (cachedEntries == null ) {
330+ if (cachedEntries == null || cachedEntries . isEmpty () ) {
340331 return false ;
341332 }
342333
@@ -442,7 +433,7 @@ private boolean doResolveAllCached(String hostname,
442433 Promise <List <InetAddress >> promise ,
443434 DnsCache resolveCache ) {
444435 final List <DnsCacheEntry > cachedEntries = resolveCache .get (hostname );
445- if (cachedEntries == null ) {
436+ if (cachedEntries == null || cachedEntries . isEmpty () ) {
446437 return false ;
447438 }
448439
@@ -605,6 +596,13 @@ private static Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> cast(P
605596 }
606597
607598 private final class DnsResponseHandler extends ChannelInboundHandlerAdapter {
599+
600+ private final Promise <Channel > channelActivePromise ;
601+
602+ DnsResponseHandler (Promise <Channel > channelActivePromise ) {
603+ this .channelActivePromise = channelActivePromise ;
604+ }
605+
608606 @ Override
609607 public void channelRead (ChannelHandlerContext ctx , Object msg ) throws Exception {
610608 try {
@@ -627,6 +625,12 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
627625 }
628626 }
629627
628+ @ Override
629+ public void channelActive (ChannelHandlerContext ctx ) throws Exception {
630+ super .channelActive (ctx );
631+ channelActivePromise .setSuccess (ctx .channel ());
632+ }
633+
630634 @ Override
631635 public void exceptionCaught (ChannelHandlerContext ctx , Throwable cause ) throws Exception {
632636 logger .warn ("{} Unexpected exception: " , ch , cause );
0 commit comments