HADOOP-17542. IPV6 support in Netutils#createSocketAddress (#3217)
* HADOOP-17542. IPV6 support in Netutils#createSocketAddress * HADOOP-17542. IPV6 support in Netutils#createSocketAddress, review comments
This commit is contained in:
parent
7118db5ee3
commit
c0f0b33e40
|
@ -199,8 +199,16 @@ public class Path
|
|||
int start = 0;
|
||||
|
||||
// parse uri scheme, if any
|
||||
int colon = pathString.indexOf(':');
|
||||
int colon = -1;
|
||||
int slash = pathString.indexOf('/');
|
||||
if (StringUtils.countMatches(pathString, ":") > 2) {
|
||||
//In case of IPv6 address, we should be able to parse the scheme
|
||||
// correctly (This will ensure to parse path with & without scheme
|
||||
// correctly in IPv6).
|
||||
colon = pathString.indexOf(":/");
|
||||
} else {
|
||||
colon = pathString.indexOf(':');
|
||||
}
|
||||
if ((colon != -1) &&
|
||||
((slash == -1) || (colon < slash))) { // has a scheme
|
||||
scheme = pathString.substring(0, colon);
|
||||
|
|
|
@ -45,6 +45,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hadoop.security.AccessControlException;
|
||||
import org.apache.hadoop.thirdparty.com.google.common.cache.Cache;
|
||||
import org.apache.hadoop.thirdparty.com.google.common.cache.CacheBuilder;
|
||||
|
@ -223,6 +224,22 @@ public class NetUtils {
|
|||
}
|
||||
target = target.trim();
|
||||
boolean hasScheme = target.contains("://");
|
||||
if (StringUtils.countMatches(target, ":") > 2) {
|
||||
// if scheme exists in the target
|
||||
// for example : https://ffff:ffff:ffff:ffff::1:XXXXX
|
||||
// we have to form https://[ffff:ffff:ffff:ffff::1]:XXXXX
|
||||
if (hasScheme) {
|
||||
int i = target.lastIndexOf("/");
|
||||
String scheme = target.substring(0, i + 1);
|
||||
String ipAddrWithPort = target.substring(i + 1);
|
||||
target = scheme + normalizeV6Address(ipAddrWithPort);
|
||||
} else {
|
||||
// if scheme does not exists in the target
|
||||
// for example : ffff:ffff:ffff:ffff::1:XXXXX
|
||||
// we have to form [ffff:ffff:ffff:ffff::1]:XXXXX
|
||||
target = normalizeV6Address(target);
|
||||
}
|
||||
}
|
||||
URI uri = createURI(target, hasScheme, helpText, useCacheIfPresent);
|
||||
|
||||
String host = uri.getHost();
|
||||
|
@ -275,6 +292,24 @@ public class NetUtils {
|
|||
return uri;
|
||||
}
|
||||
|
||||
public static String normalizeV6Address(String target) {
|
||||
if (!target.startsWith("[")) {
|
||||
if (target.contains("%")) {
|
||||
int i = target.lastIndexOf('%');
|
||||
target = target.trim();
|
||||
String port = target.substring(target.lastIndexOf(":") + 1);
|
||||
String addr = target.substring(0, i);
|
||||
target = "[" + addr + "]" + ":" + port;
|
||||
} else {
|
||||
int i = target.lastIndexOf(':');
|
||||
String port = target.substring(target.lastIndexOf(":") + 1);
|
||||
String addr = target.substring(0, i);
|
||||
target = "[" + addr + "]" + ":" + port;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket address with the given host and port. The hostname
|
||||
* might be replaced with another host that was set via
|
||||
|
|
|
@ -817,4 +817,41 @@ public class TestNetUtils {
|
|||
String gotStr = StringUtils.join(got, ", ");
|
||||
assertEquals(expectStr, gotStr);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSocketAddressWithIPV6() throws Throwable {
|
||||
String ipv6Address = "2a03:2880:2130:cf05:face:b00c:0:1";
|
||||
String ipv6WithPort = ipv6Address + ":12345";
|
||||
|
||||
InetSocketAddress addr = NetUtils.createSocketAddr(ipv6WithPort,
|
||||
1000, "myconfig");
|
||||
assertEquals("[" + ipv6Address + "]", addr.getHostName());
|
||||
assertEquals(12345, addr.getPort());
|
||||
|
||||
String ipv6SampleAddressWithScope = ipv6Address + "%2";
|
||||
ipv6WithPort = ipv6SampleAddressWithScope + ":12345";
|
||||
addr = NetUtils.createSocketAddr(ipv6WithPort, 1000, "myconfig");
|
||||
assertEquals("[" + ipv6Address + "]", addr.getHostName());
|
||||
assertEquals(12345, addr.getPort());
|
||||
|
||||
ipv6Address = "[2a03:2880:2130:cf05:face:b00c:0:1]";
|
||||
ipv6WithPort = ipv6Address + ":12345";
|
||||
|
||||
addr = NetUtils.createSocketAddr(ipv6WithPort, 1000, "myconfig");
|
||||
assertEquals(ipv6Address, addr.getHostName());
|
||||
assertEquals(12345, addr.getPort());
|
||||
|
||||
String ipv6AddressWithScheme =
|
||||
"https://2a03:2880:2130:cf05:face:b00c:0:1:12345";
|
||||
addr = NetUtils.createSocketAddr(ipv6AddressWithScheme, 1000,
|
||||
"myconfig");
|
||||
assertEquals(ipv6Address, addr.getHostName());
|
||||
assertEquals(12345, addr.getPort());
|
||||
|
||||
ipv6AddressWithScheme = "https://[2a03:2880:2130:cf05:face:b00c:0:1]:12345";
|
||||
addr = NetUtils.createSocketAddr(ipv6AddressWithScheme, 1000,
|
||||
"myconfig");
|
||||
assertEquals(ipv6Address, addr.getHostName());
|
||||
assertEquals(12345, addr.getPort());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue