From commits-return-7948-archive-asf-public=cust-asf.ponee.io@zookeeper.apache.org Tue Sep 10 16:50:45 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id F2B04180642 for ; Tue, 10 Sep 2019 18:50:44 +0200 (CEST) Received: (qmail 66622 invoked by uid 500); 10 Sep 2019 16:50:44 -0000 Mailing-List: contact commits-help@zookeeper.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@zookeeper.apache.org Delivered-To: mailing list commits@zookeeper.apache.org Received: (qmail 66611 invoked by uid 99); 10 Sep 2019 16:50:44 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 10 Sep 2019 16:50:44 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id CBC56812E2; Tue, 10 Sep 2019 16:50:43 +0000 (UTC) Date: Tue, 10 Sep 2019 16:50:43 +0000 To: "commits@zookeeper.apache.org" Subject: [zookeeper] branch master updated: ZOOKEEPER-3540: Avoid client port unavailable by skip binding the same client port during reconfig MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <156813424351.21071.13981279662407249592@gitbox.apache.org> From: eolivelli@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: zookeeper X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: f01d01ce3ba86baf9bd623f91d97a560703260e4 X-Git-Newrev: 8460f4ed48c5f9018d882bee2be748de42e965f9 X-Git-Rev: 8460f4ed48c5f9018d882bee2be748de42e965f9 X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated 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 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 Reviewers: Enrico Olivelli 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()); + } + +}