I2CP Multisession Work in progress:

Fix NPE in requestLeaseSet()
Fix setting new session ID in SessionStatusMessage
Fix subsession support detection
Streaming: one socket manager, multiple connection managers.
Change data structure for subessions in socket manager
Subsession cleanup on destroy
I2PTunnel: add DSA subsession for non-DSA shared client
Javadocs
This commit is contained in:
zzz
2015-04-18 19:01:23 +00:00
parent 6a644dd0e5
commit 91e98ba447
9 changed files with 120 additions and 23 deletions

View File

@ -723,13 +723,15 @@ class ClientConnectionRunner {
* within the timeout specified, queue up the onFailedJob. This call does not
* block.
*
* @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.
* @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
*/
void requestLeaseSet(LeaseSet set, long expirationTime, Job onCreateJob, Job onFailedJob) {
void requestLeaseSet(Hash h, LeaseSet set, long expirationTime, Job onCreateJob, Job onFailedJob) {
if (_dead) {
if (_log.shouldLog(Log.WARN))
_log.warn("Requesting leaseSet from a dead client: " + set);
@ -737,6 +739,12 @@ class ClientConnectionRunner {
_context.jobQueue().addJob(onFailedJob);
return;
}
SessionParams sp = _sessions.get(h);
if (sp == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Requesting leaseSet for an unknown sesssion");
return;
}
// We can't use LeaseSet.equals() here because the dest, keys, and sig on
// the new LeaseSet are null. So we compare leases one by one.
// In addition, the client rewrites the expiration time of all the leases to
@ -748,10 +756,9 @@ class ClientConnectionRunner {
int leases = set.getLeaseCount();
// synch so _currentLeaseSet isn't changed out from under us
LeaseSet current = null;
Destination dest = sp.dest;
synchronized (this) {
Destination dest = set.getDestination();
if (dest != null)
current = getLeaseSet(dest.calculateHash());
current = sp.currentLeaseSet;
if (current != null && current.getLeaseCount() == leases) {
for (int i = 0; i < leases; i++) {
if (! current.getLease(i).getTunnelId().equals(set.getLease(i).getTunnelId()))
@ -770,10 +777,6 @@ class ClientConnectionRunner {
}
if (_log.shouldLog(Log.INFO))
_log.info("Current leaseSet " + current + "\nNew leaseSet " + set);
Hash h = set.getDestination().calculateHash();
SessionParams sp = _sessions.get(h);
if (sp == null)
return;
LeaseRequestState state;
synchronized (this) {
state = sp.leaseRequest;
@ -788,12 +791,15 @@ class ClientConnectionRunner {
// theirs is newer
} else {
// ours is newer, so wait a few secs and retry
set.setDestination(dest);
_context.simpleTimer2().addEvent(new Rerequest(set, expirationTime, onCreateJob, onFailedJob), 3*1000);
}
// fire onCreated?
return; // already requesting
} else {
sp.leaseRequest = state = new LeaseRequestState(onCreateJob, onFailedJob, _context.clock().now() + expirationTime, set);
set.setDestination(dest);
sp.leaseRequest = state = new LeaseRequestState(onCreateJob, onFailedJob,
_context.clock().now() + expirationTime, set);
if (_log.shouldLog(Log.DEBUG))
_log.debug("New request: " + state);
}
@ -807,6 +813,7 @@ class ClientConnectionRunner {
private final Job _onCreate;
private final Job _onFailed;
/** @param ls dest must be set */
public Rerequest(LeaseSet ls, long expirationTime, Job onCreate, Job onFailed) {
_ls = ls;
_expirationTime = expirationTime;
@ -815,7 +822,7 @@ class ClientConnectionRunner {
}
public void timeReached() {
requestLeaseSet(_ls, _expirationTime, _onCreate, _onFailed);
requestLeaseSet(_ls.getDestination().calculateHash(), _ls, _expirationTime, _onCreate, _onFailed);
}
}

View File

@ -392,7 +392,8 @@ class ClientManager {
*
* @param dest Destination from which the LeaseSet's authorization should be requested
* @param set LeaseSet with requested leases - this object must be updated to contain the
* signed version (as well as any changed/added/removed Leases)
* signed version (as well as any changed/added/removed Leases).
* The LeaseSet contains Leases only; it is unsigned and does not have the destination set.
* @param timeout ms to wait before failing
* @param onCreateJob Job to run after the LeaseSet is authorized
* @param onFailedJob Job to run after the timeout passes without receiving authorization
@ -405,15 +406,24 @@ class ClientManager {
+ dest.calculateHash().toBase64() + ". disconnected?");
_ctx.jobQueue().addJob(onFailedJob);
} else {
runner.requestLeaseSet(set, timeout, onCreateJob, onFailedJob);
runner.requestLeaseSet(dest.calculateHash(), set, timeout, onCreateJob, onFailedJob);
}
}
/**
* Request that a particular client authorize the Leases contained in the
* LeaseSet.
*
* @param dest Destination from which the LeaseSet's authorization should be requested
* @param ls 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 only; it is unsigned and does not have the destination set.
*/
public void requestLeaseSet(Hash dest, LeaseSet ls) {
ClientConnectionRunner runner = getRunner(dest);
if (runner != null) {
// no need to fire off any jobs...
runner.requestLeaseSet(ls, REQUEST_LEASESET_TIMEOUT, null, null);
runner.requestLeaseSet(dest, ls, REQUEST_LEASESET_TIMEOUT, null, null);
}
}

View File

@ -115,6 +115,7 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade implements Inte
* @param dest Destination from which the LeaseSet's authorization should be requested
* @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 only; it is unsigned and does not have the destination set.
* @param timeout ms to wait before failing
* @param onCreateJob Job to run after the LeaseSet is authorized
* @param onFailedJob Job to run after the timeout passes without receiving authorization
@ -126,6 +127,15 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade implements Inte
_log.error("Null manager on requestLeaseSet!");
}
/**
* Request that a particular client authorize the Leases contained in the
* LeaseSet.
*
* @param dest Destination from which the LeaseSet's authorization should be requested
* @param ls 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 only; it is unsigned and does not have the destination set.
*/
public void requestLeaseSet(Hash dest, LeaseSet set) {
if (_manager != null)
_manager.requestLeaseSet(dest, set);

View File

@ -251,6 +251,7 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
props.putAll(in.getOptions());
cfg.setOptions(props);
boolean isPrimary = _runner.getSessionIds().isEmpty();
// this sets the session id
int status = _runner.sessionEstablished(cfg);
if (status != SessionStatusMessage.STATUS_CREATED) {
// For now, we do NOT send a SessionStatusMessage - see javadoc above
@ -266,6 +267,8 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
_runner.disconnectClient(msg);
return;
}
// get the new session ID
id = _runner.getSessionId(dest.calculateHash());
sendStatusMessage(id, status);
if (_log.shouldLog(Log.INFO))

View File

@ -30,6 +30,9 @@ class LeaseRequestState {
/**
* @param expiration absolute time, when the request expires (not when the LS expires)
* @param requested 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.
*/
public LeaseRequestState(Job onGranted, Job onFailed, long expiration, LeaseSet requested) {
_onGranted = onGranted;