From 22b2c4c3b8be75ad3ea97f115d1bc56fa46069d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9A=E5=B7=B4=E8=83=BA?= <1330456228zjp@gmail.com> Date: Fri, 7 Dec 2018 20:50:00 +0800 Subject: [PATCH] Fix concurrency problem in UniqueIpFilter (#8635) Motivation: If two requests from the same IP are reached at the same time, `connected.contains(remoteIp)` may return false in both threads. Modifications: Check if there is already a connection with the same IP using return values. Result: Become thread safe. --- .../handler/ipfilter/UniqueIpFilter.java | 3 +- .../handler/ipfilter/UniqueIpFilterTest.java | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 handler/src/test/java/io/netty/handler/ipfilter/UniqueIpFilterTest.java diff --git a/handler/src/main/java/io/netty/handler/ipfilter/UniqueIpFilter.java b/handler/src/main/java/io/netty/handler/ipfilter/UniqueIpFilter.java index ac346481d7..15099bb2a3 100644 --- a/handler/src/main/java/io/netty/handler/ipfilter/UniqueIpFilter.java +++ b/handler/src/main/java/io/netty/handler/ipfilter/UniqueIpFilter.java @@ -38,10 +38,9 @@ public class UniqueIpFilter extends AbstractRemoteAddressFilter future1 = newChannelAsync(barrier, executorService, ipFilter); + Future future2 = newChannelAsync(barrier, executorService, ipFilter); + EmbeddedChannel ch1 = future1.get(); + EmbeddedChannel ch2 = future2.get(); + Assert.assertTrue(ch1.isActive() || ch2.isActive()); + Assert.assertFalse(ch1.isActive() && ch2.isActive()); + + barrier.reset(); + ch1.close().await(); + ch2.close().await(); + } + } finally { + executorService.shutdown(); + } + } + + private static Future newChannelAsync(final CyclicBarrier barrier, + ExecutorService executorService, + final ChannelHandler... handler) { + return executorService.submit(new Callable() { + @Override + public EmbeddedChannel call() throws Exception { + barrier.await(); + return new EmbeddedChannel(handler) { + @Override + protected SocketAddress remoteAddress0() { + return isActive() ? SocketUtils.socketAddress("91.92.93.1", 5421) : null; + } + }; + } + }); + } + +}