From 7839c0fec3213063df76670f8843df10a0de9f06 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 26 Oct 2013 20:52:56 +0000 Subject: [PATCH] * Tunnels: - Don't use fallback expl. tunnels as the paired tunnel for a client tunnel build. This will cause more client tunnel breakage but it's really bad to use a zero-hop for this. - Fix selection of an expl. tunnel close to a hash - Don't update build generation stat if the generation failed - log tweaks --- history.txt | 7 ++ .../src/net/i2p/router/RouterVersion.java | 2 +- .../i2p/router/tunnel/pool/BuildExecutor.java | 4 +- .../router/tunnel/pool/BuildRequestor.java | 85 ++++++++++++------- .../router/tunnel/pool/TunnelPoolManager.java | 8 +- 5 files changed, 69 insertions(+), 37 deletions(-) diff --git a/history.txt b/history.txt index 815f382d37..289ee0e16e 100644 --- a/history.txt +++ b/history.txt @@ -1,5 +1,12 @@ 2013-10-26 zzz + * i2psnark: Display base name, not torrent file name (ticket #985) * I2PTunnel HTTP server: New POST limiter + * Profiles: Ensure we select random peers even before the first reorganization + * Streaming: Randomize end of first conn limit period + * Tunnels: + - Don't use fallback expl. tunnels as the paired tunnel + for a client tunnel build. + - Fix selection of an expl. tunnel close to a hash 2013-10-25 zzz * Router: Only log ping file error once (ticket #1086) diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 5a58b19bc2..e36cd3b143 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 11; + public final static long BUILD = 12; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java index 3ed3c18ebb..5b6e95944b 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java @@ -471,7 +471,9 @@ class BuildExecutor implements Runnable { cfg.setReplyMessageId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE)); } while (addToBuilding(cfg)); // if a dup, go araound again } - BuildRequestor.request(_context, pool, cfg, this); + boolean ok = BuildRequestor.request(_context, pool, cfg, this); + if (!ok) + return; long buildTime = System.currentTimeMillis() - beforeBuild; if (cfg.getLength() <= 1) _context.statManager().addRateData("tunnel.buildRequestZeroHopTime", buildTime, 0); diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java index 32ad62b245..6ef984cc6f 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java @@ -16,6 +16,7 @@ import net.i2p.router.JobImpl; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; import net.i2p.router.TunnelInfo; +import net.i2p.router.TunnelManagerFacade; import net.i2p.router.tunnel.BuildMessageGenerator; import net.i2p.util.Log; import net.i2p.util.VersionComparator; @@ -98,15 +99,19 @@ abstract class BuildRequestor { } /** + * Send out a build request message. + * * @param cfg ReplyMessageId must be set + * @return success */ - public static void request(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, BuildExecutor exec) { + public static boolean request(RouterContext ctx, TunnelPool pool, + PooledTunnelCreatorConfig cfg, BuildExecutor exec) { // new style crypto fills in all the blanks, while the old style waits for replies to fill in the next hop, etc prepare(ctx, cfg); if (cfg.getLength() <= 1) { buildZeroHop(ctx, pool, cfg, exec); - return; + return true; } Log log = ctx.logManager().getLog(BuildRequestor.class); @@ -114,49 +119,66 @@ abstract class BuildRequestor { TunnelInfo pairedTunnel = null; Hash farEnd = cfg.getFarEnd(); + TunnelManagerFacade mgr = ctx.tunnelManager(); + boolean isInbound = pool.getSettings().isInbound(); if (pool.getSettings().isExploratory() || !usePairedTunnels(ctx)) { - if (pool.getSettings().isInbound()) - pairedTunnel = ctx.tunnelManager().selectOutboundExploratoryTunnel(farEnd); + if (isInbound) + pairedTunnel = mgr.selectOutboundExploratoryTunnel(farEnd); else - pairedTunnel = ctx.tunnelManager().selectInboundExploratoryTunnel(farEnd); + pairedTunnel = mgr.selectInboundExploratoryTunnel(farEnd); } else { - if (pool.getSettings().isInbound()) - pairedTunnel = ctx.tunnelManager().selectOutboundTunnel(pool.getSettings().getDestination(), farEnd); + // building a client tunnel + if (isInbound) + pairedTunnel = mgr.selectOutboundTunnel(pool.getSettings().getDestination(), farEnd); else - pairedTunnel = ctx.tunnelManager().selectInboundTunnel(pool.getSettings().getDestination(), farEnd); - } - if (pairedTunnel == null) { - if (log.shouldLog(Log.WARN)) - log.warn("Couldn't find a paired tunnel for " + cfg + ", fall back on exploratory tunnels for pairing"); - if (!pool.getSettings().isExploratory() && usePairedTunnels(ctx)) - if (pool.getSettings().isInbound()) - pairedTunnel = ctx.tunnelManager().selectOutboundExploratoryTunnel(farEnd); - else - pairedTunnel = ctx.tunnelManager().selectInboundExploratoryTunnel(farEnd); + pairedTunnel = mgr.selectInboundTunnel(pool.getSettings().getDestination(), farEnd); + if (pairedTunnel == null) { + if (log.shouldLog(Log.INFO)) + log.info("Couldn't find a paired tunnel for " + cfg + ", fall back on exploratory tunnels for pairing"); + if (isInbound) { + pairedTunnel = mgr.selectOutboundExploratoryTunnel(farEnd); + if (pairedTunnel != null && + pairedTunnel.getLength() <= 1 && + mgr.getOutboundSettings().getLength() + mgr.getOutboundSettings().getLengthVariance() > 0) { + // don't build using a zero-hop expl., + // as it is both very bad for anonomyity, + // and it takes a build slot away from exploratory + pairedTunnel = null; + } + } else { + pairedTunnel = mgr.selectInboundExploratoryTunnel(farEnd); + if (pairedTunnel != null && + pairedTunnel.getLength() <= 1 && + mgr.getInboundSettings().getLength() + mgr.getInboundSettings().getLengthVariance() > 0) { + // ditto + pairedTunnel = null; + } + } + } } if (pairedTunnel == null) { - if (log.shouldLog(Log.ERROR)) - log.error("Tunnel build failed, as we couldn't find a paired tunnel for " + cfg); + if (log.shouldLog(Log.WARN)) + log.warn("Tunnel build failed, as we couldn't find a paired tunnel for " + cfg); exec.buildComplete(cfg, pool); - // Not even a zero-hop exploratory tunnel? We are in big trouble. + // Not even an exploratory tunnel? We are in big trouble. // Let's not spin through here too fast. try { Thread.sleep(250); } catch (InterruptedException ie) {} - return; + return false; } - long beforeCreate = System.currentTimeMillis(); + //long beforeCreate = System.currentTimeMillis(); TunnelBuildMessage msg = createTunnelBuildMessage(ctx, pool, cfg, pairedTunnel, exec); - long createTime = System.currentTimeMillis()-beforeCreate; + //long createTime = System.currentTimeMillis()-beforeCreate; if (msg == null) { if (log.shouldLog(Log.WARN)) log.warn("Tunnel build failed, as we couldn't create the tunnel build message for " + cfg); exec.buildComplete(cfg, pool); - return; + return false; } //cfg.setPairedTunnel(pairedTunnel); - long beforeDispatch = System.currentTimeMillis(); + //long beforeDispatch = System.currentTimeMillis(); if (cfg.isInbound()) { if (log.shouldLog(Log.INFO)) log.info("Sending the tunnel build request " + msg.getUniqueId() + " out the tunnel " + pairedTunnel + " to " @@ -182,15 +204,16 @@ abstract class BuildRequestor { if (log.shouldLog(Log.WARN)) log.warn("Could not find the next hop to send the outbound request to: " + cfg); exec.buildComplete(cfg, pool); - return; + return false; } OutNetMessage outMsg = new OutNetMessage(ctx, msg, ctx.clock().now() + FIRST_HOP_TIMEOUT, PRIORITY, peer); outMsg.setOnFailedSendJob(new TunnelBuildFirstHopFailJob(ctx, pool, cfg, exec)); ctx.outNetMessagePool().add(outMsg); } - if (log.shouldLog(Log.DEBUG)) - log.debug("Tunnel build message " + msg.getUniqueId() + " created in " + createTime - + "ms and dispatched in " + (System.currentTimeMillis()-beforeDispatch)); + //if (log.shouldLog(Log.DEBUG)) + // log.debug("Tunnel build message " + msg.getUniqueId() + " created in " + createTime + // + "ms and dispatched in " + (System.currentTimeMillis()-beforeDispatch)); + return true; } private static final String MIN_VARIABLE_VERSION = "0.7.12"; @@ -266,8 +289,8 @@ abstract class BuildRequestor { if (useVariable) { msg = new VariableTunnelBuildMessage(ctx, SHORT_RECORDS); order = new ArrayList(SHORT_ORDER); - if (log.shouldLog(Log.INFO)) - log.info("Using new VTBM"); + //if (log.shouldLog(Log.INFO)) + // log.info("Using new VTBM"); } else { msg = new TunnelBuildMessage(ctx); order = new ArrayList(ORDER); diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java index 464a5791ca..dd0c026f32 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java @@ -177,11 +177,11 @@ public class TunnelPoolManager implements TunnelManagerFacade { * @since 0.8.10 */ public TunnelInfo selectInboundExploratoryTunnel(Hash closestTo) { - TunnelInfo info = _inboundExploratory.selectTunnel(); + TunnelInfo info = _inboundExploratory.selectTunnel(closestTo); if (info == null) { _inboundExploratory.buildFallback(); // still can be null, but probably not - info = _inboundExploratory.selectTunnel(closestTo); + info = _inboundExploratory.selectTunnel(); } return info; } @@ -221,11 +221,11 @@ public class TunnelPoolManager implements TunnelManagerFacade { * @since 0.8.10 */ public TunnelInfo selectOutboundExploratoryTunnel(Hash closestTo) { - TunnelInfo info = _outboundExploratory.selectTunnel(); + TunnelInfo info = _outboundExploratory.selectTunnel(closestTo); if (info == null) { _outboundExploratory.buildFallback(); // still can be null, but probably not - info = _outboundExploratory.selectTunnel(closestTo); + info = _outboundExploratory.selectTunnel(); } return info; }