Package marauroa.server.net.validator

Source Code of marauroa.server.net.validator.ConnectionValidator

/* $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 java.net.InetAddress;
import java.net.Socket;
import java.nio.channels.SocketChannel;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import marauroa.common.Log4J;
import marauroa.server.game.db.BanListDAO;
import marauroa.server.game.db.DAORegister;

/**
* 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();
    }
  }
}
TOP

Related Classes of marauroa.server.net.validator.ConnectionValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.