I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 4588f1ec authored by zzz's avatar zzz
Browse files

I2CP: Periodically send a SetDate message to external clients

so they stay in sync
parent 629f7f05
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,7 @@ import java.util.Set; ...@@ -19,6 +19,7 @@ import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import net.i2p.CoreVersion;
import net.i2p.client.I2PSessionException; import net.i2p.client.I2PSessionException;
import net.i2p.crypto.SessionKeyManager; import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Destination; import net.i2p.data.Destination;
...@@ -26,11 +27,13 @@ import net.i2p.data.Hash; ...@@ -26,11 +27,13 @@ import net.i2p.data.Hash;
import net.i2p.data.LeaseSet; import net.i2p.data.LeaseSet;
import net.i2p.data.Payload; import net.i2p.data.Payload;
import net.i2p.data.i2cp.I2CPMessage; import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.I2CPMessageException;
import net.i2p.data.i2cp.MessageId; import net.i2p.data.i2cp.MessageId;
import net.i2p.data.i2cp.MessageStatusMessage; import net.i2p.data.i2cp.MessageStatusMessage;
import net.i2p.data.i2cp.SessionConfig; import net.i2p.data.i2cp.SessionConfig;
import net.i2p.data.i2cp.SessionId; import net.i2p.data.i2cp.SessionId;
import net.i2p.data.i2cp.SessionStatusMessage; import net.i2p.data.i2cp.SessionStatusMessage;
import net.i2p.data.i2cp.SetDateMessage;
import net.i2p.internal.I2CPMessageQueue; import net.i2p.internal.I2CPMessageQueue;
import net.i2p.router.ClientManagerFacade; import net.i2p.router.ClientManagerFacade;
import net.i2p.router.ClientMessage; import net.i2p.router.ClientMessage;
...@@ -39,6 +42,7 @@ import net.i2p.router.JobImpl; ...@@ -39,6 +42,7 @@ import net.i2p.router.JobImpl;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.util.I2PThread; import net.i2p.util.I2PThread;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.SimpleTimer2;
import net.i2p.util.SystemVersion; import net.i2p.util.SystemVersion;
/** /**
...@@ -61,6 +65,7 @@ class ClientManager { ...@@ -61,6 +65,7 @@ class ClientManager {
protected final RouterContext _ctx; protected final RouterContext _ctx;
protected final int _port; protected final int _port;
protected volatile boolean _isStarted; protected volatile boolean _isStarted;
private final SimpleTimer2.TimedEvent _clientTimestamper;
/** Disable external interface, allow internal clients only @since 0.8.3 */ /** Disable external interface, allow internal clients only @since 0.8.3 */
private static final String PROP_DISABLE_EXTERNAL = "i2cp.disableInterface"; private static final String PROP_DISABLE_EXTERNAL = "i2cp.disableInterface";
...@@ -96,6 +101,7 @@ class ClientManager { ...@@ -96,6 +101,7 @@ class ClientManager {
_pendingRunners = new HashSet<ClientConnectionRunner>(); _pendingRunners = new HashSet<ClientConnectionRunner>();
_runnerSessionIds = new HashSet<SessionId>(); _runnerSessionIds = new HashSet<SessionId>();
_port = port; _port = port;
_clientTimestamper = new ClientTimestamper();
// following are for RequestLeaseSetJob // following are for RequestLeaseSetJob
_ctx.statManager().createRateStat("client.requestLeaseSetSuccess", "How frequently the router requests successfully a new leaseSet?", "ClientMessages", new long[] { 60*60*1000 }); _ctx.statManager().createRateStat("client.requestLeaseSetSuccess", "How frequently the router requests successfully a new leaseSet?", "ClientMessages", new long[] { 60*60*1000 });
_ctx.statManager().createRateStat("client.requestLeaseSetTimeout", "How frequently the router requests a new leaseSet but gets no reply?", "ClientMessages", new long[] { 60*60*1000 }); _ctx.statManager().createRateStat("client.requestLeaseSetTimeout", "How frequently the router requests a new leaseSet but gets no reply?", "ClientMessages", new long[] { 60*60*1000 });
...@@ -107,7 +113,10 @@ class ClientManager { ...@@ -107,7 +113,10 @@ class ClientManager {
startListeners(); startListeners();
} }
/** Todo: Start a 3rd listener for IPV6? */ /**
* Call from synchronized method
* Todo: Start a 3rd listener for IPV6?
*/
protected void startListeners() { protected void startListeners() {
ClientListenerRunner listener; ClientListenerRunner listener;
if (SystemVersion.isAndroid()) { if (SystemVersion.isAndroid()) {
...@@ -125,6 +134,7 @@ class ClientManager { ...@@ -125,6 +134,7 @@ class ClientManager {
Thread t = new I2PThread(listener, "ClientListener:" + _port, true); Thread t = new I2PThread(listener, "ClientListener:" + _port, true);
t.start(); t.start();
_listeners.add(listener); _listeners.add(listener);
_clientTimestamper.schedule(ClientTimestamper.LOOP_TIME);
} }
_isStarted = true; _isStarted = true;
} }
...@@ -162,6 +172,7 @@ class ClientManager { ...@@ -162,6 +172,7 @@ class ClientManager {
runner.disconnectClient(msg, Log.WARN); runner.disconnectClient(msg, Log.WARN);
} }
_runnersByHash.clear(); _runnersByHash.clear();
_clientTimestamper.cancel();
} }
/** /**
...@@ -600,4 +611,41 @@ class ClientManager { ...@@ -600,4 +611,41 @@ class ClientManager {
} }
} }
} }
/**
* Tell external clients the time periodically
*
* @since 0.9.20
*/
private class ClientTimestamper extends SimpleTimer2.TimedEvent {
public static final long LOOP_TIME = 10*60*1000;
/** must call schedule() later */
public ClientTimestamper() {
super(_ctx.simpleTimer2());
}
public void timeReached() {
if (!_isStarted)
return;
for (ClientConnectionRunner runner : _runners.values()) {
if (runner instanceof QueuedClientConnectionRunner)
continue;
if (runner.isDead())
continue;
if (runner.getConfig() == null)
continue; // simple session or no session yet
if (runner.getLeaseSet() == null)
continue; // don't confuse client while waiting for CreateLeaseSet msg
try {
// only send version if the client can handle it (0.8.7 or greater)
runner.doSend(new SetDateMessage(runner.getClientVersion() != null ?
CoreVersion.VERSION : null));
} catch (I2CPMessageException ime) {}
}
if (_isStarted)
schedule(LOOP_TIME);
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment