This commit is contained in:
zab2
2019-03-28 18:57:42 +00:00
parent 85db853d74
commit d90fc421fd
12 changed files with 144 additions and 1 deletions

View File

@ -4,14 +4,32 @@ import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
/**
* Counts connection attempts and decides if specified thresholds have been
* breached.
*
* @since 0.9.40
*/
class AccessCounter {
/**
* List of timestamps of each connection attempt
*/
private final List<Long> accesses = new ArrayList<Long>();
/**
* records that a connection attempt was made
*
* @param now the current time
*/
void recordAccess(long now) {
accesses.add(now);
}
/**
* @param threshold definition of a threshold
* @return true if the given threshold has been breached
*/
boolean isBreached(Threshold threshold) {
if (threshold.getConnections() == 0)
return !accesses.isEmpty();

View File

@ -22,6 +22,20 @@ import net.i2p.data.Hash;
import net.i2p.i2ptunnel.I2PTunnelTask;
import net.i2p.client.streaming.IncomingConnectionFilter;
/**
* A filter for incoming connections which can be configured
* based on access list rules.
*
* It keeps a track of known destinations - those defined in existing access
* lists and unknown ones - those who are not defined in such lists but have
* recently attempted to connect to us.
*
* Every SYNC_INTERVAL seconds the access lists are reloaded from disk which
* allows the user to edit them. Also, if any recorders are defined in the
* access rules, they will write to disk at such interval.
*
* @since 0.9.40
*/
class AccessFilter implements IncomingConnectionFilter {
private static final long PURGE_INTERVAL = 1000;
@ -40,6 +54,11 @@ class AccessFilter implements IncomingConnectionFilter {
*/
private final Map<Hash, DestTracker> unknownDests = new HashMap<Hash, DestTracker>();
/**
* @param context the context, used for scheduling and timer purposes
* @param definition definition of this filter
* @param task the task to query for liveness of the tunnel
*/
AccessFilter(I2PAppContext context, FilterDefinition definition, I2PTunnelTask task)
throws IOException {
this.context = context;
@ -56,7 +75,7 @@ class AccessFilter implements IncomingConnectionFilter {
public boolean allowDestination(Destination d) {
Hash hash = d.getHash();
long now = context.clock().now();
DestTracker tracker = null;
DestTracker tracker;
synchronized(knownDests) {
tracker = knownDests.get(hash);
}

View File

@ -7,8 +7,22 @@ import java.io.File;
import net.i2p.data.DataHelper;
/**
* Utility class for parsing filter definitions
*
* @since 0.9.40
*/
class DefinitionParser {
/**
* Processes an array of String objects containing the human-readable definition of
* the filter.
*
* TODO: format
*
* @return a FilterDefinition POJO representation for internal use
* @throws InvalidDefinitionException if the definition is malformed
*/
static FilterDefinition parse(String []definition) throws InvalidDefinitionException {
DefinitionBuilder builder = new DefinitionBuilder();

View File

@ -2,12 +2,21 @@ package net.i2p.i2ptunnel.access;
import net.i2p.data.Hash;
/**
* Tracks the connection attempts for a given remote Destination
*
* @since 0.9.40
*/
class DestTracker {
private final Hash hash;
private final Threshold threshold;
private final AccessCounter counter;
/**
* @param hash hash of the remote destination
* @param threshold threshold defined in the access rule
*/
DestTracker(Hash hash, Threshold threshold) {
this.hash = hash;
this.threshold = threshold;

View File

@ -4,10 +4,21 @@ import java.util.Map;
import net.i2p.data.Hash;
/**
* A filter definition element that includes a single, explicitly defined
* remote destination
*
* @since 0.9.40
*/
class ExplicitFilterDefinitionElement extends FilterDefinitionElement {
private final Hash hash;
/**
* @param b32 A string with the .b32 representation of the remote destination
* @param threshold threshold to apply to that destination
* @throws InvalidDefinitionException if the b32 string is not valid b32
*/
ExplicitFilterDefinitionElement(String b32, Threshold threshold) throws InvalidDefinitionException {
super(threshold);
this.hash = fromBase32(b32);

View File

@ -9,10 +9,20 @@ import java.io.IOException;
import net.i2p.data.Hash;
/**
* An element of filter definition that reads hashes of remote destinations
* from a file.
*
* @since 0.9.40
*/
class FileFilterDefinitionElement extends FilterDefinitionElement {
private final File file;
/**
* @param file file to read the remote destinations from
* @param threshold threshold to apply to all those destinations
*/
FileFilterDefinitionElement(File file, Threshold threshold) {
super(threshold);
this.file = file;

View File

@ -1,5 +1,12 @@
package net.i2p.i2ptunnel.access;
/**
* Definition of an access filter.
*
* This POJO contains the parsed representation from the filter definition file.
*
* @since 0.9.40
*/
class FilterDefinition {
private final Threshold defaultThreshold;
@ -7,6 +14,11 @@ class FilterDefinition {
private final Recorder[] recorders;
private final int purgeMinutes;
/**
* @param defaultThreshold threshold to apply to unknown remote destinations
* @param elements the elements defined in the filter definition, if any
* @param recorders the recorders defined in the filter definition, if any
*/
FilterDefinition(Threshold defaultThreshold,
FilterDefinitionElement[] elements,
Recorder[] recorders) {

View File

@ -6,6 +6,11 @@ import java.io.IOException;
import net.i2p.data.Hash;
import net.i2p.data.Base32;
/**
* Base class for elements found in filter definition files
*
* @since 0.9.40
*/
abstract class FilterDefinitionElement {
protected final Threshold threshold;
@ -14,12 +19,19 @@ abstract class FilterDefinitionElement {
this.threshold = threshold;
}
/**
* Updates the provided map with the hash(es) of remote destinations
* mentioned in this element
*/
abstract void update(Map<Hash, DestTracker> map) throws IOException;
Threshold getThreshold() {
return threshold;
}
/**
* Utility method to create a Hash object from a .b32 string
*/
protected static Hash fromBase32(String b32) throws InvalidDefinitionException {
if (!b32.endsWith(".b32.i2p"))
throw new InvalidDefinitionException("Invalid b32 " + b32);

View File

@ -12,7 +12,21 @@ import net.i2p.I2PAppContext;
import net.i2p.i2ptunnel.I2PTunnelTask;
import net.i2p.client.streaming.IncomingConnectionFilter;
/**
* Factory for incoming connection filters. Only public class in this package.
*
* @since 0.9.40
*/
public class FilterFactory {
/**
* Creates an instance of IncomingConnectionFilter based on the definition
* contained in the given file.
*
* @param context the context this is running in
* @param definition file containing the filter definition
* @param task the I2PTunnelTask instance to query for liveness
*/
public static IncomingConnectionFilter createFilter(I2PAppContext context,
File definition,
I2PTunnelTask task)

View File

@ -1,5 +1,9 @@
package net.i2p.i2ptunnel.access;
/**
* Exception thrown if the filter definition file cannot be
* parsed for some reason.
*/
public class InvalidDefinitionException extends Exception {
public InvalidDefinitionException(String reason) {
super(reason);

View File

@ -2,11 +2,22 @@ package net.i2p.i2ptunnel.access;
import java.io.File;
/**
* Definition of a recorder. If any remote destinations attempt
* enough connections to cause a breach of the specified threshold,
* their hash will be recorded in the specified file.
*
* @since 0.9.40
*/
class Recorder {
private final File file;
private final Threshold threshold;
/**
* @param file to record hashes of destinations that breach the threshold
* @param threshold the threshold that needs to be breached to trigger recording
*/
Recorder(File file, Threshold threshold) {
this.file = file;
this.threshold = threshold;

View File

@ -1,8 +1,17 @@
package net.i2p.i2ptunnel.access;
/**
* Definition of a Threshold.
*
* A Threshold is defined by a number of connections over a period of minutes
*
* @since 0.9.40
*/
class Threshold {
/** A Threshold that is never breached */
static final Threshold ALLOW = new Threshold(Integer.MAX_VALUE, 1);
/** A Threshold that is always breached */
static final Threshold DENY = new Threshold(0, 1);
private final int connections;