* 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:
jrandom
2004-07-28 00:08:15 +00:00
committed by zzz
parent 60c7db0733
commit 2dbe33e769
6 changed files with 51 additions and 14 deletions

View File

@ -40,6 +40,7 @@ public class TunnelInfo extends DataStructureImpl {
private static Log _log;
private TunnelId _id;
private Hash _nextHop;
private TunnelId _nextHopId;
private Hash _thisHop;
private TunnelInfo _nextHopInfo;
private TunnelConfigurationSessionKey _configurationKey;
@ -62,6 +63,7 @@ public class TunnelInfo extends DataStructureImpl {
setTunnelId(null);
setThisHop(null);
setNextHop(null);
setNextHopId(null);
setNextHopInfo(null);
_configurationKey = null;
_verificationKey = null;
@ -83,6 +85,9 @@ public class TunnelInfo extends DataStructureImpl {
public Hash getNextHop() { return _nextHop; }
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 void setThisHop(Hash thisHopRouterIdentity) { _thisHop = thisHopRouterIdentity; }
@ -197,6 +202,8 @@ public class TunnelInfo extends DataStructureImpl {
if (includeNext.booleanValue()) {
_nextHop = new Hash();
_nextHop.readBytes(in);
_nextHopId = new TunnelId();
_nextHopId.readBytes(in);
} else {
_nextHop = null;
}
@ -266,6 +273,7 @@ public class TunnelInfo extends DataStructureImpl {
if (_nextHop != null) {
DataHelper.writeBoolean(out, Boolean.TRUE);
_nextHop.writeBytes(out);
_nextHopId.writeBytes(out);
} else {
DataHelper.writeBoolean(out, Boolean.FALSE);
}
@ -321,6 +329,8 @@ public class TunnelInfo extends DataStructureImpl {
buf.append("\n Destination: ").append(cur.getDestination().calculateHash().toBase64());
if (cur.getNextHop() != null)
buf.append("\n Next: ").append(cur.getNextHop());
if (cur.getNextHop() != null)
buf.append("\n NextId: ").append(cur.getNextHopId());
if (cur.getSettings() == null)
buf.append("\n Expiration: ").append("none");
else
@ -338,6 +348,7 @@ public class TunnelInfo extends DataStructureImpl {
rv = 7*rv + DataHelper.hashCode(_options);
rv = 7*rv + DataHelper.hashCode(_destination);
rv = 7*rv + DataHelper.hashCode(_nextHop);
rv = 7*rv + DataHelper.hashCode(_nextHopId);
rv = 7*rv + DataHelper.hashCode(_thisHop);
rv = 7*rv + DataHelper.hashCode(_id);
rv = 7*rv + DataHelper.hashCode(_configurationKey);
@ -357,6 +368,7 @@ public class TunnelInfo extends DataStructureImpl {
getIsReady() == info.getIsReady() &&
DataHelper.eq(getEncryptionKey(), info.getEncryptionKey()) &&
DataHelper.eq(getNextHop(), info.getNextHop()) &&
DataHelper.eq(getNextHopId(), info.getNextHopId()) &&
DataHelper.eq(getNextHopInfo(), info.getNextHopInfo()) &&
DataHelper.eq(getSettings(), info.getSettings()) &&
DataHelper.eq(getSigningKey(), info.getSigningKey()) &&

View File

@ -34,6 +34,9 @@ public class GarlicMessageBuilder {
return buildMessage(ctx, config, new SessionKey(), new HashSet());
}
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);
PublicKey key = config.getRecipientPublicKey();
if (key == null) {
@ -61,16 +64,16 @@ public class GarlicMessageBuilder {
log.debug("Available tags for encryption to " + key + ": " + availTags);
if (availTags < 10) { // arbitrary threshold
for (int i = 0; i < 20; i++)
for (int i = 0; i < numTagsToDeliver; i++)
wrappedTags.add(new SessionTag(true));
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) {
// 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));
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 {
// always tack on at least one more - not necessary.
//wrappedTags.add(new SessionTag(true));

View File

@ -198,9 +198,24 @@ public class HandleTunnelMessageJob extends JobImpl {
getContext().statManager().addRateData("tunnel.relayMessageSize",
_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(),
(int)(_message.getMessageExpiration().getTime() - getContext().clock().now()),
timeoutMs,
FORWARD_PRIORITY);
getContext().jobQueue().addJob(j);
return;
@ -515,7 +530,7 @@ public class HandleTunnelMessageJob extends JobImpl {
ReplyJob onReply = null;
Hash targetRouter = 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);
} else {
if (_log.shouldLog(Log.WARN))

View File

@ -180,7 +180,14 @@ public class SendTunnelMessageJob extends JobImpl {
_log.debug("Tunnel message created: " + msg + " out of encrypted message: "
+ _message);
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))
_log.warn("Adding a tunnel message that will expire shortly ["
+ new Date(_expiration) + "]", getAddedBy());

View File

@ -66,6 +66,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
info.setConfigurationKey(_message.getConfigurationKey());
info.setEncryptionKey(_message.getTunnelKey());
info.setNextHop(_message.getNextRouter());
info.setNextHopId(_message.getNextTunnelId());
TunnelSettings settings = new TunnelSettings(getContext());
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) {
if (_log.shouldLog(Log.DEBUG))
_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
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
GarlicMessage reply = createReply(msg);
@ -161,7 +161,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
_message.getReplyTunnel(),
(Job)null, (ReplyJob)null,
(Job)null, (MessageSelector)null,
REPLY_TIMEOUT, PRIORITY);
TIMEOUT, PRIORITY);
getContext().jobQueue().addJob(job);
}
@ -189,7 +189,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
config.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
config.setDeliveryInstructions(instructions);
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.setRequestAck(false);
@ -211,7 +211,7 @@ public class HandleTunnelCreateMessageJob extends JobImpl {
replyClove.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
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.setPayload(body);
replyClove.setRecipient(null);

View File

@ -422,7 +422,7 @@ public class RequestTunnelJob extends JobImpl {
wrappedTo.setData(rcptKey.getData());
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();
if ( (end - start) > 1000) {
if (_log.shouldLog(Log.WARN))