This is an automated email from the ASF dual-hosted git repository.
eolivelli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zookeeper.git
The following commit(s) were added to refs/heads/master by this push:
new 8460f4e ZOOKEEPER-3540: Avoid client port unavailable by skip binding
the same client port during reconfig
8460f4e is described below
commit 8460f4ed48c5f9018d882bee2be748de42e965f9
Author: Fangmin Lyu <[email protected]>
AuthorDate: Tue Sep 10 18:50:37 2019 +0200
ZOOKEEPER-3540: Avoid client port unavailable by skip binding the same
client port during reconfig
Author: Fangmin Lyu <[email protected]>
Reviewers: Enrico Olivelli <[email protected]>
Closes #1083 from lvfangmin/ZOOKEEPER-3540
---
.../zookeeper/server/NettyServerCnxnFactory.java | 15 +++++-
.../server/NettyServerCnxnFactoryTest.java | 61 ++++++++++++++++++++++
2 files changed, 75 insertions(+), 1 deletion(-)
diff --git
a/zookeeper-server/src/main/java/org/apache/zookeeper/server/NettyServerCnxnFactory.java
b/zookeeper-server/src/main/java/org/apache/zookeeper/server/NettyServerCnxnFactory.java
index fec7a86..dd5aa75 100644
---
a/zookeeper-server/src/main/java/org/apache/zookeeper/server/NettyServerCnxnFactory.java
+++
b/zookeeper-server/src/main/java/org/apache/zookeeper/server/NettyServerCnxnFactory.java
@@ -622,9 +622,18 @@ public class NettyServerCnxnFactory extends
ServerCnxnFactory {
}
public void reconfigure(InetSocketAddress addr) {
+ LOG.info("binding to port {}, {}", addr, localAddress);
+ if (addr != null && localAddress != null) {
+ if (addr.equals(localAddress) ||
(addr.getAddress().isAnyLocalAddress()
+ && localAddress.getAddress().isAnyLocalAddress()
+ && addr.getPort() == localAddress.getPort())) {
+ LOG.info("address is the same, skip rebinding");
+ return;
+ }
+ }
+
Channel oldChannel = parentChannel;
try {
- LOG.info("binding to port {}", addr);
parentChannel =
bootstrap.bind(addr).syncUninterruptibly().channel();
// Port changes after bind() if the original port was 0, update
// localAddress to get the real port.
@@ -734,4 +743,8 @@ public class NettyServerCnxnFactory extends
ServerCnxnFactory {
this.secure = secure;
}
+ // VisibleForTest
+ public Channel getParentChannel() {
+ return parentChannel;
+ }
}
diff --git
a/zookeeper-server/src/test/java/org/apache/zookeeper/server/NettyServerCnxnFactoryTest.java
b/zookeeper-server/src/test/java/org/apache/zookeeper/server/NettyServerCnxnFactoryTest.java
new file mode 100644
index 0000000..144ca3b
--- /dev/null
+++
b/zookeeper-server/src/test/java/org/apache/zookeeper/server/NettyServerCnxnFactoryTest.java
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server;
+
+import java.net.InetSocketAddress;
+import org.apache.zookeeper.PortAssignment;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class NettyServerCnxnFactoryTest {
+
+ @Test
+ public void testRebind() throws Exception {
+ InetSocketAddress addr = new
InetSocketAddress(PortAssignment.unique());
+ NettyServerCnxnFactory factory = new NettyServerCnxnFactory();
+ factory.configure(addr, 100, -1, false);
+ factory.start();
+ Assert.assertTrue(factory.getParentChannel().isActive());
+
+ factory.reconfigure(addr);
+
+ // wait the state change
+ Thread.sleep(100);
+
+ Assert.assertTrue(factory.getParentChannel().isActive());
+ }
+
+ @Test
+ public void testRebindIPv4IPv6() throws Exception {
+ int randomPort = PortAssignment.unique();
+ InetSocketAddress addr = new InetSocketAddress("0.0.0.0", randomPort);
+ NettyServerCnxnFactory factory = new NettyServerCnxnFactory();
+ factory.configure(addr, 100, -1, false);
+ factory.start();
+ Assert.assertTrue(factory.getParentChannel().isActive());
+
+ factory.reconfigure(new InetSocketAddress("[0:0:0:0:0:0:0:0]",
randomPort));
+
+ // wait the state change
+ Thread.sleep(100);
+
+ Assert.assertTrue(factory.getParentChannel().isActive());
+ }
+
+}