* cleaned up the tunnelCreate reply timeout
* reduced the number of tags passed when garlic routing a tunnelCreate * catch timeout on a tunnel message quicker * give a tunnel message a new messageId per hop * added some more infrastructure for per-hop tunnelId
This commit is contained in:
@ -40,6 +40,7 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
private static Log _log;
|
private static Log _log;
|
||||||
private TunnelId _id;
|
private TunnelId _id;
|
||||||
private Hash _nextHop;
|
private Hash _nextHop;
|
||||||
|
private TunnelId _nextHopId;
|
||||||
private Hash _thisHop;
|
private Hash _thisHop;
|
||||||
private TunnelInfo _nextHopInfo;
|
private TunnelInfo _nextHopInfo;
|
||||||
private TunnelConfigurationSessionKey _configurationKey;
|
private TunnelConfigurationSessionKey _configurationKey;
|
||||||
@ -62,6 +63,7 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
setTunnelId(null);
|
setTunnelId(null);
|
||||||
setThisHop(null);
|
setThisHop(null);
|
||||||
setNextHop(null);
|
setNextHop(null);
|
||||||
|
setNextHopId(null);
|
||||||
setNextHopInfo(null);
|
setNextHopInfo(null);
|
||||||
_configurationKey = null;
|
_configurationKey = null;
|
||||||
_verificationKey = null;
|
_verificationKey = null;
|
||||||
@ -83,6 +85,9 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
public Hash getNextHop() { return _nextHop; }
|
public Hash getNextHop() { return _nextHop; }
|
||||||
public void setNextHop(Hash nextHopRouterIdentity) { _nextHop = nextHopRouterIdentity; }
|
public void setNextHop(Hash nextHopRouterIdentity) { _nextHop = nextHopRouterIdentity; }
|
||||||
|
|
||||||
|
public TunnelId getNextHopId() { return _nextHopId; }
|
||||||
|
public void setNextHopId(TunnelId id) { _nextHopId = id; }
|
||||||
|
|
||||||
public Hash getThisHop() { return _thisHop; }
|
public Hash getThisHop() { return _thisHop; }
|
||||||
public void setThisHop(Hash thisHopRouterIdentity) { _thisHop = thisHopRouterIdentity; }
|
public void setThisHop(Hash thisHopRouterIdentity) { _thisHop = thisHopRouterIdentity; }
|
||||||
|
|
||||||
@ -197,6 +202,8 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
if (includeNext.booleanValue()) {
|
if (includeNext.booleanValue()) {
|
||||||
_nextHop = new Hash();
|
_nextHop = new Hash();
|
||||||
_nextHop.readBytes(in);
|
_nextHop.readBytes(in);
|
||||||
|
_nextHopId = new TunnelId();
|
||||||
|
_nextHopId.readBytes(in);
|
||||||
} else {
|
} else {
|
||||||
_nextHop = null;
|
_nextHop = null;
|
||||||
}
|
}
|
||||||
@ -266,6 +273,7 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
if (_nextHop != null) {
|
if (_nextHop != null) {
|
||||||
DataHelper.writeBoolean(out, Boolean.TRUE);
|
DataHelper.writeBoolean(out, Boolean.TRUE);
|
||||||
_nextHop.writeBytes(out);
|
_nextHop.writeBytes(out);
|
||||||
|
_nextHopId.writeBytes(out);
|
||||||
} else {
|
} else {
|
||||||
DataHelper.writeBoolean(out, Boolean.FALSE);
|
DataHelper.writeBoolean(out, Boolean.FALSE);
|
||||||
}
|
}
|
||||||
@ -321,6 +329,8 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
buf.append("\n Destination: ").append(cur.getDestination().calculateHash().toBase64());
|
buf.append("\n Destination: ").append(cur.getDestination().calculateHash().toBase64());
|
||||||
if (cur.getNextHop() != null)
|
if (cur.getNextHop() != null)
|
||||||
buf.append("\n Next: ").append(cur.getNextHop());
|
buf.append("\n Next: ").append(cur.getNextHop());
|
||||||
|
if (cur.getNextHop() != null)
|
||||||
|
buf.append("\n NextId: ").append(cur.getNextHopId());
|
||||||
if (cur.getSettings() == null)
|
if (cur.getSettings() == null)
|
||||||
buf.append("\n Expiration: ").append("none");
|
buf.append("\n Expiration: ").append("none");
|
||||||
else
|
else
|
||||||
@ -338,6 +348,7 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
rv = 7*rv + DataHelper.hashCode(_options);
|
rv = 7*rv + DataHelper.hashCode(_options);
|
||||||
rv = 7*rv + DataHelper.hashCode(_destination);
|
rv = 7*rv + DataHelper.hashCode(_destination);
|
||||||
rv = 7*rv + DataHelper.hashCode(_nextHop);
|
rv = 7*rv + DataHelper.hashCode(_nextHop);
|
||||||
|
rv = 7*rv + DataHelper.hashCode(_nextHopId);
|
||||||
rv = 7*rv + DataHelper.hashCode(_thisHop);
|
rv = 7*rv + DataHelper.hashCode(_thisHop);
|
||||||
rv = 7*rv + DataHelper.hashCode(_id);
|
rv = 7*rv + DataHelper.hashCode(_id);
|
||||||
rv = 7*rv + DataHelper.hashCode(_configurationKey);
|
rv = 7*rv + DataHelper.hashCode(_configurationKey);
|
||||||
@ -357,6 +368,7 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
getIsReady() == info.getIsReady() &&
|
getIsReady() == info.getIsReady() &&
|
||||||
DataHelper.eq(getEncryptionKey(), info.getEncryptionKey()) &&
|
DataHelper.eq(getEncryptionKey(), info.getEncryptionKey()) &&
|
||||||
DataHelper.eq(getNextHop(), info.getNextHop()) &&
|
DataHelper.eq(getNextHop(), info.getNextHop()) &&
|
||||||
|
DataHelper.eq(getNextHopId(), info.getNextHopId()) &&
|
||||||
DataHelper.eq(getNextHopInfo(), info.getNextHopInfo()) &&
|
DataHelper.eq(getNextHopInfo(), info.getNextHopInfo()) &&
|
||||||
DataHelper.eq(getSettings(), info.getSettings()) &&
|
DataHelper.eq(getSettings(), info.getSettings()) &&
|
||||||
DataHelper.eq(getSigningKey(), info.getSigningKey()) &&
|
DataHelper.eq(getSigningKey(), info.getSigningKey()) &&
|
||||||
|
@ -34,6 +34,9 @@ public class GarlicMessageBuilder {
|
|||||||
return buildMessage(ctx, config, new SessionKey(), new HashSet());
|
return buildMessage(ctx, config, new SessionKey(), new HashSet());
|
||||||
}
|
}
|
||||||
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set wrappedTags) {
|
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set wrappedTags) {
|
||||||
|
return buildMessage(ctx, config, wrappedKey, wrappedTags, 20);
|
||||||
|
}
|
||||||
|
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set wrappedTags, int numTagsToDeliver) {
|
||||||
Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
|
Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
|
||||||
PublicKey key = config.getRecipientPublicKey();
|
PublicKey key = config.getRecipientPublicKey();
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
@ -61,16 +64,16 @@ public class GarlicMessageBuilder {
|
|||||||
log.debug("Available tags for encryption to " + key + ": " + availTags);
|
log.debug("Available tags for encryption to " + key + ": " + availTags);
|
||||||
|
|
||||||
if (availTags < 10) { // arbitrary threshold
|
if (availTags < 10) { // arbitrary threshold
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < numTagsToDeliver; i++)
|
||||||
wrappedTags.add(new SessionTag(true));
|
wrappedTags.add(new SessionTag(true));
|
||||||
if (log.shouldLog(Log.INFO))
|
if (log.shouldLog(Log.INFO))
|
||||||
log.info("Less than 10 tags are available (" + availTags + "), so we're including 20 more");
|
log.info("Less than 10 tags are available (" + availTags + "), so we're including more");
|
||||||
} else if (ctx.sessionKeyManager().getAvailableTimeLeft(key, curKey) < 30*1000) {
|
} else if (ctx.sessionKeyManager().getAvailableTimeLeft(key, curKey) < 30*1000) {
|
||||||
// if we have > 10 tags, but they expire in under 30 seconds, we want more
|
// if we have > 10 tags, but they expire in under 30 seconds, we want more
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < numTagsToDeliver; i++)
|
||||||
wrappedTags.add(new SessionTag(true));
|
wrappedTags.add(new SessionTag(true));
|
||||||
if (log.shouldLog(Log.INFO))
|
if (log.shouldLog(Log.INFO))
|
||||||
log.info("Tags are almost expired, adding 20 new ones");
|
log.info("Tags are almost expired, adding new ones");
|
||||||
} else {
|
} else {
|
||||||
// always tack on at least one more - not necessary.
|
// always tack on at least one more - not necessary.
|
||||||
//wrappedTags.add(new SessionTag(true));
|
//wrappedTags.add(new SessionTag(true));
|
||||||
|
@ -198,9 +198,24 @@ public class HandleTunnelMessageJob extends JobImpl {
|
|||||||
getContext().statManager().addRateData("tunnel.relayMessageSize",
|
getContext().statManager().addRateData("tunnel.relayMessageSize",
|
||||||
_message.getData().length, 0);
|
_message.getData().length, 0);
|
||||||
|
|
||||||
SendMessageDirectJob j = new SendMessageDirectJob(getContext(), _message,
|
TunnelMessage msg = new TunnelMessage(getContext());
|
||||||
|
msg.setData(_message.getData());
|
||||||
|
msg.setEncryptedDeliveryInstructions(_message.getEncryptedDeliveryInstructions());
|
||||||
|
msg.setTunnelId(info.getNextHopId());
|
||||||
|
msg.setVerificationStructure(_message.getVerificationStructure());
|
||||||
|
msg.setMessageExpiration(_message.getMessageExpiration());
|
||||||
|
|
||||||
|
int timeoutMs = (int)(_message.getMessageExpiration().getTime() - getContext().clock().now());
|
||||||
|
if (timeoutMs < 1000) {
|
||||||
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
_log.error("Message " + _message.getUniqueId() + " is valid and we would pass it on through tunnel "
|
||||||
|
+ info.getTunnelId().getTunnelId() + ", but its too late (expired " + timeoutMs + "ms ago)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageDirectJob j = new SendMessageDirectJob(getContext(), msg,
|
||||||
info.getNextHop(),
|
info.getNextHop(),
|
||||||
(int)(_message.getMessageExpiration().getTime() - getContext().clock().now()),
|
timeoutMs,
|
||||||
FORWARD_PRIORITY);
|
FORWARD_PRIORITY);
|
||||||
getContext().jobQueue().addJob(j);
|
getContext().jobQueue().addJob(j);
|
||||||
return;
|
return;
|
||||||
@ -515,7 +530,7 @@ public class HandleTunnelMessageJob extends JobImpl {
|
|||||||
ReplyJob onReply = null;
|
ReplyJob onReply = null;
|
||||||
Hash targetRouter = null;
|
Hash targetRouter = null;
|
||||||
TunnelId targetTunnelId = null;
|
TunnelId targetTunnelId = null;
|
||||||
SendTunnelMessageJob j = new SendTunnelMessageJob(ctx, _body, _info.getTunnelId(), targetRouter, targetTunnelId, onSuccess, onReply, onFailure, selector, timeout, FORWARD_PRIORITY);
|
SendTunnelMessageJob j = new SendTunnelMessageJob(ctx, _body, _info.getNextHopId(), targetRouter, targetTunnelId, onSuccess, onReply, onFailure, selector, timeout, FORWARD_PRIORITY);
|
||||||
ctx.jobQueue().addJob(j);
|
ctx.jobQueue().addJob(j);
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
@ -180,7 +180,14 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
_log.debug("Tunnel message created: " + msg + " out of encrypted message: "
|
_log.debug("Tunnel message created: " + msg + " out of encrypted message: "
|
||||||
+ _message);
|
+ _message);
|
||||||
long now = getContext().clock().now();
|
long now = getContext().clock().now();
|
||||||
if (_expiration < now + 15*1000) {
|
if (_expiration < now) {
|
||||||
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
_log.error("We are the gateway to " + info.getTunnelId().getTunnelId()
|
||||||
|
+ " and the message " + msg.getUniqueId() + " is valid, but it has timed out ("
|
||||||
|
+ (now - _expiration) + "ms ago)");
|
||||||
|
if (_onFailure != null)
|
||||||
|
getContext().jobQueue().addJob(_onFailure);
|
||||||
|
}else if (_expiration < now + 15*1000) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
_log.warn("Adding a tunnel message that will expire shortly ["
|
_log.warn("Adding a tunnel message that will expire shortly ["
|
||||||
+ new Date(_expiration) + "]", getAddedBy());
|
+ new Date(_expiration) + "]", getAddedBy());
|
||||||
|
@ -66,6 +66,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
|
|||||||
info.setConfigurationKey(_message.getConfigurationKey());
|
info.setConfigurationKey(_message.getConfigurationKey());
|
||||||
info.setEncryptionKey(_message.getTunnelKey());
|
info.setEncryptionKey(_message.getTunnelKey());
|
||||||
info.setNextHop(_message.getNextRouter());
|
info.setNextHop(_message.getNextRouter());
|
||||||
|
info.setNextHopId(_message.getNextTunnelId());
|
||||||
|
|
||||||
TunnelSettings settings = new TunnelSettings(getContext());
|
TunnelSettings settings = new TunnelSettings(getContext());
|
||||||
settings.setBytesPerMinuteAverage(_message.getMaxAvgBytesPerMin());
|
settings.setBytesPerMinuteAverage(_message.getMaxAvgBytesPerMin());
|
||||||
@ -129,7 +130,6 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long REPLY_TIMEOUT = 10*1000;
|
|
||||||
private void sendReply(boolean ok) {
|
private void sendReply(boolean ok) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Sending reply to a tunnel create of id " + _message.getTunnelId()
|
_log.debug("Sending reply to a tunnel create of id " + _message.getTunnelId()
|
||||||
@ -149,7 +149,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
|
|||||||
// since we don't actually check anything, this is a catch all
|
// since we don't actually check anything, this is a catch all
|
||||||
msg.setStatus(TunnelCreateStatusMessage.STATUS_FAILED_OVERLOADED);
|
msg.setStatus(TunnelCreateStatusMessage.STATUS_FAILED_OVERLOADED);
|
||||||
}
|
}
|
||||||
msg.setMessageExpiration(new Date(getContext().clock().now()+60*1000));
|
msg.setMessageExpiration(new Date(getContext().clock().now()+TIMEOUT));
|
||||||
|
|
||||||
// put that message into a garlic
|
// put that message into a garlic
|
||||||
GarlicMessage reply = createReply(msg);
|
GarlicMessage reply = createReply(msg);
|
||||||
@ -161,7 +161,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
|
|||||||
_message.getReplyTunnel(),
|
_message.getReplyTunnel(),
|
||||||
(Job)null, (ReplyJob)null,
|
(Job)null, (ReplyJob)null,
|
||||||
(Job)null, (MessageSelector)null,
|
(Job)null, (MessageSelector)null,
|
||||||
REPLY_TIMEOUT, PRIORITY);
|
TIMEOUT, PRIORITY);
|
||||||
getContext().jobQueue().addJob(job);
|
getContext().jobQueue().addJob(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
|
|||||||
config.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
|
config.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
|
||||||
config.setDeliveryInstructions(instructions);
|
config.setDeliveryInstructions(instructions);
|
||||||
config.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
|
config.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
|
||||||
config.setExpiration(REPLY_TIMEOUT+getContext().clock().now());
|
config.setExpiration(TIMEOUT+getContext().clock().now());
|
||||||
config.setRecipient(null);
|
config.setRecipient(null);
|
||||||
config.setRequestAck(false);
|
config.setRequestAck(false);
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
|
|||||||
|
|
||||||
replyClove.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
|
replyClove.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
|
||||||
replyClove.setDeliveryInstructions(instructions);
|
replyClove.setDeliveryInstructions(instructions);
|
||||||
replyClove.setExpiration(REPLY_TIMEOUT+getContext().clock().now());
|
replyClove.setExpiration(TIMEOUT+getContext().clock().now());
|
||||||
replyClove.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
|
replyClove.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
|
||||||
replyClove.setPayload(body);
|
replyClove.setPayload(body);
|
||||||
replyClove.setRecipient(null);
|
replyClove.setRecipient(null);
|
||||||
|
@ -422,7 +422,7 @@ public class RequestTunnelJob extends JobImpl {
|
|||||||
wrappedTo.setData(rcptKey.getData());
|
wrappedTo.setData(rcptKey.getData());
|
||||||
|
|
||||||
long start = getContext().clock().now();
|
long start = getContext().clock().now();
|
||||||
GarlicMessage message = GarlicMessageBuilder.buildMessage(getContext(), config, wrappedKey, wrappedTags);
|
GarlicMessage message = GarlicMessageBuilder.buildMessage(getContext(), config, wrappedKey, wrappedTags, 10);
|
||||||
long end = getContext().clock().now();
|
long end = getContext().clock().now();
|
||||||
if ( (end - start) > 1000) {
|
if ( (end - start) > 1000) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
Reference in New Issue
Block a user