diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java index bc3ec2913a15e381c4103714c7e7d202fc90a044..94c9933e5805845a2bac479ca7bb5ec926477323 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java @@ -2,15 +2,28 @@ package net.i2p.i2ptunnel.access; import java.util.Map; import java.util.HashMap; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; +import java.io.File; +import java.io.FileReader; +import java.io.BufferedReader; +import java.io.FileWriter; +import java.io.BufferedWriter; import java.io.IOException; import net.i2p.I2PAppContext; +import net.i2p.util.SimpleTimer2; +import net.i2p.util.Log; import net.i2p.data.Destination; import net.i2p.client.streaming.IncomingConnectionFilter; class AccessFilter implements IncomingConnectionFilter { + private static final long PURGE_INTERVAL = 1000; + private static final long SYNC_INTERVAL = 10 * 1000; + private final FilterDefinition definition; private final I2PAppContext context; @@ -23,9 +36,14 @@ class AccessFilter implements IncomingConnectionFilter { */ private final Map<String, DestTracker> unknownDests = new HashMap<String, DestTracker>(); - AccessFilter(I2PAppContext context, FilterDefinition definition) { + AccessFilter(I2PAppContext context, FilterDefinition definition) throws IOException { this.context = context; this.definition = definition; + + reload(); + + new Purger(); + new Syncer(); } @Override @@ -56,4 +74,87 @@ class AccessFilter implements IncomingConnectionFilter { } } + + private void record() throws IOException { + for (Recorder recorder : definition.getRecorders()) { + Threshold threshold = recorder.getThreshold(); + File file = recorder.getFile(); + Set<String> breached = new HashSet<String>(); + synchronized(unknownDests) { + for (DestTracker tracker : unknownDests.values()) { + if (!tracker.getCounter().isBreached(threshold)) + continue; + breached.add(tracker.getB32()); + } + } + if (breached.isEmpty()) + continue; + + // if the file already exists, add previously breached b32s + if (file.exists() && file.isFile()) { + BufferedReader reader = new BufferedReader(new FileReader(file)); + try { + String b32; + while((b32 = reader.readLine()) != null) + breached.add(b32); + } finally { + if (reader != null) try { reader.close(); } catch (IOException ignored) {} + } + } + + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + try { + for (String b32 : breached) { + writer.write(b32); + writer.newLine(); + } + } finally { + if (writer != null) try { writer.close(); } catch (IOException ignored) {} + } + } + } + + private void purge() { + long olderThan = context.clock().now() - definition.getPurgeMinutes() * 60000; + + synchronized(knownDests) { + for (DestTracker tracker : knownDests.values()) + tracker.purge(olderThan); + } + + synchronized(unknownDests) { + for (Iterator<Map.Entry<String,DestTracker>> iter = unknownDests.entrySet().iterator(); + iter.hasNext();) { + Map.Entry<String,DestTracker> entry = iter.next(); + if (entry.getValue().purge(olderThan)) + iter.remove(); + } + } + } + + private class Purger extends SimpleTimer2.TimedEvent { + Purger() { + super(context.simpleTimer2(), PURGE_INTERVAL); + } + public void timeReached() { + purge(); + schedule(PURGE_INTERVAL); + } + } + + private class Syncer extends SimpleTimer2.TimedEvent { + Syncer() { + super(context.simpleTimer2(), SYNC_INTERVAL); + } + public void timeReached() { + try { + record(); + reload(); + schedule(SYNC_INTERVAL); + } catch (IOException bad) { + Log log = context.logManager().getLog(AccessFilter.class); + log.log(Log.CRIT, "syncing access list failed", bad); + } + } + } } diff --git a/build.properties b/build.properties index f7820e33a4692ba53a64b3bfdb10e9515dec7afa..706fd975e2ffb2ea5d12f8dfcb86ae9834f865ac 100644 --- a/build.properties +++ b/build.properties @@ -31,13 +31,13 @@ sloccount.report.file=sloccount.sc # Building EXEs in x64 Linux requires that 32bit libraries are installed. In Debian, # for example, installing the libc6-i386 package will satisfy this requirement. # Uncomment the next line to prevent building EXEs (changing it to false will have no impact) -#noExe=true +noExe=true # IzPack 5.1.x install dir #izpack5.home=/PATH/TO/IzPack # Change this to false if you don't have gettext or you want to prevent it from running during the build -require.gettext=true +require.gettext=false # Compile for this version of Java javac.version=1.7