package com.limegroup.gnutella.filters;
import java.net.InetAddress;
import java.net.UnknownHostException;
import com.limegroup.gnutella.messages.Message;
import com.limegroup.gnutella.messages.PingReply;
import com.limegroup.gnutella.messages.PushRequest;
import com.limegroup.gnutella.messages.QueryReply;
import com.limegroup.gnutella.settings.FilterSettings;
/**
* Blocks messages and hosts based on IP address. Formerly know as
* BlackListFilter. Immutable.
*/
public final class IPFilter extends SpamFilter {
private static IPFilter _instance;
private final IPList badHosts = new IPList();
private final IPList goodHosts = new IPList();
/** Constructs a new BlackListFilter containing the addresses listed
* in the SettingsManager. */
private IPFilter(){
String[] allHosts = FilterSettings.BLACK_LISTED_IP_ADDRESSES.getValue();
for (int i=0; i<allHosts.length; i++)
badHosts.add(allHosts[i]);
allHosts = FilterSettings.WHITE_LISTED_IP_ADDRESSES.getValue();
for (int i=0; i<allHosts.length; i++)
goodHosts.add(allHosts[i]);
}
/**
* Returns the current active instance of IPFilter.
*/
public static IPFilter instance() {
if( _instance == null )
_instance = new IPFilter();
return _instance;
}
/**
* Refresh the IPFilter's instance.
*/
public static void refreshIPFilter() {
_instance = new IPFilter();
}
/**
* Return the badList of the instance
*/
public IPList getBadHosts() {
return badHosts;
}
/**
* Checks if a given host is banned. This method will be
* called when accepting an incoming or outgoing connection.
* @param host preferably an IP in the form of A.B.C.D, but if
* it is a DNS name then a lookup will be performed.
* @return true if this host is allowed, false if it is banned
* or we are unable to create correct IP addr out of it.
*/
public boolean allow(String host) {
IP ip;
try {
ip = new IP(host);
} catch (IllegalArgumentException badHost) {
try {
InetAddress lookUp = InetAddress.getByName(host);
host = lookUp.getHostAddress();
ip = new IP(host);
} catch(UnknownHostException unknownHost) {
// could not look up this host.
return false;
} catch(IllegalArgumentException stillBadHost) {
// couldn't construct IP still.
return false;
}
}
return goodHosts.contains(ip) || !badHosts.contains(ip);
}
/**
* Checks to see if a given host is banned.
* @param host the host's IP in byte form.
*/
public boolean allow(byte[] host) {
IP ip;
try {
ip = new IP(host);
} catch(IllegalArgumentException badHost) {
return false;
}
return goodHosts.contains(ip) || !badHosts.contains(ip);
}
/**
* Checks if a given Message's host is banned.
* @return true if this Message's host is allowed, false if it is banned
* or we are unable to create correct IP addr out of it.
*/
public boolean allow(Message m) {
if (m instanceof PingReply) {
PingReply pr = (PingReply)m;
return allow(pr.getAddress());
} else if (m instanceof QueryReply) {
QueryReply qr = (QueryReply)m;
return allow(qr.getIPBytes());
} else if (m instanceof PushRequest) {
PushRequest push=(PushRequest)m;
return allow(push.getIP());
} else // we dont want to block other kinds of messages
return true;
}
}