You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by nk...@apache.org on 2020/10/09 11:55:01 UTC
[zookeeper] branch branch-3.5 updated: ZOOKEEPER-3886: Client
connection string should support IPV6 with or without enclosed in square
bracket
This is an automated email from the ASF dual-hosted git repository.
nkalmar pushed a commit to branch branch-3.5
in repository https://gitbox.apache.org/repos/asf/zookeeper.git
The following commit(s) were added to refs/heads/branch-3.5 by this push:
new 5a149c5 ZOOKEEPER-3886: Client connection string should support IPV6 with or without enclosed in square bracket
5a149c5 is described below
commit 5a149c5a09b2c7dcac28d5b546c833fcc90f9934
Author: Mohammad Arshad <ar...@apache.org>
AuthorDate: Fri Oct 9 13:54:53 2020 +0200
ZOOKEEPER-3886: Client connection string should support IPV6 with or without enclosed in square bracket
…without enclosed in square bracket.
Author: Mohammad Arshad <ar...@apache.org>
Reviewers: Enrico Olivelli <eo...@apache.org>, Norbert Kalmar <nk...@apache.org>
Closes #1494 from arshadmohammad/ZOOKEEPER-3886-branch-3.5
---
.../zookeeper/client/ConnectStringParser.java | 21 ++++++---
.../java/org/apache/zookeeper/common/NetUtils.java | 45 ++++++++++++++++++
.../org/apache/zookeeper/common/NetUtilsTest.java | 54 ++++++++++++++++++++--
.../zookeeper/test/ConnectStringParserTest.java | 22 +++++++++
4 files changed, 132 insertions(+), 10 deletions(-)
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java b/zookeeper-server/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
index 085e44d..fe24fa2 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
@@ -18,6 +18,7 @@
package org.apache.zookeeper.client;
+import org.apache.zookeeper.common.NetUtils;
import org.apache.zookeeper.common.PathUtils;
import java.net.InetSocketAddress;
@@ -68,13 +69,21 @@ public final class ConnectStringParser {
List<String> hostsList = split(connectString,",");
for (String host : hostsList) {
int port = DEFAULT_PORT;
- int pidx = host.lastIndexOf(':');
- if (pidx >= 0) {
- // otherwise : is at the end of the string, ignore
- if (pidx < host.length() - 1) {
- port = Integer.parseInt(host.substring(pidx + 1));
+ String[] hostAndPort = NetUtils.getIPV6HostAndPort(host);
+ if (hostAndPort.length != 0) {
+ host = hostAndPort[0];
+ if (hostAndPort.length == 2) {
+ port = Integer.parseInt(hostAndPort[1]);
+ }
+ } else {
+ int pidx = host.lastIndexOf(':');
+ if (pidx >= 0) {
+ // otherwise : is at the end of the string, ignore
+ if (pidx < host.length() - 1) {
+ port = Integer.parseInt(host.substring(pidx + 1));
+ }
+ host = host.substring(0, pidx);
}
- host = host.substring(0, pidx);
}
serverAddresses.add(InetSocketAddress.createUnresolved(host, port));
}
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/NetUtils.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/NetUtils.java
index 4779003..a5f43d9 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/common/NetUtils.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/NetUtils.java
@@ -40,4 +40,49 @@ public class NetUtils {
return String.format("%s:%s", ia.getHostAddress(), addr.getPort());
}
}
+
+ /**
+ * Separates host and port from given host port string if host port string is enclosed
+ * within square bracket.
+ *
+ * @param hostPort host port string
+ * @return String[]{host, port} if host port string is host:port
+ * or String[] {host, port:port} if host port string is host:port:port
+ * or String[] {host} if host port string is host
+ * or String[]{} if not a ipv6 host port string.
+ */
+ public static String[] getIPV6HostAndPort(String hostPort) {
+ if (hostPort.startsWith("[")) {
+ int i = hostPort.lastIndexOf(']');
+ if (i < 0) {
+ throw new IllegalArgumentException(
+ hostPort + " starts with '[' but has no matching ']'");
+ }
+ String host = hostPort.substring(1, i);
+ if (host.isEmpty()) {
+ throw new IllegalArgumentException(host + " is empty.");
+ }
+ if (hostPort.length() > i + 1) {
+ return getHostPort(hostPort, i, host);
+ }
+ return new String[] { host };
+ } else {
+ //Not an IPV6 host port string
+ return new String[] {};
+ }
+ }
+
+ private static String[] getHostPort(String hostPort, int indexOfClosingBracket, String host) {
+ // [127::1]:2181 , check separator : exits
+ if (hostPort.charAt(indexOfClosingBracket + 1) != ':') {
+ throw new IllegalArgumentException(hostPort + " does not have : after ]");
+ }
+ // [127::1]: scenario
+ if (indexOfClosingBracket + 2 == hostPort.length()) {
+ throw new IllegalArgumentException(hostPort + " doesn't have a port after colon.");
+ }
+ //do not include
+ String port = hostPort.substring(indexOfClosingBracket + 2);
+ return new String[] { host, port };
+ }
}
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/common/NetUtilsTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/common/NetUtilsTest.java
index 4f8379e..81aff78 100644
--- a/zookeeper-server/src/test/java/org/apache/zookeeper/common/NetUtilsTest.java
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/common/NetUtilsTest.java
@@ -18,6 +18,7 @@
package org.apache.zookeeper.common;
+import static org.junit.Assert.assertEquals;
import org.apache.zookeeper.ZKTestCase;
import org.hamcrest.core.AnyOf;
import org.hamcrest.core.IsEqual;
@@ -38,21 +39,21 @@ public class NetUtilsTest extends ZKTestCase {
@Test
public void testFormatInetAddrGoodIpv4() {
InetSocketAddress isa = new InetSocketAddress(v4addr, port);
- Assert.assertEquals("127.0.0.1:1234", NetUtils.formatInetAddr(isa));
+ assertEquals("127.0.0.1:1234", NetUtils.formatInetAddr(isa));
}
@Test
public void testFormatInetAddrGoodIpv6Local() {
// Have to use the expanded address here, hence not using v6addr in instantiation
InetSocketAddress isa = new InetSocketAddress("::1", port);
- Assert.assertEquals(v6local, NetUtils.formatInetAddr(isa));
+ assertEquals(v6local, NetUtils.formatInetAddr(isa));
}
@Test
public void testFormatInetAddrGoodIpv6Ext() {
// Have to use the expanded address here, hence not using v6addr in instantiation
InetSocketAddress isa = new InetSocketAddress("2600::", port);
- Assert.assertEquals(v6ext, NetUtils.formatInetAddr(isa));
+ assertEquals(v6ext, NetUtils.formatInetAddr(isa));
}
@Test
@@ -67,6 +68,51 @@ public class NetUtilsTest extends ZKTestCase {
@Test
public void testFormatAddrUnresolved() {
InetSocketAddress isa = InetSocketAddress.createUnresolved("doesnt.exist.com", 1234);
- Assert.assertEquals("doesnt.exist.com:1234", NetUtils.formatInetAddr(isa));
+ assertEquals("doesnt.exist.com:1234", NetUtils.formatInetAddr(isa));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void tetGetIPV6HostAndPort_WhenHostDoesNotEndWithBracket() {
+ NetUtils.getIPV6HostAndPort("[2001:0db8:85a3:0000:0000:8a2e:0370:7334:443");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void tetGetIPV6HostAndPort_WhenNoPortAfterColon() {
+ NetUtils.getIPV6HostAndPort("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void tetGetIPV6HostAndPort_WhenPortIsNotSeparatedProperly() {
+ NetUtils.getIPV6HostAndPort("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]2181");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void tetGetIPV6HostAndPort_WhenHostIsEmpty() {
+ NetUtils.getIPV6HostAndPort("[]:2181");
+ }
+
+ @Test
+ public void tetGetIPV6HostAndPort_EmptyStringArrayIfDoesNotStartWithBracket() {
+ String[] ipv6HostAndPort =
+ NetUtils.getIPV6HostAndPort("2001:0db8:85a3:0000:0000:8a2e:0370:7334]");
+ assertEquals(0, ipv6HostAndPort.length);
+ }
+
+ @Test
+ public void tetGetIPV6HostAndPort_ReturnHostPort() {
+ String[] ipv6HostAndPort =
+ NetUtils.getIPV6HostAndPort("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:2181");
+ assertEquals(2, ipv6HostAndPort.length);
+ assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", ipv6HostAndPort[0]);
+ assertEquals("2181", ipv6HostAndPort[1]);
+ }
+
+ @Test
+ public void tetGetIPV6HostAndPort_ReturnHostPortPort() {
+ String[] ipv6HostAndPort =
+ NetUtils.getIPV6HostAndPort("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:2181:3181");
+ assertEquals(2, ipv6HostAndPort.length);
+ assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", ipv6HostAndPort[0]);
+ assertEquals("2181:3181", ipv6HostAndPort[1]);
}
}
\ No newline at end of file
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
index 393cc03..1444d69 100644
--- a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
@@ -65,4 +65,26 @@ public class ConnectStringParserTest extends ZKTestCase{
private void assertChrootPath(String expected, ConnectStringParser parser){
Assert.assertEquals(expected, parser.getChrootPath());
}
+
+ @Test
+ public void testParseIPV6ConnectionString() {
+ String servers = "[127::1],127.0.10.2";
+ ConnectStringParser parser = new ConnectStringParser(servers);
+
+ Assert.assertEquals("127::1", parser.getServerAddresses().get(0).getHostString());
+ Assert.assertEquals("127.0.10.2", parser.getServerAddresses().get(1).getHostString());
+ Assert.assertEquals(2181, parser.getServerAddresses().get(0).getPort());
+ Assert.assertEquals(2181, parser.getServerAddresses().get(1).getPort());
+
+ servers = "[127::1]:2181,[127::2]:2182,[127::3]:2183";
+ parser = new ConnectStringParser(servers);
+
+ Assert.assertEquals("127::1", parser.getServerAddresses().get(0).getHostString());
+ Assert.assertEquals("127::2", parser.getServerAddresses().get(1).getHostString());
+ Assert.assertEquals("127::3", parser.getServerAddresses().get(2).getHostString());
+ Assert.assertEquals(2181, parser.getServerAddresses().get(0).getPort());
+ Assert.assertEquals(2182, parser.getServerAddresses().get(1).getPort());
+ Assert.assertEquals(2183, parser.getServerAddresses().get(2).getPort());
+ }
+
}