1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.firewall;
21
22 import java.net.InetSocketAddress;
23 import java.net.SocketAddress;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.locks.Lock;
28 import java.util.concurrent.locks.ReentrantLock;
29
30 import org.apache.mina.core.filterchain.IoFilter;
31 import org.apache.mina.core.filterchain.IoFilterAdapter;
32 import org.apache.mina.core.session.IoSession;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37
38
39
40
41
42 public class ConnectionThrottleFilter extends IoFilterAdapter {
43
44 private final static Logger LOGGER = LoggerFactory.getLogger(ConnectionThrottleFilter.class);
45
46
47 private static final long DEFAULT_TIME = 1000;
48
49
50
51
52
53 private long allowedInterval;
54
55
56 private final Map<String, Long> clients;
57
58
59 private Lock lock = new ReentrantLock();
60
61
62
63
64 private class ExpiredSessionThread extends Thread {
65 public void run() {
66
67 try {
68
69 Thread.sleep(allowedInterval);
70 } catch (InterruptedException e) {
71
72 return;
73 }
74
75
76
77 long currentTime = System.currentTimeMillis();
78
79 lock.lock();
80
81 try {
82 Iterator<String> sessions = clients.keySet().iterator();
83
84 while (sessions.hasNext()) {
85 String session = sessions.next();
86 long creationTime = clients.get(session);
87
88 if (creationTime + allowedInterval < currentTime) {
89 clients.remove(session);
90 }
91 }
92 } finally {
93 lock.unlock();
94 }
95 }
96 }
97
98
99
100
101 public ConnectionThrottleFilter() {
102 this(DEFAULT_TIME);
103 }
104
105
106
107
108
109
110
111
112
113 public ConnectionThrottleFilter(long allowedInterval) {
114 this.allowedInterval = allowedInterval;
115 clients = new ConcurrentHashMap<String, Long>();
116
117
118 ExpiredSessionThread cleanupThread = new ExpiredSessionThread();
119
120
121 cleanupThread.setDaemon(true);
122
123
124 cleanupThread.start();
125 }
126
127
128
129
130
131
132
133
134
135 public void setAllowedInterval(long allowedInterval) {
136 lock.lock();
137
138 try {
139 this.allowedInterval = allowedInterval;
140 } finally {
141 lock.unlock();
142 }
143 }
144
145
146
147
148
149
150
151
152
153
154 protected boolean isConnectionOk(IoSession session) {
155 SocketAddress remoteAddress = session.getRemoteAddress();
156
157 if (remoteAddress instanceof InetSocketAddress) {
158 InetSocketAddress addr = (InetSocketAddress) remoteAddress;
159 long now = System.currentTimeMillis();
160
161 lock.lock();
162
163 try {
164 if (clients.containsKey(addr.getAddress().getHostAddress())) {
165
166 if (LOGGER.isDebugEnabled()) {
167 LOGGER.debug("This is not a new client");
168 }
169
170 Long lastConnTime = clients.get(addr.getAddress().getHostAddress());
171
172 clients.put(addr.getAddress().getHostAddress(), now);
173
174
175
176 if (now - lastConnTime < allowedInterval) {
177 LOGGER.warn("Session connection interval too short");
178 return false;
179 }
180
181 return true;
182 }
183
184 clients.put(addr.getAddress().getHostAddress(), now);
185 } finally {
186 lock.unlock();
187 }
188
189 return true;
190 }
191
192 return false;
193 }
194
195 @Override
196 public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
197 if (!isConnectionOk(session)) {
198 LOGGER.warn("Connections coming in too fast; closing.");
199 session.closeNow();
200 }
201
202 nextFilter.sessionCreated(session);
203 }
204 }