1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.ipfilter;
17
18 import io.netty.channel.Channel;
19 import io.netty.channel.ChannelHandler.Sharable;
20 import io.netty.channel.ChannelHandlerContext;
21 import io.netty.util.internal.ObjectUtil;
22
23 import java.net.Inet4Address;
24 import java.net.InetSocketAddress;
25 import java.net.SocketAddress;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.Iterator;
30 import java.util.List;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 @Sharable
55 public class IpSubnetFilter extends AbstractRemoteAddressFilter<InetSocketAddress> {
56
57 private final boolean acceptIfNotFound;
58 private final List<IpSubnetFilterRule> ipv4Rules;
59 private final List<IpSubnetFilterRule> ipv6Rules;
60 private final IpFilterRuleType ipFilterRuleTypeIPv4;
61 private final IpFilterRuleType ipFilterRuleTypeIPv6;
62
63
64
65
66
67
68
69 public IpSubnetFilter(IpSubnetFilterRule... rules) {
70 this(true, Arrays.asList(ObjectUtil.checkNotNull(rules, "rules")));
71 }
72
73
74
75
76
77
78
79
80 public IpSubnetFilter(boolean acceptIfNotFound, IpSubnetFilterRule... rules) {
81 this(acceptIfNotFound, Arrays.asList(ObjectUtil.checkNotNull(rules, "rules")));
82 }
83
84
85
86
87
88
89
90 public IpSubnetFilter(List<IpSubnetFilterRule> rules) {
91 this(true, rules);
92 }
93
94
95
96
97
98
99
100
101 public IpSubnetFilter(boolean acceptIfNotFound, List<IpSubnetFilterRule> rules) {
102 ObjectUtil.checkNotNull(rules, "rules");
103 this.acceptIfNotFound = acceptIfNotFound;
104
105 int numAcceptIPv4 = 0;
106 int numRejectIPv4 = 0;
107 int numAcceptIPv6 = 0;
108 int numRejectIPv6 = 0;
109
110 List<IpSubnetFilterRule> unsortedIPv4Rules = new ArrayList<IpSubnetFilterRule>();
111 List<IpSubnetFilterRule> unsortedIPv6Rules = new ArrayList<IpSubnetFilterRule>();
112
113
114 for (IpSubnetFilterRule ipSubnetFilterRule : rules) {
115 ObjectUtil.checkNotNull(ipSubnetFilterRule, "rule");
116
117 if (ipSubnetFilterRule.getFilterRule() instanceof IpSubnetFilterRule.Ip4SubnetFilterRule) {
118 unsortedIPv4Rules.add(ipSubnetFilterRule);
119
120 if (ipSubnetFilterRule.ruleType() == IpFilterRuleType.ACCEPT) {
121 numAcceptIPv4++;
122 } else {
123 numRejectIPv4++;
124 }
125 } else {
126 unsortedIPv6Rules.add(ipSubnetFilterRule);
127
128 if (ipSubnetFilterRule.ruleType() == IpFilterRuleType.ACCEPT) {
129 numAcceptIPv6++;
130 } else {
131 numRejectIPv6++;
132 }
133 }
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147 if (numAcceptIPv4 == 0 && numRejectIPv4 > 0) {
148 ipFilterRuleTypeIPv4 = IpFilterRuleType.REJECT;
149 } else if (numAcceptIPv4 > 0 && numRejectIPv4 == 0) {
150 ipFilterRuleTypeIPv4 = IpFilterRuleType.ACCEPT;
151 } else {
152 ipFilterRuleTypeIPv4 = null;
153 }
154
155 if (numAcceptIPv6 == 0 && numRejectIPv6 > 0) {
156 ipFilterRuleTypeIPv6 = IpFilterRuleType.REJECT;
157 } else if (numAcceptIPv6 > 0 && numRejectIPv6 == 0) {
158 ipFilterRuleTypeIPv6 = IpFilterRuleType.ACCEPT;
159 } else {
160 ipFilterRuleTypeIPv6 = null;
161 }
162
163 this.ipv4Rules = sortAndFilter(unsortedIPv4Rules);
164 this.ipv6Rules = sortAndFilter(unsortedIPv6Rules);
165 }
166
167 @Override
168 protected boolean accept(ChannelHandlerContext ctx, InetSocketAddress remoteAddress) {
169 if (remoteAddress.getAddress() instanceof Inet4Address) {
170 int indexOf = Collections.binarySearch(ipv4Rules, remoteAddress, IpSubnetFilterRuleComparator.INSTANCE);
171 if (indexOf >= 0) {
172 if (ipFilterRuleTypeIPv4 == null) {
173 return ipv4Rules.get(indexOf).ruleType() == IpFilterRuleType.ACCEPT;
174 } else {
175 return ipFilterRuleTypeIPv4 == IpFilterRuleType.ACCEPT;
176 }
177 }
178 } else {
179 int indexOf = Collections.binarySearch(ipv6Rules, remoteAddress, IpSubnetFilterRuleComparator.INSTANCE);
180 if (indexOf >= 0) {
181 if (ipFilterRuleTypeIPv6 == null) {
182 return ipv6Rules.get(indexOf).ruleType() == IpFilterRuleType.ACCEPT;
183 } else {
184 return ipFilterRuleTypeIPv6 == IpFilterRuleType.ACCEPT;
185 }
186 }
187 }
188
189 return acceptIfNotFound;
190 }
191
192
193
194
195
196
197
198
199 @SuppressWarnings("ConstantConditions")
200 private static List<IpSubnetFilterRule> sortAndFilter(List<IpSubnetFilterRule> rules) {
201 Collections.sort(rules);
202 Iterator<IpSubnetFilterRule> iterator = rules.iterator();
203 List<IpSubnetFilterRule> toKeep = new ArrayList<IpSubnetFilterRule>();
204
205 IpSubnetFilterRule parentRule = iterator.hasNext() ? iterator.next() : null;
206 if (parentRule != null) {
207 toKeep.add(parentRule);
208 }
209
210 while (iterator.hasNext()) {
211
212
213 IpSubnetFilterRule childRule = iterator.next();
214
215
216
217 if (!parentRule.matches(new InetSocketAddress(childRule.getIpAddress(), 1))) {
218 toKeep.add(childRule);
219
220 parentRule = childRule;
221 }
222 }
223
224 return toKeep;
225 }
226 }