package com.limegroup.gnutella.filters;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.limewire.core.settings.FilterSettings;
import org.limewire.io.IpPort;
import org.limewire.io.IpPortSet;
import com.google.inject.Inject;
import com.limegroup.gnutella.Response;
import com.limegroup.gnutella.messages.BadPacketException;
import com.limegroup.gnutella.messages.Message;
import com.limegroup.gnutella.messages.QueryReply;
import com.limegroup.gnutella.spam.SpamManager;
/**
* Drops query replies containing multiple responses that all have similar
* alt-locs.
*/
class SameAltLocsFilter implements SpamFilter {
private static final Log LOG = LogFactory.getLog(SameAltLocsFilter.class);
private final SpamManager spamManager;
@Inject
SameAltLocsFilter(SpamManager spamManager) {
this.spamManager = spamManager;
}
@Override
public boolean allow(Message m) {
if(m instanceof QueryReply) {
Set<IpPort> sameAlts = null;
QueryReply q = (QueryReply)m;
try {
Response[] responses = q.getResultsArray();
int minResponses = FilterSettings.SAME_ALTS_MIN_RESPONSES.getValue();
if(responses.length < minResponses) {
if(LOG.isDebugEnabled())
LOG.debug("Allowing reply with " + responses.length + " responses");
return true;
}
int minAlts = FilterSettings.SAME_ALTS_MIN_ALTS.getValue();
float minOverlap = FilterSettings.SAME_ALTS_MIN_OVERLAP.getValue();
for(Response r : responses) {
Set<? extends IpPort> alts = r.getLocations();
if(alts.size() < minAlts) {
if(LOG.isDebugEnabled())
LOG.debug("Allowing reply with " + alts.size() + " alt-locs");
return true;
}
if(sameAlts == null) {
sameAlts = new IpPortSet(alts);
} else {
sameAlts.retainAll(alts);
if(sameAlts.size() < alts.size() * minOverlap) {
LOG.debug("Allowing reply with different alt-locs");
return true;
} else {
if(LOG.isDebugEnabled())
LOG.debug("Same " + sameAlts.size() + " alt-locs");
}
}
}
// Train the adaptive spam filter
if(FilterSettings.SAME_ALTS_ARE_SPAM.getValue())
spamManager.handleSpamQueryReply(q);
LOG.debug("Dropping reply");
return false;
} catch(BadPacketException bpe) {
return false;
}
}
return true;
}
}