Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't strip scopeId when resolving ipv6 address #12019

Merged
merged 1 commit into from
Jan 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 53 additions & 0 deletions common/src/main/java/io/netty/util/NetUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,59 @@ public static byte[] createByteArrayFromIpAddressString(String ipAddressString)
return null;
}

/**
* Creates an {@link InetAddress} based on an ipAddressString or might return null if it can't be parsed.
* No error handling is performed here.
*/
public static InetAddress createInetAddressFromIpAddressString(String ipAddressString) {
if (isValidIpV4Address(ipAddressString)) {
byte[] bytes = validIpV4ToBytes(ipAddressString);
try {
return InetAddress.getByAddress(bytes);
} catch (UnknownHostException e) {
// Should never happen!
throw new IllegalStateException(e);
}
}

if (isValidIpV6Address(ipAddressString)) {
if (ipAddressString.charAt(0) == '[') {
ipAddressString = ipAddressString.substring(1, ipAddressString.length() - 1);
}

int percentPos = ipAddressString.indexOf('%');
if (percentPos >= 0) {
try {
int scopeId = Integer.parseInt(ipAddressString.substring(percentPos + 1));
ipAddressString = ipAddressString.substring(0, percentPos);
byte[] bytes = getIPv6ByName(ipAddressString, true);
if (bytes == null) {
return null;
}
try {
return Inet6Address.getByAddress(null, bytes, scopeId);
} catch (UnknownHostException e) {
// Should never happen!
throw new IllegalStateException(e);
}
} catch (NumberFormatException e) {
return null;
}
}
byte[] bytes = getIPv6ByName(ipAddressString, true);
if (bytes == null) {
return null;
}
try {
return InetAddress.getByAddress(bytes);
} catch (UnknownHostException e) {
// Should never happen!
throw new IllegalStateException(e);
}
}
return null;
}

private static int decimalDigit(String str, int pos) {
return str.charAt(pos) - '0';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -943,10 +943,10 @@ protected void doResolve(String inetHost,
promise.setSuccess(loopbackAddress());
return;
}
final byte[] bytes = NetUtil.createByteArrayFromIpAddressString(inetHost);
if (bytes != null) {
final InetAddress address = NetUtil.createInetAddressFromIpAddressString(inetHost);
if (address != null) {
// The inetHost is actually an ipaddress.
promise.setSuccess(InetAddress.getByAddress(bytes));
promise.setSuccess(address);
return;
}

Expand Down Expand Up @@ -1048,10 +1048,10 @@ protected void doResolveAll(String inetHost,
promise.setSuccess(Collections.singletonList(loopbackAddress()));
return;
}
final byte[] bytes = NetUtil.createByteArrayFromIpAddressString(inetHost);
if (bytes != null) {
final InetAddress address = NetUtil.createInetAddressFromIpAddressString(inetHost);
if (address != null) {
// The unresolvedAddress was created via a String that contains an ipaddress.
promise.setSuccess(Collections.singletonList(InetAddress.getByAddress(bytes)));
promise.setSuccess(Collections.singletonList(address));
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import java.io.InputStream;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
Expand Down Expand Up @@ -3541,4 +3542,96 @@ private static void assertNotEmptyAndRelease(Future<List<DnsRecord>> recordsFutu
ReferenceCountUtil.release(record);
}
}

@Test
public void testResolveIpv6WithScopeId() throws Exception {
testResolveIpv6WithScopeId0(false);
}

@Test
public void testResolveAllIpv6WithScopeId() throws Exception {
testResolveIpv6WithScopeId0(true);
}

private void testResolveIpv6WithScopeId0(boolean resolveAll) throws Exception {
DnsNameResolver resolver = newResolver().build();
String address = "fe80:0:0:0:1c31:d1d1:4824:72a9";
int scopeId = 15;
String addressString = address + '%' + scopeId;
byte[] bytes = NetUtil.createByteArrayFromIpAddressString(address);
Inet6Address inet6Address = Inet6Address.getByAddress(null, bytes, scopeId);
try {
final InetAddress addr;
if (resolveAll) {
List<InetAddress> addressList = resolver.resolveAll(addressString).getNow();
assertEquals(1, addressList.size());
addr = addressList.get(0);
} else {
addr = resolver.resolve(addressString).getNow();
}
assertEquals(inet6Address, addr);
} finally {
resolver.close();
}
}

@Test
public void testResolveIpv6WithoutScopeId() throws Exception {
testResolveIpv6WithoutScopeId0(false);
}

@Test
public void testResolveAllIpv6WithoutScopeId() throws Exception {
testResolveIpv6WithoutScopeId0(true);
}

private void testResolveIpv6WithoutScopeId0(boolean resolveAll) throws Exception {
DnsNameResolver resolver = newResolver().build();
String addressString = "fe80:0:0:0:1c31:d1d1:4824:72a9";
byte[] bytes = NetUtil.createByteArrayFromIpAddressString(addressString);
Inet6Address inet6Address = (Inet6Address) InetAddress.getByAddress(bytes);
try {
final InetAddress addr;
if (resolveAll) {
List<InetAddress> addressList = resolver.resolveAll(addressString).getNow();
assertEquals(1, addressList.size());
addr = addressList.get(0);
} else {
addr = resolver.resolve(addressString).getNow();
}
assertEquals(inet6Address, addr);
} finally {
resolver.close();
}
}

@Test
public void testResolveIp4() throws Exception {
testResolveIp4(false);
}

@Test
public void testResolveAllIp4() throws Exception {
testResolveIp4(true);
}

private void testResolveIp4(boolean resolveAll) throws Exception {
DnsNameResolver resolver = newResolver().build();
String addressString = "10.0.0.1";
byte[] bytes = NetUtil.createByteArrayFromIpAddressString(addressString);
InetAddress inetAddress = InetAddress.getByAddress(bytes);
try {
final InetAddress addr;
if (resolveAll) {
List<InetAddress> addressList = resolver.resolveAll(addressString).getNow();
assertEquals(1, addressList.size());
addr = addressList.get(0);
} else {
addr = resolver.resolve(addressString).getNow();
}
assertEquals(inetAddress, addr);
} finally {
resolver.close();
}
}
}