/marauroa/src/marauroa/server/net/validator/ConnectionValidator.java
http://wastelanders.googlecode.com/ · Java · 216 lines · 86 code · 30 blank · 100 comment · 5 complexity · 30a582b29a5d48516b0562b2ed93a1ca MD5 · raw file
- /* $Id: ConnectionValidator.java,v 1.19 2009/08/01 19:06:45 nhnb Exp $ */
- /***************************************************************************
- * (C) Copyright 2003 - Marauroa *
- ***************************************************************************
- ***************************************************************************
- * *
- * 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
- package marauroa.server.net.validator;
- import marauroa.common.Log4J;
- import marauroa.server.game.db.BanListDAO;
- import marauroa.server.game.db.DAORegister;
- import java.net.InetAddress;
- import java.net.Socket;
- import java.nio.channels.SocketChannel;
- import java.sql.SQLException;
- import java.util.*;
- /**
- * The ConnectionValidator validates the ariving connections, currently it can
- * only check if the address is banned.
- * <p/>
- * There are two types of bans:
- * <ul>
- * <li>Permanent bans<br>
- * That are stored at database and that we offer no interface.
- * <li>Temportal bans<br>
- * That are not stored but that has a interface for adding, removing and
- * querying bans.
- * </ul>
- */
- public class ConnectionValidator implements Iterable<InetAddressMask> {
- /**
- * the logger instance.
- */
- private static final marauroa.common.Logger logger = Log4J.getLogger(ConnectionValidator.class);
- /**
- * Permanent bans are stored inside the database.
- */
- private List<InetAddressMask> permanentBans;
- /**
- * Temporal bans are added using the API and are lost on each server reset.
- * Consider using Database for a permanent ban
- */
- List<InetAddressMask> temporalBans;
- /**
- * A timer to remove ban when it is done.
- */
- private Timer timer;
- /* timestamp of last reload */
- private long lastLoadTS;
- /* How often do we reload ban information from database? Each 5 minutes */
- private final static long RELOAD_PERMANENT_BANS = 5 * 60 * 1000;
- /**
- * Constructor. It loads permanent bans from database.
- */
- public ConnectionValidator() {
- permanentBans = new LinkedList<InetAddressMask>();
- temporalBans = Collections.synchronizedList(new LinkedList<InetAddressMask>());
- /* read ban list from configuration */
- loadBannedIPNetworkListFromDB();
- timer = new Timer();
- }
- /**
- * Request connection validator to stop all the activity, and stop checking
- * if any ban needs to be removed.
- */
- public void finish() {
- timer.cancel();
- }
- /**
- * This class extend timer task to remove bans when the time is reached.
- *
- * @author miguel
- */
- private class RemoveBan extends TimerTask {
- private InetAddressMask mask;
- /**
- * Constructor
- *
- * @param mask
- */
- public RemoveBan(InetAddressMask mask) {
- this.mask = mask;
- }
- @Override
- public void run() {
- temporalBans.remove(mask);
- }
- }
- /**
- * Adds a ban just for this ip address for i seconds.
- *
- * @param channel the channel whose IP we are going to ban.
- * @param time how many seconds to ban.
- */
- public void addBan(SocketChannel channel, int time) {
- addBan(channel.socket().getInetAddress().getHostAddress(), "255.255.255.255", time);
- }
- /**
- * This adds a temporal ban.
- *
- * @param address the address to ban
- * @param mask mask to apply to the address
- * @param time how many seconds should the ban apply.
- */
- public void addBan(String address, String mask, long time) {
- InetAddressMask inetmask = new InetAddressMask(address, mask);
- timer.schedule(new RemoveBan(inetmask), time);
- temporalBans.add(inetmask);
- }
- /**
- * Removes one of the added temporal bans.
- *
- * @param address the address to remove
- * @param mask the mask used.
- * @return true if it has been removed.
- */
- public boolean removeBan(String address, String mask) {
- return temporalBans.remove(new InetAddressMask(address, mask));
- }
- /**
- * Returns an iterator over the temporal bans. To access permanent bans, use
- * database facility.
- */
- public Iterator<InetAddressMask> iterator() {
- return temporalBans.iterator();
- }
- /**
- * Is the source ip-address banned?
- *
- * @param address the InetAddress of the source
- * @return true if the source ip is banned
- */
- public synchronized boolean checkBanned(InetAddress address) {
- checkReload();
- for (InetAddressMask iam : temporalBans) {
- if (iam.matches(address)) {
- logger.debug("Address " + address + " is banned by " + iam);
- return true;
- }
- }
- for (InetAddressMask iam : permanentBans) {
- if (iam.matches(address)) {
- logger.debug("Address " + address + " is permanently banned by " + iam);
- return true;
- }
- }
- return false;
- }
- /**
- * Check if a socket that has a InetAddress associated is banned.
- *
- * @param socket the socket we want to check if it is banned or not.
- * @return true if it is banned.
- */
- public synchronized boolean checkBanned(Socket socket) {
- InetAddress address = socket.getInetAddress();
- return checkBanned(address);
- }
- /**
- * loads and initializes the ban list from a database
- */
- public synchronized void loadBannedIPNetworkListFromDB() {
- try {
- permanentBans.clear();
- permanentBans.addAll(DAORegister.get().get(BanListDAO.class).getBannedAddresses());
- } catch (SQLException sqle) {
- logger.error("cannot read banned networks database table", sqle);
- } catch (NullPointerException e) {
- logger.error("cannot read banned networks database table", e);
- }
- lastLoadTS = System.currentTimeMillis();
- }
- /**
- * checks if reload is necessary and performs it
- */
- public synchronized void checkReload() {
- if (System.currentTimeMillis() - lastLoadTS >= RELOAD_PERMANENT_BANS) {
- loadBannedIPNetworkListFromDB();
- }
- }
- }