Fix IpSubnetFilterRule with IPv6 Default Route does not accept all IPv6 addresses (#11351)

Motivation:

In this issue(https://github.com/netty/netty/issues/11349 ),IpSubnetFilterRule needs to support ipv6 reserved addresses, such as 8000::, but the current implementation does not support

Modification:

Added support for default rule

Result:

Fixes https://github.com/netty/netty/issues/11349

Signed-off-by: xingrufei <xingrufei@sogou-inc.com>
This commit is contained in:
skyguard1 2021-06-07 14:06:52 +08:00 committed by Norman Maurer
parent 7c0662007d
commit 21c3de9c69
2 changed files with 51 additions and 42 deletions

View File

@ -196,7 +196,7 @@ public final class IpSubnetFilterRule implements IpFilterRule, Comparable<IpSubn
final InetAddress inetAddress = remoteAddress.getAddress();
if (inetAddress instanceof Inet6Address) {
BigInteger ipAddress = ipToInt((Inet6Address) inetAddress);
return ipAddress.and(subnetMask).equals(networkAddress);
return ipAddress.and(subnetMask).equals(subnetMask) || ipAddress.and(subnetMask).equals(networkAddress);
}
return false;
}

View File

@ -29,44 +29,46 @@ import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class IpSubnetFilterTest {
@Test
public void testIpv4DefaultRoute() {
IpSubnetFilterRule rule = new IpSubnetFilterRule("0.0.0.0", 0, IpFilterRuleType.ACCEPT);
Assert.assertTrue(rule.matches(newSockAddress("91.114.240.43")));
Assert.assertTrue(rule.matches(newSockAddress("10.0.0.3")));
Assert.assertTrue(rule.matches(newSockAddress("192.168.93.2")));
assertTrue(rule.matches(newSockAddress("91.114.240.43")));
assertTrue(rule.matches(newSockAddress("10.0.0.3")));
assertTrue(rule.matches(newSockAddress("192.168.93.2")));
}
@Test
public void testIpv4SubnetMaskCorrectlyHandlesIpv6() {
IpSubnetFilterRule rule = new IpSubnetFilterRule("0.0.0.0", 0, IpFilterRuleType.ACCEPT);
Assert.assertFalse(rule.matches(newSockAddress("2001:db8:abcd:0000::1")));
assertFalse(rule.matches(newSockAddress("2001:db8:abcd:0000::1")));
}
@Test
public void testIpv6SubnetMaskCorrectlyHandlesIpv4() {
IpSubnetFilterRule rule = new IpSubnetFilterRule("::", 0, IpFilterRuleType.ACCEPT);
Assert.assertFalse(rule.matches(newSockAddress("91.114.240.43")));
assertFalse(rule.matches(newSockAddress("91.114.240.43")));
}
@Test
public void testIp4SubnetFilterRule() throws Exception {
IpSubnetFilterRule rule = new IpSubnetFilterRule("192.168.56.1", 24, IpFilterRuleType.ACCEPT);
for (int i = 0; i <= 255; i++) {
Assert.assertTrue(rule.matches(newSockAddress(String.format("192.168.56.%d", i))));
assertTrue(rule.matches(newSockAddress(String.format("192.168.56.%d", i))));
}
Assert.assertFalse(rule.matches(newSockAddress("192.168.57.1")));
assertFalse(rule.matches(newSockAddress("192.168.57.1")));
rule = new IpSubnetFilterRule("91.114.240.1", 23, IpFilterRuleType.ACCEPT);
Assert.assertTrue(rule.matches(newSockAddress("91.114.240.43")));
Assert.assertTrue(rule.matches(newSockAddress("91.114.240.255")));
Assert.assertTrue(rule.matches(newSockAddress("91.114.241.193")));
Assert.assertTrue(rule.matches(newSockAddress("91.114.241.254")));
Assert.assertFalse(rule.matches(newSockAddress("91.115.241.2")));
assertTrue(rule.matches(newSockAddress("91.114.240.43")));
assertTrue(rule.matches(newSockAddress("91.114.240.255")));
assertTrue(rule.matches(newSockAddress("91.114.241.193")));
assertTrue(rule.matches(newSockAddress("91.114.241.254")));
assertFalse(rule.matches(newSockAddress("91.115.241.2")));
}
@Test
@ -74,9 +76,16 @@ public class IpSubnetFilterTest {
IpSubnetFilterRule rule;
rule = new IpSubnetFilterRule("2001:db8:abcd:0000::", 52, IpFilterRuleType.ACCEPT);
Assert.assertTrue(rule.matches(newSockAddress("2001:db8:abcd:0000::1")));
Assert.assertTrue(rule.matches(newSockAddress("2001:db8:abcd:0fff:ffff:ffff:ffff:ffff")));
Assert.assertFalse(rule.matches(newSockAddress("2001:db8:abcd:1000::")));
assertTrue(rule.matches(newSockAddress("2001:db8:abcd:0000::1")));
assertTrue(rule.matches(newSockAddress("2001:db8:abcd:0fff:ffff:ffff:ffff:ffff")));
assertFalse(rule.matches(newSockAddress("2001:db8:abcd:1000::")));
}
@Test
public void testIp6SubnetFilterDefaultRule() {
IpFilterRule rule = new IpSubnetFilterRule("::", 0, IpFilterRuleType.ACCEPT);
assertTrue(rule.matches(newSockAddress("7FFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF")));
assertTrue(rule.matches(newSockAddress("8000::")));
}
@Test
@ -98,8 +107,8 @@ public class IpSubnetFilterTest {
@Override
protected ChannelFuture channelRejected(ChannelHandlerContext ctx, InetSocketAddress remoteAddress) {
Assert.assertTrue(ctx.channel().isActive());
Assert.assertTrue(ctx.channel().isWritable());
assertTrue(ctx.channel().isActive());
assertTrue(ctx.channel().isWritable());
Assert.assertEquals("192.168.57.1", remoteAddress.getHostName());
return ctx.writeAndFlush(Unpooled.wrappedBuffer(message));
@ -111,8 +120,8 @@ public class IpSubnetFilterTest {
for (byte i = 1; i <= 7; i++) {
Assert.assertEquals(i, out.readByte());
}
Assert.assertFalse(chDeny.isActive());
Assert.assertFalse(chDeny.isOpen());
assertFalse(chDeny.isActive());
assertFalse(chDeny.isOpen());
RuleBasedIpFilter allowHandler = new RuleBasedIpFilter(filter0) {
@Override
@ -122,8 +131,8 @@ public class IpSubnetFilterTest {
}
};
EmbeddedChannel chAllow = newEmbeddedInetChannel("192.168.57.2", allowHandler);
Assert.assertTrue(chAllow.isActive());
Assert.assertTrue(chAllow.isOpen());
assertTrue(chAllow.isActive());
assertTrue(chAllow.isOpen());
}
@Test
@ -131,17 +140,17 @@ public class IpSubnetFilterTest {
UniqueIpFilter handler = new UniqueIpFilter();
EmbeddedChannel ch1 = newEmbeddedInetChannel("91.92.93.1", handler);
Assert.assertTrue(ch1.isActive());
assertTrue(ch1.isActive());
EmbeddedChannel ch2 = newEmbeddedInetChannel("91.92.93.2", handler);
Assert.assertTrue(ch2.isActive());
assertTrue(ch2.isActive());
EmbeddedChannel ch3 = newEmbeddedInetChannel("91.92.93.1", handler);
Assert.assertFalse(ch3.isActive());
assertFalse(ch3.isActive());
// false means that no data is left to read/write
Assert.assertFalse(ch1.finish());
assertFalse(ch1.finish());
EmbeddedChannel ch4 = newEmbeddedInetChannel("91.92.93.1", handler);
Assert.assertTrue(ch4.isActive());
assertTrue(ch4.isActive());
}
@Test
@ -156,39 +165,39 @@ public class IpSubnetFilterTest {
// 1.0.0.0/8
EmbeddedChannel ch1 = newEmbeddedInetChannel("1.1.1.1", new IpSubnetFilter(ipSubnetFilterRuleList));
Assert.assertFalse(ch1.isActive());
Assert.assertTrue(ch1.close().isSuccess());
assertFalse(ch1.isActive());
assertTrue(ch1.close().isSuccess());
// Nothing applies here
EmbeddedChannel ch2 = newEmbeddedInetChannel("2.2.2.2", new IpSubnetFilter(ipSubnetFilterRuleList));
Assert.assertTrue(ch2.isActive());
Assert.assertTrue(ch2.close().isSuccess());
assertTrue(ch2.isActive());
assertTrue(ch2.close().isSuccess());
// 108.0.0.0/4
EmbeddedChannel ch3 = newEmbeddedInetChannel("97.100.100.100", new IpSubnetFilter(ipSubnetFilterRuleList));
Assert.assertFalse(ch3.isActive());
Assert.assertTrue(ch3.close().isSuccess());
assertFalse(ch3.isActive());
assertTrue(ch3.close().isSuccess());
// 200.200.200.200/32
EmbeddedChannel ch4 = newEmbeddedInetChannel("200.200.200.200", new IpSubnetFilter(ipSubnetFilterRuleList));
Assert.assertFalse(ch4.isActive());
Assert.assertTrue(ch4.close().isSuccess());
assertFalse(ch4.isActive());
assertTrue(ch4.close().isSuccess());
// Nothing applies here
EmbeddedChannel ch5 = newEmbeddedInetChannel("127.0.0.1", new IpSubnetFilter(ipSubnetFilterRuleList));
Assert.assertTrue(ch5.isActive());
Assert.assertTrue(ch5.close().isSuccess());
assertTrue(ch5.isActive());
assertTrue(ch5.close().isSuccess());
// 10.0.0.0/8
EmbeddedChannel ch6 = newEmbeddedInetChannel("10.1.1.2", new IpSubnetFilter(ipSubnetFilterRuleList));
Assert.assertFalse(ch6.isActive());
Assert.assertTrue(ch6.close().isSuccess());
assertFalse(ch6.isActive());
assertTrue(ch6.close().isSuccess());
//2001:db8:abcd:0000::/52
EmbeddedChannel ch7 = newEmbeddedInetChannel("2001:db8:abcd:1000::",
new IpSubnetFilter(ipSubnetFilterRuleList));
Assert.assertFalse(ch7.isActive());
Assert.assertTrue(ch7.close().isSuccess());
assertFalse(ch7.isActive());
assertTrue(ch7.close().isSuccess());
}
private static IpSubnetFilterRule buildRejectIP(String ipAddress, int mask) {