Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit33d9ced

Browse files
committed
DnsNameResolver.resolve*(...) never notifies the Future when empty hostname is used,closeAsyncHttpClient#1330
Motivation:When an empty hostname is used in DnsNameResolver.resolve*(...) it willnever notify the future / promise. The root cause is that we notcorrectly guard against errors of IDN.toASCII(...) which will throw anIllegalArgumentException when it can not parse its input. That said weshould also handle an empty hostname the same way as the JDK does andjust use "localhost" when this happens.Modifications:- If the try to resolve an empty hostname we use localhost- Correctly guard against errors raised by IDN.toASCII(...) so we willalways noify the future / promise- Add unit test.Result:DnsNameResolver.resolve*(...) will always notify the future.
1 parent6b4f75d commit33d9ced

File tree

5 files changed

+372
-8
lines changed

5 files changed

+372
-8
lines changed

‎netty-bp/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
importjava.util.List;
6565
importjava.util.Set;
6666

67-
importstaticio.netty.util.internal.ObjectUtil2.*;
67+
importstaticio.netty.util.internal.ObjectUtil.*;
6868

6969
/**
7070
* A DNS-based {@link InetNameResolver}.
@@ -411,8 +411,11 @@ public final Future<InetAddress> resolve(String inetHost, Iterable<DnsRecord> ad
411411
*/
412412
publicfinalFuture<InetAddress>resolve(StringinetHost,Iterable<DnsRecord>additionals,
413413
Promise<InetAddress>promise) {
414-
checkNotNull(inetHost,"inetHost");
415414
checkNotNull(promise,"promise");
415+
if (inetHost ==null ||inetHost.isEmpty()) {
416+
// If an empty hostname is used we should use "localhost", just like InetAddress.getByName(...) does.
417+
returnpromise.setSuccess(loopbackAddress());
418+
}
416419
DnsRecord[]additionalsArray =toArray(additionals,true);
417420
try {
418421
doResolve(inetHost,additionalsArray,promise,resolveCache);
@@ -445,8 +448,13 @@ public final Future<List<InetAddress>> resolveAll(String inetHost, Iterable<DnsR
445448
*/
446449
publicfinalFuture<List<InetAddress>>resolveAll(StringinetHost,Iterable<DnsRecord>additionals,
447450
Promise<List<InetAddress>>promise) {
448-
checkNotNull(inetHost,"inetHost");
449451
checkNotNull(promise,"promise");
452+
453+
if (inetHost ==null ||inetHost.isEmpty()) {
454+
// If an empty hostname is used we should use "localhost", just like InetAddress.getAllByName(...) does.
455+
returnpromise.setSuccess(Collections.singletonList(loopbackAddress()));
456+
}
457+
450458
DnsRecord[]additionalsArray =toArray(additionals,true);
451459
try {
452460
doResolveAll(inetHost,additionalsArray,promise,resolveCache);
@@ -492,6 +500,12 @@ private static void validateAdditional(DnsRecord record, boolean validateType) {
492500
}
493501
}
494502

503+
@Override
504+
protectedfinalInetAddressloopbackAddress() {
505+
returnpreferredAddressType() ==InternetProtocolFamily2.IPv4 ?
506+
NetUtil2.LOCALHOST4 :NetUtil2.LOCALHOST6;
507+
}
508+
495509
/**
496510
* Hook designed for extensibility so one can pass a different cache on each resolution attempt
497511
* instead of using the global one.

‎netty-bp/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolverContext.java‎

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ public void operationComplete(Future<T> future) throws Exception {
147147
privatevoidinternalResolve(Promise<T>promise) {
148148
InetSocketAddressnameServerAddrToTry =nameServerAddrs.next();
149149
for (DnsRecordTypetype:parent.resolveRecordTypes()) {
150-
query(nameServerAddrToTry,newDefaultDnsQuestion(hostname,type),promise);
150+
if (!query(hostname,type,nameServerAddrToTry,promise)) {
151+
return;
152+
}
151153
}
152154
}
153155

@@ -383,7 +385,7 @@ void tryToFinishResolve(Promise<T> promise) {
383385
if (!triedCNAME) {
384386
// As the last resort, try to query CNAME, just in case the name server has it.
385387
triedCNAME =true;
386-
query(nameServerAddrs.next(),newDefaultDnsQuestion(hostname,DnsRecordType.CNAME),promise);
388+
query(hostname,DnsRecordType.CNAME,nameServerAddrs.next(),promise);
387389
return;
388390
}
389391
}
@@ -510,12 +512,25 @@ private void followCname(InetSocketAddress nameServerAddr, String name, String c
510512
}
511513

512514
finalInetSocketAddressnextAddr =nameServerAddrs.next();
513-
if (parent.isCnameFollowARecords()) {
514-
query(nextAddr,newDefaultDnsQuestion(cname,DnsRecordType.A),promise);
515+
if (parent.isCnameFollowARecords() && !query(hostname,DnsRecordType.A,nextAddr,promise)) {
516+
return;
515517
}
516518
if (parent.isCnameFollowAAAARecords()) {
517-
query(nextAddr,newDefaultDnsQuestion(cname,DnsRecordType.AAAA),promise);
519+
query(hostname,DnsRecordType.AAAA,nextAddr,promise);
520+
}
521+
}
522+
523+
privatebooleanquery(Stringhostname,DnsRecordTypetype,finalInetSocketAddressnextAddr,Promise<T>promise) {
524+
finalDnsQuestionquestion;
525+
try {
526+
question =newDefaultDnsQuestion(hostname,type);
527+
}catch (IllegalArgumentExceptione) {
528+
// java.net.IDN.toASCII(...) may throw an IllegalArgumentException if it fails to parse the hostname
529+
promise.tryFailure(e);
530+
returnfalse;
518531
}
532+
query(nextAddr,question,promise);
533+
returntrue;
519534
}
520535

521536
privatevoidaddTrace(InetSocketAddressnameServerAddr,Stringmsg) {

‎netty-bp/resolver/src/main/java/io/netty/resolver/InetNameResolver.java‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,21 @@
1717

1818
importio.netty.util.concurrent.EventExecutor;
1919
importio.netty.util.concurrent.Future;
20+
importio.netty.util.concurrent.Promise;
21+
importio.netty.util.internal.SocketUtils2;
2022

2123
importjava.net.InetAddress;
2224
importjava.net.InetSocketAddress;
25+
importjava.util.Collections;
26+
importjava.util.List;
2327

2428
/**
2529
* A skeletal {@link NameResolver} implementation that resolves {@link InetAddress}.
2630
*/
2731
publicabstractclassInetNameResolverextendsSimpleNameResolver<InetAddress> {
2832

33+
privatefinalInetAddressloopbackAddress;
34+
2935
privatevolatileAddressResolver<InetSocketAddress>addressResolver;
3036

3137
/**
@@ -34,6 +40,32 @@ public abstract class InetNameResolver extends SimpleNameResolver<InetAddress> {
3440
*/
3541
protectedInetNameResolver(EventExecutorexecutor) {
3642
super(executor);
43+
loopbackAddress =SocketUtils2.loopbackAddress();
44+
}
45+
46+
/**
47+
* Returns the {@link InetAddress} for loopback.
48+
*/
49+
protectedInetAddressloopbackAddress() {
50+
returnloopbackAddress;
51+
}
52+
53+
@Override
54+
publicFuture<InetAddress>resolve(StringinetHost,Promise<InetAddress>promise) {
55+
if (inetHost ==null ||inetHost.isEmpty()) {
56+
// If an empty hostname is used we should use "localhost", just like InetAddress.getByName(...) does.
57+
returnpromise.setSuccess(loopbackAddress());
58+
}
59+
returnsuper.resolve(inetHost,promise);
60+
}
61+
62+
@Override
63+
publicFuture<List<InetAddress>>resolveAll(StringinetHost,Promise<List<InetAddress>>promise) {
64+
if (inetHost ==null ||inetHost.isEmpty()) {
65+
// If an empty hostname is used we should use "localhost", just like InetAddress.getByName(...) does.
66+
returnpromise.setSuccess(Collections.singletonList(loopbackAddress()));
67+
}
68+
returnsuper.resolveAll(inetHost,promise);
3769
}
3870

3971
/**
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/*
2+
* Copyright 2016 The Netty Project
3+
*
4+
* The Netty Project licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
packageio.netty.util.internal;
17+
18+
importjava.io.IOException;
19+
importjava.net.InetAddress;
20+
importjava.net.InetSocketAddress;
21+
importjava.net.NetworkInterface;
22+
importjava.net.ServerSocket;
23+
importjava.net.Socket;
24+
importjava.net.SocketAddress;
25+
importjava.net.SocketException;
26+
importjava.net.SocketPermission;
27+
importjava.net.UnknownHostException;
28+
importjava.nio.channels.DatagramChannel;
29+
importjava.nio.channels.ServerSocketChannel;
30+
importjava.nio.channels.SocketChannel;
31+
importjava.security.AccessController;
32+
importjava.security.PrivilegedAction;
33+
importjava.security.PrivilegedActionException;
34+
importjava.security.PrivilegedExceptionAction;
35+
importjava.util.Enumeration;
36+
37+
/**
38+
* Provides socket operations with privileges enabled. This is necessary for applications that use the
39+
* {@link SecurityManager} to restrict {@link SocketPermission} to their application. By asserting that these
40+
* operations are privileged, the operations can proceed even if some code in the calling chain lacks the appropriate
41+
* {@link SocketPermission}.
42+
*/
43+
publicfinalclassSocketUtils2 {
44+
45+
privateSocketUtils2() {
46+
}
47+
48+
publicstaticvoidconnect(finalSocketsocket,finalSocketAddressremoteAddress,finalinttimeout)
49+
throwsIOException {
50+
try {
51+
AccessController.doPrivileged(newPrivilegedExceptionAction<Void>() {
52+
@Override
53+
publicVoidrun()throwsIOException {
54+
socket.connect(remoteAddress,timeout);
55+
returnnull;
56+
}
57+
});
58+
}catch (PrivilegedActionExceptione) {
59+
throw (IOException)e.getCause();
60+
}
61+
}
62+
63+
publicstaticvoidbind(finalSocketsocket,finalSocketAddressbindpoint)throwsIOException {
64+
try {
65+
AccessController.doPrivileged(newPrivilegedExceptionAction<Void>() {
66+
@Override
67+
publicVoidrun()throwsIOException {
68+
socket.bind(bindpoint);
69+
returnnull;
70+
}
71+
});
72+
}catch (PrivilegedActionExceptione) {
73+
throw (IOException)e.getCause();
74+
}
75+
}
76+
77+
publicstaticbooleanconnect(finalSocketChannelsocketChannel,finalSocketAddressremoteAddress)
78+
throwsIOException {
79+
try {
80+
returnAccessController.doPrivileged(newPrivilegedExceptionAction<Boolean>() {
81+
@Override
82+
publicBooleanrun()throwsIOException {
83+
returnsocketChannel.connect(remoteAddress);
84+
}
85+
});
86+
}catch (PrivilegedActionExceptione) {
87+
throw (IOException)e.getCause();
88+
}
89+
}
90+
91+
publicstaticvoidbind(finalSocketChannelsocketChannel,finalSocketAddressaddress)throwsIOException {
92+
try {
93+
AccessController.doPrivileged(newPrivilegedExceptionAction<Void>() {
94+
@Override
95+
publicVoidrun()throwsIOException {
96+
socketChannel.bind(address);
97+
returnnull;
98+
}
99+
});
100+
}catch (PrivilegedActionExceptione) {
101+
throw (IOException)e.getCause();
102+
}
103+
}
104+
105+
publicstaticSocketChannelaccept(finalServerSocketChannelserverSocketChannel)throwsIOException {
106+
try {
107+
returnAccessController.doPrivileged(newPrivilegedExceptionAction<SocketChannel>() {
108+
@Override
109+
publicSocketChannelrun()throwsIOException {
110+
returnserverSocketChannel.accept();
111+
}
112+
});
113+
}catch (PrivilegedActionExceptione) {
114+
throw (IOException)e.getCause();
115+
}
116+
}
117+
118+
publicstaticvoidbind(finalDatagramChannelnetworkChannel,finalSocketAddressaddress)throwsIOException {
119+
try {
120+
AccessController.doPrivileged(newPrivilegedExceptionAction<Void>() {
121+
@Override
122+
publicVoidrun()throwsIOException {
123+
networkChannel.bind(address);
124+
returnnull;
125+
}
126+
});
127+
}catch (PrivilegedActionExceptione) {
128+
throw (IOException)e.getCause();
129+
}
130+
}
131+
132+
publicstaticSocketAddresslocalSocketAddress(finalServerSocketsocket) {
133+
returnAccessController.doPrivileged(newPrivilegedAction<SocketAddress>() {
134+
@Override
135+
publicSocketAddressrun() {
136+
returnsocket.getLocalSocketAddress();
137+
}
138+
});
139+
}
140+
141+
publicstaticInetAddressaddressByName(finalStringhostname)throwsUnknownHostException {
142+
try {
143+
returnAccessController.doPrivileged(newPrivilegedExceptionAction<InetAddress>() {
144+
@Override
145+
publicInetAddressrun()throwsUnknownHostException {
146+
returnInetAddress.getByName(hostname);
147+
}
148+
});
149+
}catch (PrivilegedActionExceptione) {
150+
throw (UnknownHostException)e.getCause();
151+
}
152+
}
153+
154+
publicstaticInetAddress[]allAddressesByName(finalStringhostname)throwsUnknownHostException {
155+
try {
156+
returnAccessController.doPrivileged(newPrivilegedExceptionAction<InetAddress[]>() {
157+
@Override
158+
publicInetAddress[]run()throwsUnknownHostException {
159+
returnInetAddress.getAllByName(hostname);
160+
}
161+
});
162+
}catch (PrivilegedActionExceptione) {
163+
throw (UnknownHostException)e.getCause();
164+
}
165+
}
166+
167+
publicstaticInetSocketAddresssocketAddress(finalStringhostname,finalintport) {
168+
returnAccessController.doPrivileged(newPrivilegedAction<InetSocketAddress>() {
169+
@Override
170+
publicInetSocketAddressrun() {
171+
returnnewInetSocketAddress(hostname,port);
172+
}
173+
});
174+
}
175+
176+
publicstaticEnumeration<InetAddress>addressesFromNetworkInterface(finalNetworkInterfaceintf) {
177+
returnAccessController.doPrivileged(newPrivilegedAction<Enumeration<InetAddress>>() {
178+
@Override
179+
publicEnumeration<InetAddress>run() {
180+
returnintf.getInetAddresses();
181+
}
182+
});
183+
}
184+
185+
publicstaticInetAddressloopbackAddress() {
186+
returnAccessController.doPrivileged(newPrivilegedAction<InetAddress>() {
187+
@Override
188+
publicInetAddressrun() {
189+
if (PlatformDependent.javaVersion() >=7) {
190+
returnInetAddress.getLoopbackAddress();
191+
}
192+
try {
193+
returnInetAddress.getByName(null);
194+
}catch (UnknownHostExceptione) {
195+
thrownewIllegalStateException(e);
196+
}
197+
}
198+
});
199+
}
200+
201+
publicstaticbyte[]hardwareAddressFromNetworkInterface(finalNetworkInterfaceintf)throwsSocketException {
202+
try {
203+
returnAccessController.doPrivileged(newPrivilegedExceptionAction<byte[]>() {
204+
@Override
205+
publicbyte[]run()throwsSocketException {
206+
returnintf.getHardwareAddress();
207+
}
208+
});
209+
}catch (PrivilegedActionExceptione) {
210+
throw (SocketException)e.getCause();
211+
}
212+
}
213+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp