* Tunnel Pool:
- Remove tunnel from participating if can't contact next hop - Fail outbound build faster if can't contact first hop
This commit is contained in:
@ -46,6 +46,7 @@ class BuildExecutor implements Runnable {
|
|||||||
_context.statManager().createRateStat("tunnel.buildRequestTime", "How long it takes to build a tunnel request", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.buildRequestTime", "How long it takes to build a tunnel request", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
_context.statManager().createRateStat("tunnel.buildRequestZeroHopTime", "How long it takes to build a zero hop tunnel", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.buildRequestZeroHopTime", "How long it takes to build a zero hop tunnel", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
_context.statManager().createRateStat("tunnel.pendingRemaining", "How many inbound requests are pending after a pass (period is how long the pass takes)?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.pendingRemaining", "How many inbound requests are pending after a pass (period is how long the pass takes)?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
|
_context.statManager().createRateStat("tunnel.buildFailFirstHop", "How often we fail to build a OB tunnel because we can't contact the first hop", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
|
|
||||||
// Get stat manager, get recognized bandwidth tiers
|
// Get stat manager, get recognized bandwidth tiers
|
||||||
StatManager statMgr = _context.statManager();
|
StatManager statMgr = _context.statManager();
|
||||||
|
@ -61,6 +61,7 @@ class BuildHandler {
|
|||||||
|
|
||||||
_context.statManager().createRateStat("tunnel.decryptRequestTime", "How long it takes to decrypt a new tunnel build request", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.decryptRequestTime", "How long it takes to decrypt a new tunnel build request", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
_context.statManager().createRateStat("tunnel.rejectTimeout", "How often we reject a tunnel because we can't find the next hop", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.rejectTimeout", "How often we reject a tunnel because we can't find the next hop", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
|
_context.statManager().createRateStat("tunnel.rejectTimeout2", "How often we fail a tunnel because we can't contact the next hop", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
|
|
||||||
_context.statManager().createRateStat("tunnel.rejectOverloaded", "How long we had to wait before processing the request (when it was rejected)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.rejectOverloaded", "How long we had to wait before processing the request (when it was rejected)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
_context.statManager().createRateStat("tunnel.acceptLoad", "Delay before processing the accepted request", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.acceptLoad", "Delay before processing the accepted request", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
@ -413,7 +414,7 @@ class BuildHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TimeoutReq extends JobImpl {
|
private static class TimeoutReq extends JobImpl {
|
||||||
private BuildMessageState _state;
|
private BuildMessageState _state;
|
||||||
private BuildRequestRecord _req;
|
private BuildRequestRecord _req;
|
||||||
private Hash _nextPeer;
|
private Hash _nextPeer;
|
||||||
@ -425,10 +426,12 @@ class BuildHandler {
|
|||||||
}
|
}
|
||||||
public String getName() { return "Timeout looking for next peer for tunnel join"; }
|
public String getName() { return "Timeout looking for next peer for tunnel join"; }
|
||||||
public void runJob() {
|
public void runJob() {
|
||||||
getContext().statManager().addRateData("tunnel.rejectTimeout", 1, 1);
|
getContext().statManager().addRateData("tunnel.rejectTimeout", 1, 0);
|
||||||
if (_log.shouldLog(Log.WARN))
|
// logging commented out so class can be static
|
||||||
_log.warn("Request " + _state.msg.getUniqueId()
|
//if (_log.shouldLog(Log.WARN))
|
||||||
+ " could no be satisfied, as the next peer could not be found: " + _nextPeer.toBase64());
|
// _log.warn("Request " + _state.msg.getUniqueId()
|
||||||
|
// + " could no be satisfied, as the next peer could not be found: " + _nextPeer.toBase64());
|
||||||
|
|
||||||
// ??? should we blame the peer here? getContext().profileManager().tunnelTimedOut(_nextPeer);
|
// ??? should we blame the peer here? getContext().profileManager().tunnelTimedOut(_nextPeer);
|
||||||
getContext().messageHistory().tunnelRejected(_state.fromHash, new TunnelId(_req.readReceiveTunnelId()), _nextPeer,
|
getContext().messageHistory().tunnelRejected(_state.fromHash, new TunnelId(_req.readReceiveTunnelId()), _nextPeer,
|
||||||
"rejected because we couldn't find " + _nextPeer.toBase64() + ": " +
|
"rejected because we couldn't find " + _nextPeer.toBase64() + ": " +
|
||||||
@ -516,8 +519,9 @@ class BuildHandler {
|
|||||||
+ " from " + (state.fromHash != null ? state.fromHash.toBase64() :
|
+ " from " + (state.fromHash != null ? state.fromHash.toBase64() :
|
||||||
state.from != null ? state.from.calculateHash().toBase64() : "tunnel"));
|
state.from != null ? state.from.calculateHash().toBase64() : "tunnel"));
|
||||||
|
|
||||||
|
HopConfig cfg = null;
|
||||||
if (response == 0) {
|
if (response == 0) {
|
||||||
HopConfig cfg = new HopConfig();
|
cfg = new HopConfig();
|
||||||
cfg.setCreation(_context.clock().now());
|
cfg.setCreation(_context.clock().now());
|
||||||
cfg.setExpiration(_context.clock().now() + 10*60*1000);
|
cfg.setExpiration(_context.clock().now() + 10*60*1000);
|
||||||
cfg.setIVKey(req.readIVKey());
|
cfg.setIVKey(req.readIVKey());
|
||||||
@ -593,6 +597,8 @@ class BuildHandler {
|
|||||||
msg.setExpiration(state.msg.getMessageExpiration());
|
msg.setExpiration(state.msg.getMessageExpiration());
|
||||||
msg.setPriority(300);
|
msg.setPriority(300);
|
||||||
msg.setTarget(nextPeerInfo);
|
msg.setTarget(nextPeerInfo);
|
||||||
|
if (response == 0)
|
||||||
|
msg.setOnFailedSendJob(new TunnelBuildNextHopFailJob(_context, cfg));
|
||||||
_context.outNetMessagePool().add(msg);
|
_context.outNetMessagePool().add(msg);
|
||||||
} else {
|
} else {
|
||||||
// send it to the reply tunnel on the reply peer within a new TunnelBuildReplyMessage
|
// send it to the reply tunnel on the reply peer within a new TunnelBuildReplyMessage
|
||||||
@ -619,6 +625,8 @@ class BuildHandler {
|
|||||||
outMsg.setMessage(m);
|
outMsg.setMessage(m);
|
||||||
outMsg.setPriority(300);
|
outMsg.setPriority(300);
|
||||||
outMsg.setTarget(nextPeerInfo);
|
outMsg.setTarget(nextPeerInfo);
|
||||||
|
if (response == 0)
|
||||||
|
outMsg.setOnFailedSendJob(new TunnelBuildNextHopFailJob(_context, cfg));
|
||||||
_context.outNetMessagePool().add(outMsg);
|
_context.outNetMessagePool().add(outMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -762,7 +770,7 @@ class BuildHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** normal inbound requests from other people */
|
/** normal inbound requests from other people */
|
||||||
private class BuildMessageState {
|
private static class BuildMessageState {
|
||||||
TunnelBuildMessage msg;
|
TunnelBuildMessage msg;
|
||||||
RouterIdentity from;
|
RouterIdentity from;
|
||||||
Hash fromHash;
|
Hash fromHash;
|
||||||
@ -775,7 +783,7 @@ class BuildHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** replies for outbound tunnels that we have created */
|
/** replies for outbound tunnels that we have created */
|
||||||
private class BuildReplyMessageState {
|
private static class BuildReplyMessageState {
|
||||||
TunnelBuildReplyMessage msg;
|
TunnelBuildReplyMessage msg;
|
||||||
long recvTime;
|
long recvTime;
|
||||||
public BuildReplyMessageState(I2NPMessage m) {
|
public BuildReplyMessageState(I2NPMessage m) {
|
||||||
@ -784,7 +792,7 @@ class BuildHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** replies for inbound tunnels we have created */
|
/** replies for inbound tunnels we have created */
|
||||||
private class BuildEndMessageState {
|
private static class BuildEndMessageState {
|
||||||
TunnelBuildMessage msg;
|
TunnelBuildMessage msg;
|
||||||
PooledTunnelCreatorConfig cfg;
|
PooledTunnelCreatorConfig cfg;
|
||||||
long recvTime;
|
long recvTime;
|
||||||
@ -796,15 +804,35 @@ class BuildHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// noop
|
// noop
|
||||||
private class TunnelBuildMessageHandlerJob extends JobImpl {
|
private static class TunnelBuildMessageHandlerJob extends JobImpl {
|
||||||
private TunnelBuildMessageHandlerJob(RouterContext ctx) { super(ctx); }
|
private TunnelBuildMessageHandlerJob(RouterContext ctx) { super(ctx); }
|
||||||
public void runJob() {}
|
public void runJob() {}
|
||||||
public String getName() { return "Receive tunnel build message"; }
|
public String getName() { return "Receive tunnel build message"; }
|
||||||
}
|
}
|
||||||
// noop
|
// noop
|
||||||
private class TunnelBuildReplyMessageHandlerJob extends JobImpl {
|
private static class TunnelBuildReplyMessageHandlerJob extends JobImpl {
|
||||||
private TunnelBuildReplyMessageHandlerJob(RouterContext ctx) { super(ctx); }
|
private TunnelBuildReplyMessageHandlerJob(RouterContext ctx) { super(ctx); }
|
||||||
public void runJob() {}
|
public void runJob() {}
|
||||||
public String getName() { return "Receive tunnel build reply message"; }
|
public String getName() { return "Receive tunnel build reply message"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the participating tunnel if we can't contact the next hop
|
||||||
|
* Not strictly necessary, as the entry doesn't use that much space,
|
||||||
|
* but it affects capacity calculations
|
||||||
|
*/
|
||||||
|
private static class TunnelBuildNextHopFailJob extends JobImpl {
|
||||||
|
HopConfig _cfg;
|
||||||
|
private TunnelBuildNextHopFailJob(RouterContext ctx, HopConfig cfg) {
|
||||||
|
super(ctx);
|
||||||
|
_cfg = cfg;
|
||||||
|
}
|
||||||
|
public String getName() { return "Timeout contacting next peer for tunnel join"; }
|
||||||
|
public void runJob() {
|
||||||
|
getContext().tunnelDispatcher().remove(_cfg);
|
||||||
|
getContext().statManager().addRateData("tunnel.rejectTimeout2", 1, 0);
|
||||||
|
// static, no _log
|
||||||
|
//_log.error("Cant contact next hop for " + _cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import net.i2p.data.RouterInfo;
|
|||||||
import net.i2p.data.TunnelId;
|
import net.i2p.data.TunnelId;
|
||||||
import net.i2p.data.i2np.I2NPMessage;
|
import net.i2p.data.i2np.I2NPMessage;
|
||||||
import net.i2p.data.i2np.TunnelBuildMessage;
|
import net.i2p.data.i2np.TunnelBuildMessage;
|
||||||
|
import net.i2p.router.JobImpl;
|
||||||
import net.i2p.router.OutNetMessage;
|
import net.i2p.router.OutNetMessage;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.TunnelInfo;
|
import net.i2p.router.TunnelInfo;
|
||||||
@ -136,6 +137,7 @@ class BuildRequestor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
outMsg.setTarget(peer);
|
outMsg.setTarget(peer);
|
||||||
|
outMsg.setOnFailedSendJob(new TunnelBuildFirstHopFailJob(ctx, pool, cfg, exec));
|
||||||
ctx.outNetMessagePool().add(outMsg);
|
ctx.outNetMessagePool().add(outMsg);
|
||||||
}
|
}
|
||||||
if (log.shouldLog(Log.DEBUG))
|
if (log.shouldLog(Log.DEBUG))
|
||||||
@ -213,4 +215,33 @@ class BuildRequestor {
|
|||||||
ctx.jobQueue().addJob(expireJob);
|
ctx.jobQueue().addJob(expireJob);
|
||||||
// can it get much easier?
|
// can it get much easier?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do two important things if we can't get the build msg to the
|
||||||
|
* first hop on an outbound tunnel -
|
||||||
|
* - Call buildComplete() so we can get started on the next build
|
||||||
|
* without waiting for the full expire time
|
||||||
|
* - Blame the first hop in the profile
|
||||||
|
* Most likely to happen on an exploratory tunnel, obviously.
|
||||||
|
* Can't do this for inbound tunnels since the msg goes out an expl. tunnel.
|
||||||
|
*/
|
||||||
|
private static class TunnelBuildFirstHopFailJob extends JobImpl {
|
||||||
|
TunnelPool _pool;
|
||||||
|
PooledTunnelCreatorConfig _cfg;
|
||||||
|
BuildExecutor _exec;
|
||||||
|
private TunnelBuildFirstHopFailJob(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, BuildExecutor exec) {
|
||||||
|
super(ctx);
|
||||||
|
_cfg = cfg;
|
||||||
|
_exec = exec;
|
||||||
|
_pool = pool;
|
||||||
|
}
|
||||||
|
public String getName() { return "Timeout contacting first peer for OB tunnel"; }
|
||||||
|
public void runJob() {
|
||||||
|
_exec.buildComplete(_cfg, _pool);
|
||||||
|
getContext().profileManager().tunnelTimedOut(_cfg.getPeer(1));
|
||||||
|
getContext().statManager().addRateData("tunnel.buildFailFirstHop", 1, 0);
|
||||||
|
// static, no _log
|
||||||
|
//System.err.println("Cant contact first hop for " + _cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user