From c0c95827efd0689681d0ca3a263dea4f2d563548 Mon Sep 17 00:00:00 2001 From: zab2 <zab2@mail.i2p> Date: Fri, 29 Mar 2019 16:27:10 +0000 Subject: [PATCH] add logic to start and stop filter timers --- .../net/i2p/i2ptunnel/I2PTunnelServer.java | 17 +++++++++-- .../i2p/i2ptunnel/access/AccessFilter.java | 30 ++++++++++++------- .../i2p/i2ptunnel/access/FilterFactory.java | 11 +++---- .../streaming/StatefulConnectionFilter.java | 19 ++++++++++++ 4 files changed, 57 insertions(+), 20 deletions(-) create mode 100644 apps/ministreaming/java/src/net/i2p/client/streaming/StatefulConnectionFilter.java diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java index ecbc9af606..b7d0015eae 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java @@ -40,6 +40,7 @@ import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketManagerFactory; import net.i2p.client.streaming.RouterRestartException; import net.i2p.client.streaming.IncomingConnectionFilter; +import net.i2p.client.streaming.StatefulConnectionFilter; import net.i2p.crypto.SigType; import net.i2p.data.Base64; import net.i2p.data.Hash; @@ -97,6 +98,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { private int DEFAULT_LOCALPORT = 4488; protected int localPort = DEFAULT_LOCALPORT; + private volatile StatefulConnectionFilter _filter; + /** * Non-blocking * @@ -223,16 +226,18 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { } } - IncomingConnectionFilter filter = IncomingConnectionFilter.ALLOW; if (getTunnel().filterDefinition != null) { File filterDefinition = new File(getTunnel().filterDefinition); I2PAppContext context = getTunnel().getContext(); try { - filter = FilterFactory.createFilter(context, filterDefinition, this); + _filter = FilterFactory.createFilter(context, filterDefinition); } catch (IOException | InvalidDefinitionException bad) { throw new IllegalArgumentException("Can't create socket manager", bad); } - } + } + + IncomingConnectionFilter filter = _filter == null ? IncomingConnectionFilter.ALLOW : _filter; + try { I2PSocketManager rv = I2PSocketManagerFactory.createDisconnectedManager(privData, getTunnel().host, portNum, props, filter); @@ -376,6 +381,9 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { */ public synchronized void startRunning() { connectManager(); + StatefulConnectionFilter filter = _filter; + if (filter != null) + filter.start(); // prevent JVM exit when running outside the router boolean isDaemon = getTunnel().getContext().isRouterContext(); Thread t = new I2PAppThread(this, "Server " + remoteHost + ':' + remotePort, isDaemon); @@ -430,6 +438,9 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { if (task != null) { task.close(forced); } + StatefulConnectionFilter filter = _filter; + if (filter != null) + filter.stop(); synchronized (lock) { if (!forced && sockMgr.listSockets().size() != 0) { l.log("There are still active connections!"); 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 eff55e38d5..b8c3a3dfd0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.Set; import java.util.HashSet; import java.util.Iterator; +import java.util.concurrent.atomic.AtomicBoolean; import java.io.File; import java.io.FileReader; @@ -19,8 +20,7 @@ import net.i2p.util.Log; import net.i2p.util.SecureFileOutputStream; import net.i2p.data.Destination; import net.i2p.data.Hash; -import net.i2p.i2ptunnel.I2PTunnelTask; -import net.i2p.client.streaming.IncomingConnectionFilter; +import net.i2p.client.streaming.StatefulConnectionFilter; /** * A filter for incoming connections which can be configured @@ -36,14 +36,15 @@ import net.i2p.client.streaming.IncomingConnectionFilter; * * @since 0.9.40 */ -class AccessFilter implements IncomingConnectionFilter { +class AccessFilter implements StatefulConnectionFilter { private static final long PURGE_INTERVAL = 1000; private static final long SYNC_INTERVAL = 10 * 1000; private final FilterDefinition definition; private final I2PAppContext context; - private final I2PTunnelTask task; + + private final AtomicBoolean timersRunning = new AtomicBoolean(); /** * Trackers for known destinations defined in access lists @@ -59,16 +60,25 @@ class AccessFilter implements IncomingConnectionFilter { * @param definition definition of this filter * @param task the task to query for liveness of the tunnel */ - AccessFilter(I2PAppContext context, FilterDefinition definition, I2PTunnelTask task) + AccessFilter(I2PAppContext context, FilterDefinition definition) throws IOException { this.context = context; this.definition = definition; - this.task = task; reload(); + } - new Purger(); - new Syncer(); + @Override + public void start() { + if (timersRunning.compareAndSet(false, true)) { + new Purger(); + new Syncer(); + } + } + + @Override + public void stop() { + timersRunning.set(false); } @Override @@ -169,7 +179,7 @@ class AccessFilter implements IncomingConnectionFilter { super(context.simpleTimer2(), PURGE_INTERVAL); } public void timeReached() { - if (!task.isOpen()) { + if (!timersRunning.get()) { synchronized(knownDests) { knownDests.clear(); } @@ -188,7 +198,7 @@ class AccessFilter implements IncomingConnectionFilter { super(context.simpleTimer2(), SYNC_INTERVAL); } public void timeReached() { - if (!task.isOpen()) + if (!timersRunning.get()) return; try { record(); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FilterFactory.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FilterFactory.java index 54267d6e09..e7c84ea55c 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FilterFactory.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FilterFactory.java @@ -9,8 +9,7 @@ import java.util.List; import java.util.ArrayList; import net.i2p.I2PAppContext; -import net.i2p.i2ptunnel.I2PTunnelTask; -import net.i2p.client.streaming.IncomingConnectionFilter; +import net.i2p.client.streaming.StatefulConnectionFilter; /** * Factory for incoming connection filters. Only public class in this package. @@ -25,11 +24,9 @@ public class FilterFactory { * * @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) + public static StatefulConnectionFilter createFilter(I2PAppContext context, + File definition) throws IOException, InvalidDefinitionException { List<String> linesList = new ArrayList<String>(); @@ -50,6 +47,6 @@ public class FilterFactory { } FilterDefinition parsedDefinition = DefinitionParser.parse(linesList.toArray(new String[0])); - return new AccessFilter(context, parsedDefinition, task); + return new AccessFilter(context, parsedDefinition); } } diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/StatefulConnectionFilter.java b/apps/ministreaming/java/src/net/i2p/client/streaming/StatefulConnectionFilter.java new file mode 100644 index 0000000000..bb9ec065cd --- /dev/null +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/StatefulConnectionFilter.java @@ -0,0 +1,19 @@ +package net.i2p.client.streaming; + +/** + * A ConnectionFilter that may hold state, can be started and stopped + * @since 0.9.40 + */ +public interface StatefulConnectionFilter extends IncomingConnectionFilter { + + /** + * Tells this filter to start + */ + public void start(); + + /** + * Tells this filter to stop and release any resources + */ + public void stop(); + +} -- GitLab