package com.limegroup.gnutella.filters; import com.limegroup.gnutella.messages.Message; import com.limegroup.gnutella.messages.QueryRequest; /** * Stops queries that are bound to match too many files. * * Currently, queries that are blocked include "a.asf, d.mp3, etc." or * single-character searches. Additionally, queries such as "*.mp3" or * "mpg" or "*.*" are to be blocked, are at least set to travel less than * other queries. */ public class GreedyQueryFilter extends SpamFilter { private static final int GREEDY_QUERY_MAX = 3; public boolean allow(Message m) { if (! (m instanceof QueryRequest)) return true; QueryRequest qr = (QueryRequest)m; String query = qr.getQuery(); int n=query.length(); if (n==1 && !qr.hasQueryUrns()) return false; if ((n==5 || n==6) && query.charAt(1)=='.' && Character.isLetter(query.charAt(0)) ) return false; if (this.isVeryGeneralSearch(query) || this.isObfuscatedGeneralSearch(query)) { int hops = (int)m.getHops(); int ttl = (int)m.getTTL(); if (hops >= GreedyQueryFilter.GREEDY_QUERY_MAX) return false; if ( (hops + ttl) > GreedyQueryFilter.GREEDY_QUERY_MAX) m.setTTL((byte)(GreedyQueryFilter.GREEDY_QUERY_MAX - hops)); } return true; } /** * Search through a query string and see if matches a very general search * such as "*.*", "*.mp3", or "*.mpg" and check for uppercase also */ private boolean isVeryGeneralSearch(String queryString) { int length = queryString.length(); if ((length == 3) && ( (queryString.charAt(1) == '.') || (queryString.equalsIgnoreCase("mp3")) || (queryString.equalsIgnoreCase("mpg")) ) ) return true; if (length == 5) { //could by of type "*.mp3" or "*.mpg" String fileFormat = queryString.substring(2,5); if ((queryString.charAt(1) == '.') && ( (fileFormat.equalsIgnoreCase("mp3")) || (fileFormat.equalsIgnoreCase("mpg")) ) ) return true; } return false; //not a general search } /** To combat system-wide gnutella overflow, this method checks for * permutations of "*.*" */ private boolean isObfuscatedGeneralSearch(final String queryString) { final String unacceptable = "*.- "; for (int i = 0; i < queryString.length(); i++) // if a character is not one of the unacceptable strings, the query // is ok. if (unacceptable.indexOf(queryString.charAt(i)) == -1) return false; return true; } }