18
18
import io .netty .bootstrap .Bootstrap ;
19
19
import io .netty .bootstrap .ChannelFactory ;
20
20
import io .netty .channel .AddressedEnvelope ;
21
+ import io .netty .channel .Channel ;
21
22
import io .netty .channel .ChannelFuture ;
22
23
import io .netty .channel .ChannelFutureListener ;
23
24
import io .netty .channel .ChannelHandlerContext ;
24
25
import io .netty .channel .ChannelInboundHandlerAdapter ;
25
26
import io .netty .channel .ChannelInitializer ;
27
+ import io .netty .channel .ChannelOption ;
26
28
import io .netty .channel .EventLoop ;
27
29
import io .netty .channel .FixedRecvByteBufAllocator ;
28
30
import io .netty .channel .socket .DatagramChannel ;
@@ -64,8 +66,6 @@ public class DnsNameResolver extends InetNameResolver {
64
66
private static final String LOCALHOST = "localhost" ;
65
67
private static final InetAddress LOCALHOST_ADDRESS ;
66
68
67
- static final InetSocketAddress ANY_LOCAL_ADDR = new InetSocketAddress (0 );
68
-
69
69
static final InternetProtocolFamily [] DEFAULT_RESOLVE_ADDRESS_TYPES = new InternetProtocolFamily [2 ];
70
70
71
71
static {
@@ -87,7 +87,7 @@ public class DnsNameResolver extends InetNameResolver {
87
87
private static final DatagramDnsQueryEncoder ENCODER = new DatagramDnsQueryEncoder ();
88
88
89
89
final DnsServerAddresses nameServerAddresses ;
90
- final ChannelFuture bindFuture ;
90
+ final Future < Channel > channelFuture ;
91
91
final DatagramChannel ch ;
92
92
93
93
/**
@@ -122,7 +122,6 @@ protected DnsServerAddressStream initialValue() throws Exception {
122
122
*
123
123
* @param eventLoop the {@link EventLoop} which will perform the communication with the DNS servers
124
124
* @param channelFactory the {@link ChannelFactory} that will create a {@link DatagramChannel}
125
- * @param localAddress the local address of the {@link DatagramChannel}
126
125
* @param nameServerAddresses the addresses of the DNS server. For each DNS query, a new stream is created from
127
126
* this to determine which DNS server should be contacted for the next retry in case
128
127
* of failure.
@@ -139,9 +138,8 @@ protected DnsServerAddressStream initialValue() throws Exception {
139
138
public DnsNameResolver (
140
139
EventLoop eventLoop ,
141
140
ChannelFactory <? extends DatagramChannel > channelFactory ,
142
- InetSocketAddress localAddress ,
143
141
DnsServerAddresses nameServerAddresses ,
144
- DnsCache resolveCache ,
142
+ final DnsCache resolveCache ,
145
143
long queryTimeoutMillis ,
146
144
InternetProtocolFamily [] resolvedAddressTypes ,
147
145
boolean recursionDesired ,
@@ -153,7 +151,6 @@ public DnsNameResolver(
153
151
154
152
super (eventLoop );
155
153
checkNotNull (channelFactory , "channelFactory" );
156
- checkNotNull (localAddress , "localAddress" );
157
154
this .nameServerAddresses = checkNotNull (nameServerAddresses , "nameServerAddresses" );
158
155
this .queryTimeoutMillis = checkPositive (queryTimeoutMillis , "queryTimeoutMillis" );
159
156
this .resolvedAddressTypes = checkNonEmpty (resolvedAddressTypes , "resolvedAddressTypes" );
@@ -165,34 +162,28 @@ public DnsNameResolver(
165
162
this .hostsFileEntriesResolver = checkNotNull (hostsFileEntriesResolver , "hostsFileEntriesResolver" );
166
163
this .resolveCache = resolveCache ;
167
164
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
-
176
165
Bootstrap b = new Bootstrap ();
177
166
b .group (executor ());
178
167
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 ());
180
170
b .handler (new ChannelInitializer <DatagramChannel >() {
181
171
@ Override
182
172
protected void initChannel (DatagramChannel ch ) throws Exception {
183
173
ch .pipeline ().addLast (DECODER , ENCODER , responseHandler );
184
174
}
185
175
});
186
176
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 () {
189
182
@ Override
190
183
public void operationComplete (ChannelFuture future ) throws Exception {
191
184
resolveCache .clear ();
192
185
}
193
186
});
194
-
195
- return bindFuture ;
196
187
}
197
188
198
189
/**
@@ -336,7 +327,7 @@ private boolean doResolveCached(String hostname,
336
327
Promise <InetAddress > promise ,
337
328
DnsCache resolveCache ) {
338
329
final List <DnsCacheEntry > cachedEntries = resolveCache .get (hostname );
339
- if (cachedEntries == null ) {
330
+ if (cachedEntries == null || cachedEntries . isEmpty () ) {
340
331
return false ;
341
332
}
342
333
@@ -442,7 +433,7 @@ private boolean doResolveAllCached(String hostname,
442
433
Promise <List <InetAddress >> promise ,
443
434
DnsCache resolveCache ) {
444
435
final List <DnsCacheEntry > cachedEntries = resolveCache .get (hostname );
445
- if (cachedEntries == null ) {
436
+ if (cachedEntries == null || cachedEntries . isEmpty () ) {
446
437
return false ;
447
438
}
448
439
@@ -605,6 +596,13 @@ private static Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> cast(P
605
596
}
606
597
607
598
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
+
608
606
@ Override
609
607
public void channelRead (ChannelHandlerContext ctx , Object msg ) throws Exception {
610
608
try {
@@ -627,6 +625,12 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
627
625
}
628
626
}
629
627
628
+ @ Override
629
+ public void channelActive (ChannelHandlerContext ctx ) throws Exception {
630
+ super .channelActive (ctx );
631
+ channelActivePromise .setSuccess (ctx .channel ());
632
+ }
633
+
630
634
@ Override
631
635
public void exceptionCaught (ChannelHandlerContext ctx , Throwable cause ) throws Exception {
632
636
logger .warn ("{} Unexpected exception: " , ch , cause );
0 commit comments