You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by ha...@apache.org on 2018/09/22 04:48:18 UTC

zookeeper git commit: ZOOKEEPER-3146: Limit the maximum client connections per IP in NettyServerCnxnFactory

Repository: zookeeper
Updated Branches:
  refs/heads/master e116d32b6 -> 4ebb847bc


ZOOKEEPER-3146: Limit the maximum client connections per IP in NettyServerCnxnFactory

Add similar max cnxn per ip throttling logic to Netty implementation.

Author: Fangmin Lyu <al...@fb.com>

Reviewers: hanm@apache.org

Closes #623 from lvfangmin/ZOOKEEPER-3146


Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo
Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/4ebb847b
Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/4ebb847b
Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/4ebb847b

Branch: refs/heads/master
Commit: 4ebb847bceb5ebd5c9fa53574f266c204f6f8ab7
Parents: e116d32
Author: Fangmin Lyu <al...@fb.com>
Authored: Fri Sep 21 21:48:13 2018 -0700
Committer: Michael Han <ha...@apache.org>
Committed: Fri Sep 21 21:48:13 2018 -0700

----------------------------------------------------------------------
 .../zookeeper/server/NettyServerCnxnFactory.java | 18 +++++++++++++++++-
 .../org/apache/zookeeper/test/SessionTest.java   | 19 +++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zookeeper/blob/4ebb847b/src/java/main/org/apache/zookeeper/server/NettyServerCnxnFactory.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/NettyServerCnxnFactory.java b/src/java/main/org/apache/zookeeper/server/NettyServerCnxnFactory.java
index ffb0d23..3e7c380 100644
--- a/src/java/main/org/apache/zookeeper/server/NettyServerCnxnFactory.java
+++ b/src/java/main/org/apache/zookeeper/server/NettyServerCnxnFactory.java
@@ -105,7 +105,17 @@ public class NettyServerCnxnFactory extends ServerCnxnFactory {
                 LOG.trace("Channel connected " + e);
             }
 
-            NettyServerCnxn cnxn = new NettyServerCnxn(ctx.getChannel(),
+            Channel channel = ctx.getChannel();
+            InetAddress addr = ((InetSocketAddress) channel.getRemoteAddress())
+                    .getAddress();
+            if (maxClientCnxns > 0 && getClientCnxnCount(addr) >= maxClientCnxns) {
+                LOG.warn("Too many connections from {} - max is {}", addr,
+                        maxClientCnxns);
+                channel.close();
+                return;
+            }
+
+            NettyServerCnxn cnxn = new NettyServerCnxn(channel,
                     zkServer, NettyServerCnxnFactory.this);
             ctx.setAttachment(cnxn);
 
@@ -537,6 +547,12 @@ public class NettyServerCnxnFactory extends ServerCnxnFactory {
         }
     }
 
+    private int getClientCnxnCount(InetAddress addr) {
+        Set<NettyServerCnxn> s = ipMap.get(addr);
+        if (s == null) return 0;
+        return s.size();
+    }
+
     @Override
     public void resetAllConnectionStats() {
         // No need to synchronize since cnxns is backed by a ConcurrentHashMap

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/4ebb847b/src/java/test/org/apache/zookeeper/test/SessionTest.java
----------------------------------------------------------------------
diff --git a/src/java/test/org/apache/zookeeper/test/SessionTest.java b/src/java/test/org/apache/zookeeper/test/SessionTest.java
index 4a74a78..889b65e 100644
--- a/src/java/test/org/apache/zookeeper/test/SessionTest.java
+++ b/src/java/test/org/apache/zookeeper/test/SessionTest.java
@@ -390,4 +390,23 @@ public class SessionTest extends ZKTestCase {
         zk.close();
         LOG.info(zk.toString());
     }
+
+    @Test
+    public void testMaximumCnxnPerIP() throws Exception {
+        final int maxClientCnxnsPerIP = 3;
+        serverFactory.setMaxClientCnxnsPerHost(maxClientCnxnsPerIP);
+        ZooKeeper[] clients = new ZooKeeper[maxClientCnxnsPerIP + 1];
+        for (int i = 0; i < clients.length; i++) {
+            CountdownWatcher watcher = new CountdownWatcher();
+            // wait for 3s
+            int timeout = 3000;
+            clients[i] = new DisconnectableZooKeeper(HOSTPORT, timeout, watcher);
+            boolean result = watcher.clientConnected.await(timeout, TimeUnit.MILLISECONDS);
+            if (i >= maxClientCnxnsPerIP) {
+                Assert.assertFalse(result);
+            } else {
+                Assert.assertTrue(result);
+            }
+        }
+    }
 }