package com.subgraph.orchid.data.exitpolicy;
import com.subgraph.orchid.TorParsingException;
import com.subgraph.orchid.data.IPv4Address;
public class PolicyRule {
private final static String WILDCARD = "*";
public static PolicyRule createAcceptFromString(String rule) {
return createRule(rule, true);
}
public static PolicyRule createRejectFromString(String rule) {
return createRule(rule, false);
}
private static PolicyRule createRule(String rule, boolean isAccept) {
final String[] args = rule.split(":");
if(args.length != 2)
throw new TorParsingException("Could not parse exit policy rule: "+ rule);
return new PolicyRule(parseNetwork(args[0]), parsePortRange(args[1]), isAccept);
}
private static Network parseNetwork(String network) {
if(network.equals(WILDCARD))
return Network.ALL_ADDRESSES;
else
return Network.createFromString(network);
}
private static PortRange parsePortRange(String portRange) {
if(portRange.equals(WILDCARD))
return PortRange.ALL_PORTS;
else
return PortRange.createFromString(portRange);
}
private final boolean isAcceptRule;
private final Network network;
private final PortRange portRange;
private PolicyRule(Network network, PortRange portRange, boolean isAccept) {
this.network = network;
this.portRange = portRange;
this.isAcceptRule = isAccept;
}
public boolean matchesPort(int port) {
if(!network.equals(Network.ALL_ADDRESSES))
return false;
return portRange.rangeContains(port);
}
public boolean matchesDestination(IPv4Address address, int port) {
if(!network.contains(address))
return false;
return portRange.rangeContains(port);
}
public boolean isAcceptRule() {
return isAcceptRule;
}
public String toString() {
final String keyword = isAcceptRule ? "accept" : "reject";
return keyword + " "+ network + ":"+ portRange;
}
}