Forráskód Böngészése

Login Flood Protection - tnx Forsaiken

nBd 15 éve
szülő
commit
4efd19ed6e
1 módosított fájl, 136 hozzáadás és 22 törlés
  1. 136 22
      L2_GameServer/java/net/sf/l2j/loginserver/SelectorHelper.java

+ 136 - 22
L2_GameServer/java/net/sf/l2j/loginserver/SelectorHelper.java

@@ -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)
+			{
+				
+			}
+		}
 	}
 }