package com.subgraph.orchid.circuits.path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.subgraph.orchid.Router;
import com.subgraph.orchid.TorConfig;
public class TorConfigNodeFilter {
/*
* Even though these are exactly the configuration file variable names, they are only
* used here as keys into a Map<String,ConfigNodeFilter>
*/
private final static String EXCLUDE_NODES_FILTER = "ExcludeNodes";
private final static String EXCLUDE_EXIT_NODES_FILTER = "ExcludeExitNodes";
private final static String ENTRY_NODES_FILTER = "EntryNodes";
private final static String EXIT_NODES_FILTER = "ExitNodes";
private final Map<String, ConfigNodeFilter> filters;
TorConfigNodeFilter(TorConfig config) {
this.filters = new HashMap<String, ConfigNodeFilter>();
addFilter(filters, EXCLUDE_NODES_FILTER, config.getExcludeNodes());
addFilter(filters, EXCLUDE_EXIT_NODES_FILTER, config.getExcludeExitNodes());
addFilter(filters, ENTRY_NODES_FILTER, config.getEntryNodes());
addFilter(filters, EXIT_NODES_FILTER, config.getExitNodes());
}
private static void addFilter(Map<String, ConfigNodeFilter> filters, String name, List<String> filterStrings) {
if(filterStrings == null || filterStrings.isEmpty()) {
return;
}
filters.put(name, ConfigNodeFilter.createFromStrings(filterStrings));
}
List<Router> filterExitCandidates(List<Router> candidates) {
final List<Router> filtered = new ArrayList<Router>();
for(Router r: candidates) {
if(isExitNodeIncluded(r)) {
filtered.add(r);
}
}
return filtered;
}
boolean isExitNodeIncluded(Router exitRouter) {
return isIncludedByFilter(exitRouter, EXIT_NODES_FILTER) &&
!(isExcludedByFilter(exitRouter, EXCLUDE_EXIT_NODES_FILTER) ||
isExcludedByFilter(exitRouter, EXCLUDE_NODES_FILTER));
}
boolean isIncludedByFilter(Router r, String filterName) {
final ConfigNodeFilter f = filters.get(filterName);
if(f == null || f.isEmpty()) {
return true;
}
return f.filter(r);
}
boolean isExcludedByFilter(Router r, String filterName) {
final ConfigNodeFilter f = filters.get(filterName);
if(f == null || f.isEmpty()) {
return false;
}
return f.filter(r);
}
}