I2CP: Fix requesting leasesets for subsessions (ticket #2458)

Always request new LS for subsessions also
Don't reuse LS object for subsessions
Cancel rerequest timer as necessary
Fixes watchdog warnings
Fixes console status for subsessions in different states
javadocs
This commit is contained in:
zzz
2020-12-24 13:56:32 -05:00
parent a3c44912f2
commit 8835351b99
4 changed files with 62 additions and 19 deletions

View File

@ -1,6 +1,10 @@
2020-12-24 zzz
* I2CP: Fix requesting leasesets for subsessions (ticket #2458)
2020-12-23 zzz
* Crypto: Increase ratchet tag window
* I2CP: Fix encrypted leaseset for ECIES and offline keys
* i2ptunnel: Fix writing config file twice on save
2020-12-22 zzz
* Console:

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 9;
public final static long BUILD = 10;
/** for example "-test" */
public final static String EXTRA = "";

View File

@ -53,7 +53,7 @@ import net.i2p.router.crypto.ratchet.MuxedSKM;
import net.i2p.util.ConcurrentHashSet;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.util.SimpleTimer;
import net.i2p.util.SimpleTimer2;
/**
* Bridge the router and the client - managing state for a client.
@ -229,6 +229,8 @@ class ClientConnectionRunner {
for (SessionParams sp : _sessions.values()) {
if (sp.isPrimary)
_context.tunnelManager().removeTunnels(sp.dest);
if (sp.rerequestTimer != null)
sp.rerequestTimer.cancel();
}
}
synchronized (_alreadyProcessed) {
@ -466,6 +468,10 @@ class ClientConnectionRunner {
_context.tunnelManager().removeTunnels(sp.dest);
else
_context.tunnelManager().removeAlias(sp.dest);
synchronized(this) {
if (sp.rerequestTimer != null)
sp.rerequestTimer.cancel();
}
break;
}
}
@ -483,6 +489,10 @@ class ClientConnectionRunner {
if (ls != null)
_context.netDb().unpublish(ls);
_context.tunnelManager().removeAlias(sp.dest);
synchronized(this) {
if (sp.rerequestTimer != null)
sp.rerequestTimer.cancel();
}
}
_sessions.clear();
}
@ -690,6 +700,10 @@ class ClientConnectionRunner {
_log.debug("LeaseSet created fully: " + state + '\n' + ls);
sp.leaseRequest = null;
_consecutiveLeaseRequestFails = 0;
if (sp.rerequestTimer != null) {
sp.rerequestTimer.cancel();
sp.rerequestTimer = null;
}
}
}
if ( (state != null) && (state.getOnGranted() != null) )
@ -888,7 +902,8 @@ class ClientConnectionRunner {
* @param h the Destination's hash
* @param set LeaseSet with requested leases - this object must be updated to contain the
* signed version (as well as any changed/added/removed Leases)
* The LeaseSet contains Leases and destination only, it is unsigned.
* The LeaseSet contains Leases only, it is unsigned.
* Must be unique for this hash, do not reuse for subsessions.
* @param expirationTime ms to wait before failing
* @param onCreateJob Job to run after the LeaseSet is authorized, null OK
* @param onFailedJob Job to run after the timeout passes without receiving authorization, null OK
@ -958,7 +973,7 @@ class ClientConnectionRunner {
set.setDestination(dest);
Rerequest timer = new Rerequest(set, expirationTime, onCreateJob, onFailedJob);
sp.rerequestTimer = timer;
_context.simpleTimer2().addEvent(timer, 3*1000);
timer.schedule(3*1000);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Already requesting, ours newer, wait 3 sec: " + state);
}
@ -972,13 +987,16 @@ class ClientConnectionRunner {
// before we are ready
Rerequest timer = new Rerequest(set, expirationTime, onCreateJob, onFailedJob);
sp.rerequestTimer = timer;
_context.simpleTimer2().addEvent(timer, 1000);
timer.schedule(1000);
if (_log.shouldLog(Log.DEBUG))
_log.debug("No current LS but no OB tunnels, wait 1 sec for " + h);
return;
} else {
// so the timer won't fire off with an older LS request
sp.rerequestTimer = null;
if (sp.rerequestTimer != null) {
sp.rerequestTimer.cancel();
sp.rerequestTimer = null;
}
long earliest = (current != null) ? current.getEarliestLeaseDate() : 0;
sp.leaseRequest = state = new LeaseRequestState(onCreateJob, onFailedJob, earliest,
_context.clock().now() + expirationTime, set);
@ -990,14 +1008,18 @@ class ClientConnectionRunner {
_context.jobQueue().addJob(new RequestLeaseSetJob(_context, this, state));
}
private class Rerequest implements SimpleTimer.TimedEvent {
private class Rerequest extends SimpleTimer2.TimedEvent {
private final LeaseSet _ls;
private final long _expirationTime;
private final Job _onCreate;
private final Job _onFailed;
/** @param ls dest must be set */
/**
* Caller must schedule()
* @param ls dest must be set
*/
public Rerequest(LeaseSet ls, long expirationTime, Job onCreate, Job onFailed) {
super(_context.simpleTimer2());
_ls = ls;
_expirationTime = expirationTime;
_onCreate = onCreate;

View File

@ -112,7 +112,7 @@ public class TunnelPool {
}
if (ls != null)
_context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
requestLeaseSet(ls);
}
_context.statManager().createRequiredRateStat(_rateName,
"Tunnel Bandwidth (Bytes/sec)", "Tunnels",
@ -460,7 +460,7 @@ public class TunnelPool {
}
if (ls != null)
_context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
requestLeaseSet(ls);
}
/**
@ -492,7 +492,7 @@ public class TunnelPool {
if (_alive && _settings.isInbound() && !_settings.isExploratory()) {
if (ls != null) {
_context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
requestLeaseSet(ls);
} else {
if (_log.shouldLog(Log.WARN))
_log.warn(toString() + ": unable to build a new leaseSet on removal (" + remaining
@ -551,7 +551,7 @@ public class TunnelPool {
if (_settings.isInbound() && !_settings.isExploratory()) {
if (ls != null) {
_context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
requestLeaseSet(ls);
}
}
}
@ -606,13 +606,28 @@ public class TunnelPool {
ls = locked_buildNewLeaseSet();
}
if (ls != null) {
_context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
Set<Hash> aliases = _settings.getAliases();
if (aliases != null && !aliases.isEmpty()) {
for (Hash h : aliases) {
_context.clientManager().requestLeaseSet(h, ls);
}
}
requestLeaseSet(ls);
}
}
}
/**
* Request lease set from client for the primary and all aliases.
*
* @param ls non-null
* @since 0.9.49
*/
private void requestLeaseSet(LeaseSet ls) {
_context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
Set<Hash> aliases = _settings.getAliases();
if (aliases != null && !aliases.isEmpty()) {
for (Hash h : aliases) {
// don't corrupt other requests
LeaseSet ls2 = new LeaseSet();
for (int i = 0; i < ls.getLeaseCount(); i++) {
ls2.addLease(ls.getLease(i));
}
_context.clientManager().requestLeaseSet(h, ls2);
}
}
}
@ -709,6 +724,8 @@ public class TunnelPool {
/**
* Build a leaseSet with the required tunnels that aren't about to expire.
* Caller must synchronize on _tunnels.
* The returned LeaseSet will be incomplete; it will not have the destination
* set and will not be signed. Only the leases will be included.
*
* @return null on failure
*/