From e051b5f338c3f7b722a65d2dd1ee36178b44dfdd Mon Sep 17 00:00:00 2001 From: Aayush Atharva Date: Sat, 17 Oct 2020 23:52:43 +0530 Subject: [PATCH] Add `null` rule check in `rules` array of RuleBasedIpFilter (#10527) Motivation: We can filter out `null` rules while initializing the instance of `RuleBasedIpFilter` so we don't have to keep checking for `null` rules while iterating through `rules` array in `for loop` which is just a waste of CPU cycles. Modification: Added `null` rule check inside the constructor. Result: No more wasting CPU cycles on check the `null` rule each time in `for loop` and makes the overall operation more faster. --- .../handler/ipfilter/RuleBasedIpFilter.java | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/handler/src/main/java/io/netty/handler/ipfilter/RuleBasedIpFilter.java b/handler/src/main/java/io/netty/handler/ipfilter/RuleBasedIpFilter.java index 99174dd2e7..8cf567c866 100644 --- a/handler/src/main/java/io/netty/handler/ipfilter/RuleBasedIpFilter.java +++ b/handler/src/main/java/io/netty/handler/ipfilter/RuleBasedIpFilter.java @@ -22,36 +22,71 @@ import io.netty.util.internal.ObjectUtil; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.List; /** + *

* This class allows one to filter new {@link Channel}s based on the * {@link IpFilterRule}s passed to its constructor. If no rules are provided, all connections * will be accepted. + *

* + *

* If you would like to explicitly take action on rejected {@link Channel}s, you should override * {@link AbstractRemoteAddressFilter#channelRejected(ChannelHandlerContext, SocketAddress)}. + *

+ * + *

Consider using {@link IpSubnetFilter} for better performance while not as + * general purpose as this filter.

*/ @Sharable public class RuleBasedIpFilter extends AbstractRemoteAddressFilter { - private final IpFilterRule[] rules; + private final boolean acceptIfNotFound; + private final List rules; + /** + *

Create new Instance of {@link RuleBasedIpFilter} and filter incoming connections + * based on their IP address and {@code rules} applied.

+ * + *

{@code acceptIfNotFound} is set to {@code true}.

+ * + * @param rules An array of {@link IpFilterRule} containing all rules. + */ public RuleBasedIpFilter(IpFilterRule... rules) { - this.rules = ObjectUtil.checkNotNull(rules, "rules"); + this(true, rules); + } + + /** + * Create new Instance of {@link RuleBasedIpFilter} and filter incoming connections + * based on their IP address and {@code rules} applied. + * + * @param acceptIfNotFound If {@code true} then accept connection from IP Address if it + * doesn't match any rule. + * @param rules An array of {@link IpFilterRule} containing all rules. + */ + public RuleBasedIpFilter(boolean acceptIfNotFound, IpFilterRule... rules) { + ObjectUtil.checkNotNull(rules, "rules"); + + this.acceptIfNotFound = acceptIfNotFound; + this.rules = new ArrayList(rules.length); + + for (IpFilterRule rule : rules) { + if (rule != null) { + this.rules.add(rule); + } + } } @Override protected boolean accept(ChannelHandlerContext ctx, InetSocketAddress remoteAddress) throws Exception { for (IpFilterRule rule : rules) { - if (rule == null) { - break; - } - if (rule.matches(remoteAddress)) { return rule.ruleType() == IpFilterRuleType.ACCEPT; } } - return true; + return acceptIfNotFound; } }