forked from I2P_Developers/i2p.i2p
NetDB, I2CP: Fix tunnels going yellow for several minutes (Gitlab #487)
This commit is contained in:
@@ -105,6 +105,7 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
|
||||
private long _offlineExpiration;
|
||||
private Signature _offlineSignature;
|
||||
protected SigningPublicKey _transientSigningPublicKey;
|
||||
private long _lastLS2SignTime;
|
||||
|
||||
// subsession stuff
|
||||
// registered subsessions
|
||||
@@ -1185,6 +1186,21 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
|
||||
SessionId getSessionId() { return _sessionId; }
|
||||
void setSessionId(SessionId id) { _sessionId = id; }
|
||||
|
||||
/**
|
||||
* The published timestamp of the last LS2 we signed
|
||||
*
|
||||
* @return 0 if never
|
||||
* @since 0.9.64
|
||||
*/
|
||||
long getLastLS2SignTime() { return _lastLS2SignTime; };
|
||||
|
||||
/**
|
||||
* The published timestamp of the last LS2 we signed
|
||||
*
|
||||
* @since 0.9.64
|
||||
*/
|
||||
void setLastLS2SignTime(long now) { _lastLS2SignTime = now; };
|
||||
|
||||
/** configure the listener */
|
||||
public void setSessionListener(I2PSessionListener lsnr) { _sessionListener = lsnr; }
|
||||
|
||||
|
||||
@@ -130,19 +130,25 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
boolean isLS2 = requiresLS2(session);
|
||||
LeaseSet leaseSet;
|
||||
if (isLS2) {
|
||||
LeaseSet2 ls2;
|
||||
if (_ls2Type == DatabaseEntry.KEY_TYPE_LS2) {
|
||||
leaseSet = new LeaseSet2();
|
||||
ls2 = new LeaseSet2();
|
||||
} else if (_ls2Type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) {
|
||||
leaseSet = new EncryptedLeaseSet();
|
||||
ls2 = new EncryptedLeaseSet();
|
||||
} else if (_ls2Type == DatabaseEntry.KEY_TYPE_META_LS2) {
|
||||
leaseSet = new MetaLeaseSet();
|
||||
ls2= new MetaLeaseSet();
|
||||
} else {
|
||||
session.propogateError("Unsupported LS2 type", new Exception());
|
||||
session.destroySession();
|
||||
return;
|
||||
}
|
||||
if (Boolean.parseBoolean(session.getOptions().getProperty("i2cp.dontPublishLeaseSet")))
|
||||
((LeaseSet2)leaseSet).setUnpublished();
|
||||
ls2.setUnpublished();
|
||||
// ensure 1-second resolution timestamp is higher than last one
|
||||
long now = Math.max(_context.clock().now(), session.getLastLS2SignTime() + 1000);
|
||||
ls2.setPublished(now);
|
||||
session.setLastLS2SignTime(now);
|
||||
leaseSet = ls2;
|
||||
} else {
|
||||
leaseSet = new LeaseSet();
|
||||
}
|
||||
|
||||
@@ -42,19 +42,25 @@ class RequestVariableLeaseSetMessageHandler extends RequestLeaseSetMessageHandle
|
||||
boolean isLS2 = requiresLS2(session);
|
||||
LeaseSet leaseSet;
|
||||
if (isLS2) {
|
||||
LeaseSet2 ls2;
|
||||
if (_ls2Type == DatabaseEntry.KEY_TYPE_LS2) {
|
||||
leaseSet = new LeaseSet2();
|
||||
ls2 = new LeaseSet2();
|
||||
} else if (_ls2Type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) {
|
||||
leaseSet = new EncryptedLeaseSet();
|
||||
ls2 = new EncryptedLeaseSet();
|
||||
} else if (_ls2Type == DatabaseEntry.KEY_TYPE_META_LS2) {
|
||||
leaseSet = new MetaLeaseSet();
|
||||
ls2 = new MetaLeaseSet();
|
||||
} else {
|
||||
session.propogateError("Unsupported LS2 type", new Exception());
|
||||
session.destroySession();
|
||||
return;
|
||||
}
|
||||
if (Boolean.parseBoolean(session.getOptions().getProperty("i2cp.dontPublishLeaseSet")))
|
||||
((LeaseSet2)leaseSet).setUnpublished();
|
||||
ls2.setUnpublished();
|
||||
// ensure 1-second resolution timestamp is higher than last one
|
||||
long now = Math.max(_context.clock().now(), session.getLastLS2SignTime() + 1000);
|
||||
ls2.setPublished(now);
|
||||
session.setLastLS2SignTime(now);
|
||||
leaseSet = ls2;
|
||||
} else {
|
||||
leaseSet = new LeaseSet();
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ public class EncryptedLeaseSet extends LeaseSet2 {
|
||||
DataHelper.writeLong(out, 2, _signingKey.getType().getCode());
|
||||
_signingKey.writeBytes(out);
|
||||
if (_published <= 0)
|
||||
_published = Clock.getInstance().now();
|
||||
setPublished(Clock.getInstance().now());
|
||||
DataHelper.writeLong(out, 4, _published / 1000);
|
||||
DataHelper.writeLong(out, 2, (_expires - _published) / 1000);
|
||||
DataHelper.writeLong(out, 2, _flags);
|
||||
|
||||
@@ -238,6 +238,9 @@ public class LeaseSet extends DatabaseEntry {
|
||||
* determine which LeaseSet was published more recently (later earliestLeaseSetDate
|
||||
* means it was published later)
|
||||
*
|
||||
* Warning - do not use this for version comparison for LeaseSet2.
|
||||
* Use LeaseSet2.getPublished() instead.
|
||||
*
|
||||
* @return earliest end date of any lease in the set, or -1 if there are no leases
|
||||
*/
|
||||
public long getEarliestLeaseDate() {
|
||||
|
||||
@@ -66,6 +66,9 @@ public class LeaseSet2 extends LeaseSet {
|
||||
* Published timestamp, as received.
|
||||
* Different than getDate() or getEarliestLeaseDate(), which are the earliest lease expiration.
|
||||
*
|
||||
* Use this for LS2 version comparison, NOT getEarliestLeaseDate(), because
|
||||
* that will return -1 for EncryptedLS and MetaLS.
|
||||
*
|
||||
* @return in ms, with 1 second resolution
|
||||
* @since 0.9.39
|
||||
*/
|
||||
@@ -73,6 +76,18 @@ public class LeaseSet2 extends LeaseSet {
|
||||
return _published;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set published timestamp.
|
||||
* Will be rounded to nearest second.
|
||||
* If not called, will be set on write.
|
||||
*
|
||||
* @since 0.9.64
|
||||
*/
|
||||
public void setPublished(long now) {
|
||||
// we round it here, so comparisons during verifies aren't wrong
|
||||
_published = ((now + 500) / 1000) * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Published expiration, as received.
|
||||
* May be different than getLatestLeaseDate(), which is the latest lease expiration.
|
||||
@@ -524,8 +539,7 @@ public class LeaseSet2 extends LeaseSet {
|
||||
protected void writeHeader(OutputStream out) throws DataFormatException, IOException {
|
||||
_destination.writeBytes(out);
|
||||
if (_published <= 0) {
|
||||
// we round it here, so comparisons during verifies aren't wrong
|
||||
_published = ((Clock.getInstance().now() + 500) / 1000) * 1000;
|
||||
setPublished(Clock.getInstance().now());
|
||||
}
|
||||
long pub1k = _published / 1000;
|
||||
DataHelper.writeLong(out, 4, pub1k);
|
||||
|
||||
Reference in New Issue
Block a user