* 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
This commit is contained in:
zzz
2013-10-26 20:52:56 +00:00
parent 4d24d65c1f
commit 7839c0fec3
5 changed files with 69 additions and 37 deletions

View File

@ -1,5 +1,12 @@
2013-10-26 zzz 2013-10-26 zzz
* i2psnark: Display base name, not torrent file name (ticket #985)
* I2PTunnel HTTP server: New POST limiter * 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 2013-10-25 zzz
* Router: Only log ping file error once (ticket #1086) * Router: Only log ping file error once (ticket #1086)

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 11; public final static long BUILD = 12;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";

View File

@ -471,7 +471,9 @@ class BuildExecutor implements Runnable {
cfg.setReplyMessageId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE)); cfg.setReplyMessageId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
} while (addToBuilding(cfg)); // if a dup, go araound again } 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; long buildTime = System.currentTimeMillis() - beforeBuild;
if (cfg.getLength() <= 1) if (cfg.getLength() <= 1)
_context.statManager().addRateData("tunnel.buildRequestZeroHopTime", buildTime, 0); _context.statManager().addRateData("tunnel.buildRequestZeroHopTime", buildTime, 0);

View File

@ -16,6 +16,7 @@ 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;
import net.i2p.router.TunnelManagerFacade;
import net.i2p.router.tunnel.BuildMessageGenerator; import net.i2p.router.tunnel.BuildMessageGenerator;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.VersionComparator; import net.i2p.util.VersionComparator;
@ -98,15 +99,19 @@ abstract class BuildRequestor {
} }
/** /**
* Send out a build request message.
*
* @param cfg ReplyMessageId must be set * @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 // 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); prepare(ctx, cfg);
if (cfg.getLength() <= 1) { if (cfg.getLength() <= 1) {
buildZeroHop(ctx, pool, cfg, exec); buildZeroHop(ctx, pool, cfg, exec);
return; return true;
} }
Log log = ctx.logManager().getLog(BuildRequestor.class); Log log = ctx.logManager().getLog(BuildRequestor.class);
@ -114,49 +119,66 @@ abstract class BuildRequestor {
TunnelInfo pairedTunnel = null; TunnelInfo pairedTunnel = null;
Hash farEnd = cfg.getFarEnd(); Hash farEnd = cfg.getFarEnd();
TunnelManagerFacade mgr = ctx.tunnelManager();
boolean isInbound = pool.getSettings().isInbound();
if (pool.getSettings().isExploratory() || !usePairedTunnels(ctx)) { if (pool.getSettings().isExploratory() || !usePairedTunnels(ctx)) {
if (pool.getSettings().isInbound()) if (isInbound)
pairedTunnel = ctx.tunnelManager().selectOutboundExploratoryTunnel(farEnd); pairedTunnel = mgr.selectOutboundExploratoryTunnel(farEnd);
else else
pairedTunnel = ctx.tunnelManager().selectInboundExploratoryTunnel(farEnd); pairedTunnel = mgr.selectInboundExploratoryTunnel(farEnd);
} else { } else {
if (pool.getSettings().isInbound()) // building a client tunnel
pairedTunnel = ctx.tunnelManager().selectOutboundTunnel(pool.getSettings().getDestination(), farEnd); if (isInbound)
pairedTunnel = mgr.selectOutboundTunnel(pool.getSettings().getDestination(), farEnd);
else else
pairedTunnel = ctx.tunnelManager().selectInboundTunnel(pool.getSettings().getDestination(), farEnd); pairedTunnel = mgr.selectInboundTunnel(pool.getSettings().getDestination(), farEnd);
} if (pairedTunnel == null) {
if (pairedTunnel == null) { if (log.shouldLog(Log.INFO))
if (log.shouldLog(Log.WARN)) log.info("Couldn't find a paired tunnel for " + cfg + ", fall back on exploratory tunnels for pairing");
log.warn("Couldn't find a paired tunnel for " + cfg + ", fall back on exploratory tunnels for pairing"); if (isInbound) {
if (!pool.getSettings().isExploratory() && usePairedTunnels(ctx)) pairedTunnel = mgr.selectOutboundExploratoryTunnel(farEnd);
if (pool.getSettings().isInbound()) if (pairedTunnel != null &&
pairedTunnel = ctx.tunnelManager().selectOutboundExploratoryTunnel(farEnd); pairedTunnel.getLength() <= 1 &&
else mgr.getOutboundSettings().getLength() + mgr.getOutboundSettings().getLengthVariance() > 0) {
pairedTunnel = ctx.tunnelManager().selectInboundExploratoryTunnel(farEnd); // 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 (pairedTunnel == null) {
if (log.shouldLog(Log.ERROR)) if (log.shouldLog(Log.WARN))
log.error("Tunnel build failed, as we couldn't find a paired tunnel for " + cfg); log.warn("Tunnel build failed, as we couldn't find a paired tunnel for " + cfg);
exec.buildComplete(cfg, pool); 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. // Let's not spin through here too fast.
try { Thread.sleep(250); } catch (InterruptedException ie) {} 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); TunnelBuildMessage msg = createTunnelBuildMessage(ctx, pool, cfg, pairedTunnel, exec);
long createTime = System.currentTimeMillis()-beforeCreate; //long createTime = System.currentTimeMillis()-beforeCreate;
if (msg == null) { if (msg == null) {
if (log.shouldLog(Log.WARN)) if (log.shouldLog(Log.WARN))
log.warn("Tunnel build failed, as we couldn't create the tunnel build message for " + cfg); log.warn("Tunnel build failed, as we couldn't create the tunnel build message for " + cfg);
exec.buildComplete(cfg, pool); exec.buildComplete(cfg, pool);
return; return false;
} }
//cfg.setPairedTunnel(pairedTunnel); //cfg.setPairedTunnel(pairedTunnel);
long beforeDispatch = System.currentTimeMillis(); //long beforeDispatch = System.currentTimeMillis();
if (cfg.isInbound()) { if (cfg.isInbound()) {
if (log.shouldLog(Log.INFO)) if (log.shouldLog(Log.INFO))
log.info("Sending the tunnel build request " + msg.getUniqueId() + " out the tunnel " + pairedTunnel + " to " 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)) if (log.shouldLog(Log.WARN))
log.warn("Could not find the next hop to send the outbound request to: " + cfg); log.warn("Could not find the next hop to send the outbound request to: " + cfg);
exec.buildComplete(cfg, pool); exec.buildComplete(cfg, pool);
return; return false;
} }
OutNetMessage outMsg = new OutNetMessage(ctx, msg, ctx.clock().now() + FIRST_HOP_TIMEOUT, PRIORITY, peer); OutNetMessage outMsg = new OutNetMessage(ctx, msg, ctx.clock().now() + FIRST_HOP_TIMEOUT, PRIORITY, peer);
outMsg.setOnFailedSendJob(new TunnelBuildFirstHopFailJob(ctx, pool, cfg, exec)); 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))
log.debug("Tunnel build message " + msg.getUniqueId() + " created in " + createTime // log.debug("Tunnel build message " + msg.getUniqueId() + " created in " + createTime
+ "ms and dispatched in " + (System.currentTimeMillis()-beforeDispatch)); // + "ms and dispatched in " + (System.currentTimeMillis()-beforeDispatch));
return true;
} }
private static final String MIN_VARIABLE_VERSION = "0.7.12"; private static final String MIN_VARIABLE_VERSION = "0.7.12";
@ -266,8 +289,8 @@ abstract class BuildRequestor {
if (useVariable) { if (useVariable) {
msg = new VariableTunnelBuildMessage(ctx, SHORT_RECORDS); msg = new VariableTunnelBuildMessage(ctx, SHORT_RECORDS);
order = new ArrayList(SHORT_ORDER); order = new ArrayList(SHORT_ORDER);
if (log.shouldLog(Log.INFO)) //if (log.shouldLog(Log.INFO))
log.info("Using new VTBM"); // log.info("Using new VTBM");
} else { } else {
msg = new TunnelBuildMessage(ctx); msg = new TunnelBuildMessage(ctx);
order = new ArrayList(ORDER); order = new ArrayList(ORDER);

View File

@ -177,11 +177,11 @@ public class TunnelPoolManager implements TunnelManagerFacade {
* @since 0.8.10 * @since 0.8.10
*/ */
public TunnelInfo selectInboundExploratoryTunnel(Hash closestTo) { public TunnelInfo selectInboundExploratoryTunnel(Hash closestTo) {
TunnelInfo info = _inboundExploratory.selectTunnel(); TunnelInfo info = _inboundExploratory.selectTunnel(closestTo);
if (info == null) { if (info == null) {
_inboundExploratory.buildFallback(); _inboundExploratory.buildFallback();
// still can be null, but probably not // still can be null, but probably not
info = _inboundExploratory.selectTunnel(closestTo); info = _inboundExploratory.selectTunnel();
} }
return info; return info;
} }
@ -221,11 +221,11 @@ public class TunnelPoolManager implements TunnelManagerFacade {
* @since 0.8.10 * @since 0.8.10
*/ */
public TunnelInfo selectOutboundExploratoryTunnel(Hash closestTo) { public TunnelInfo selectOutboundExploratoryTunnel(Hash closestTo) {
TunnelInfo info = _outboundExploratory.selectTunnel(); TunnelInfo info = _outboundExploratory.selectTunnel(closestTo);
if (info == null) { if (info == null) {
_outboundExploratory.buildFallback(); _outboundExploratory.buildFallback();
// still can be null, but probably not // still can be null, but probably not
info = _outboundExploratory.selectTunnel(closestTo); info = _outboundExploratory.selectTunnel();
} }
return info; return info;
} }