|
@@ -1,20 +1,22 @@
|
|
|
/*
|
|
|
- * This program is free software: you can redistribute it and/or modify it under
|
|
|
- * the terms of the GNU General Public License as published by the Free Software
|
|
|
- * Foundation, either version 3 of the License, or (at your option) any later
|
|
|
- * version.
|
|
|
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
|
|
|
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
|
|
|
+ * License, or (at your option) any later version.
|
|
|
*
|
|
|
- * This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
- * details.
|
|
|
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
|
|
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
+ * General Public License for more details.
|
|
|
*
|
|
|
- * You should have received a copy of the GNU General Public License along with
|
|
|
- * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
+ * You should have received a copy of the GNU General Public License along with this program. If
|
|
|
+ * not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
package net.sf.l2j.loginserver;
|
|
|
|
|
|
+import java.net.InetAddress;
|
|
|
import java.nio.channels.SocketChannel;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map.Entry;
|
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
@@ -28,28 +30,35 @@ import org.mmocore.network.MMOConnection;
|
|
|
import org.mmocore.network.ReceivablePacket;
|
|
|
|
|
|
/**
|
|
|
- *
|
|
|
- * @author KenM
|
|
|
+ *
|
|
|
+ * @author KenM
|
|
|
*/
|
|
|
-public class SelectorHelper implements IMMOExecutor<L2LoginClient>, IClientFactory<L2LoginClient>, IAcceptFilter
|
|
|
+public class SelectorHelper extends Thread implements IMMOExecutor<L2LoginClient>,
|
|
|
+ IClientFactory<L2LoginClient>, IAcceptFilter
|
|
|
{
|
|
|
+ private HashMap<Integer, Flood> _ipFloodMap;
|
|
|
private ThreadPoolExecutor _generalPacketsThreadPool;
|
|
|
-
|
|
|
- public SelectorHelper()
|
|
|
+
|
|
|
+ public SelectorHelper()
|
|
|
{
|
|
|
_generalPacketsThreadPool = new ThreadPoolExecutor(4, 6, 15L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
|
|
|
+ _ipFloodMap = new HashMap<Integer, Flood>();
|
|
|
+ super.setDaemon(true);
|
|
|
+ super.start();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * @see com.l2jserver.mmocore.network.IMMOExecutor#execute(com.l2jserver.mmocore.network.ReceivablePacket)
|
|
|
+ *
|
|
|
+ * @see org.mmocore.network.IMMOExecutor#execute(org.mmocore.network.ReceivablePacket)
|
|
|
*/
|
|
|
public void execute(ReceivablePacket<L2LoginClient> packet)
|
|
|
{
|
|
|
_generalPacketsThreadPool.execute(packet);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * @see com.l2jserver.mmocore.network.IClientFactory#create(com.l2jserver.mmocore.network.MMOConnection)
|
|
|
+ *
|
|
|
+ * @see org.mmocore.network.IClientFactory#create(org.mmocore.network.MMOConnection)
|
|
|
*/
|
|
|
public L2LoginClient create(MMOConnection<L2LoginClient> con)
|
|
|
{
|
|
@@ -57,12 +66,117 @@ public class SelectorHelper implements IMMOExecutor<L2LoginClient>, IClientFacto
|
|
|
client.sendPacket(new Init(client));
|
|
|
return client;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * @see com.l2jserver.mmocore.network.IAcceptFilter#accept(java.nio.channels.SocketChannel)
|
|
|
+ *
|
|
|
+ * @see org.mmocore.network.IAcceptFilter#accept(java.nio.channels.SocketChannel)
|
|
|
*/
|
|
|
public boolean accept(SocketChannel sc)
|
|
|
{
|
|
|
- return !LoginController.getInstance().isBannedAddress(sc.socket().getInetAddress());
|
|
|
+ InetAddress addr = sc.socket().getInetAddress();
|
|
|
+ int h = hash(addr.getAddress());
|
|
|
+
|
|
|
+ long current = System.currentTimeMillis();
|
|
|
+ Flood f;
|
|
|
+ synchronized (_ipFloodMap)
|
|
|
+ {
|
|
|
+ f = _ipFloodMap.get(h);
|
|
|
+ }
|
|
|
+ if (f != null)
|
|
|
+ {
|
|
|
+ if (f.trys == -1)
|
|
|
+ {
|
|
|
+ f.lastAccess = current;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (f.lastAccess + 1000 > current)
|
|
|
+ {
|
|
|
+ f.lastAccess = current;
|
|
|
+
|
|
|
+ if (f.trys >= 3)
|
|
|
+ {
|
|
|
+ f.trys = -1;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ f.trys++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ f.lastAccess = current;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ synchronized (_ipFloodMap)
|
|
|
+ {
|
|
|
+ _ipFloodMap.put(h, new Flood());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return !LoginController.getInstance().isBannedAddress(addr);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @param ip
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private int hash(byte[] ip)
|
|
|
+ {
|
|
|
+ return ip[0] & 0xFF | ip[1] << 8 & 0xFF00 | ip[2] << 16 & 0xFF0000 | ip[3] << 24
|
|
|
+ & 0xFF000000;
|
|
|
+ }
|
|
|
+
|
|
|
+ private class Flood
|
|
|
+ {
|
|
|
+ long lastAccess;
|
|
|
+ int trys;
|
|
|
+
|
|
|
+ Flood()
|
|
|
+ {
|
|
|
+ lastAccess = System.currentTimeMillis();
|
|
|
+ trys = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @see java.lang.Thread#run()
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void run()
|
|
|
+ {
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ long reference = System.currentTimeMillis() - (1000 * 300);
|
|
|
+ ArrayList<Integer> toRemove = new ArrayList<Integer>(50);
|
|
|
+ synchronized (_ipFloodMap)
|
|
|
+ {
|
|
|
+ for (Entry<Integer, Flood> e : _ipFloodMap.entrySet())
|
|
|
+ {
|
|
|
+ Flood f = e.getValue();
|
|
|
+ if (f.lastAccess < reference)
|
|
|
+ toRemove.add(e.getKey());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ synchronized (_ipFloodMap)
|
|
|
+ {
|
|
|
+ for (Integer i : toRemove)
|
|
|
+ {
|
|
|
+ _ipFloodMap.remove(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Thread.sleep(5000);
|
|
|
+ }
|
|
|
+ catch (InterruptedException e)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|