diff --git a/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java b/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java index 06a9a5211..3397c38ca 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java @@ -132,6 +132,8 @@ public class SAMStreamSession { if (socketMgr == null) { throw new SAMException("Error creating I2PSocketManager"); } + + socketMgr.addDisconnectListener(new DisconnectListener()); forceFlush = Boolean.valueOf(allprops.getProperty(PROP_FORCE_FLUSH, DEFAULT_FORCE_FLUSH)).booleanValue(); @@ -156,6 +158,12 @@ public class SAMStreamSession { t.start(); } } + + private class DisconnectListener implements I2PSocketManager.DisconnectListener { + public void sessionDisconnected() { + close(); + } + } /** * Get the SAM STREAM session Destination. diff --git a/core/java/src/net/i2p/time/Timestamper.java b/core/java/src/net/i2p/time/Timestamper.java index a1e785233..622d90b83 100644 --- a/core/java/src/net/i2p/time/Timestamper.java +++ b/core/java/src/net/i2p/time/Timestamper.java @@ -144,7 +144,7 @@ public class Timestamper implements Runnable { * True if the time was queried successfully, false if it couldn't be */ private boolean queryTime(String serverList[]) throws IllegalArgumentException { - long found[] = new long[serverList.length]; + long found[] = new long[_concurringServers]; long localTime = -1; long now = -1; long expectedDelta = 0; diff --git a/history.txt b/history.txt index 5d7556c0c..e688d3a20 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,12 @@ -$Id: history.txt,v 1.151 2005/02/22 02:07:34 jrandom Exp $ +$Id: history.txt,v 1.152 2005/02/22 18:13:00 jrandom Exp $ + +2005-02-22 jrandom + * Reworked the tunnel (re)building process to remove the tokens and + provide cleaner controls on the tunnels built. + * Fixed situations where the timestamper wanted to test more servers than + were provided (thanks Tracker!) + * Get rid of the dead SAM sessions by using the streaming lib's callbacks + (thanks Tracker!) 2005-02-22 jrandom * Temporary workaround for the I2CP disconnect bug (have the streaminglib diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index eb7da34bc..578375fa7 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -15,9 +15,9 @@ import net.i2p.CoreVersion; * */ public class RouterVersion { - public final static String ID = "$Revision: 1.146 $ $Date: 2005/02/22 02:07:33 $"; + public final static String ID = "$Revision: 1.147 $ $Date: 2005/02/22 17:58:22 $"; public final static String VERSION = "0.5"; - public final static long BUILD = 5; + public final static long BUILD = 6; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION); System.out.println("Router ID: " + RouterVersion.ID); diff --git a/router/java/src/net/i2p/router/tunnel/pool/ExpireJob.java b/router/java/src/net/i2p/router/tunnel/pool/ExpireJob.java index f21aaa4b2..83ec39570 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/ExpireJob.java +++ b/router/java/src/net/i2p/router/tunnel/pool/ExpireJob.java @@ -8,13 +8,11 @@ import net.i2p.router.tunnel.TunnelCreatorConfig; class ExpireJob extends JobImpl { private TunnelPool _pool; private TunnelCreatorConfig _cfg; - private Object _buildToken; private boolean _leaseUpdated; - public ExpireJob(RouterContext ctx, TunnelCreatorConfig cfg, TunnelPool pool, Object buildToken) { + public ExpireJob(RouterContext ctx, TunnelCreatorConfig cfg, TunnelPool pool) { super(ctx); _pool = pool; _cfg = cfg; - _buildToken = buildToken; _leaseUpdated = false; // give 'em some extra time before dropping 'em getTiming().setStartAfter(cfg.getExpiration()); // + Router.CLOCK_FUDGE_FACTOR); diff --git a/router/java/src/net/i2p/router/tunnel/pool/OnCreatedJob.java b/router/java/src/net/i2p/router/tunnel/pool/OnCreatedJob.java index a57b32a9d..74b5ed28f 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/OnCreatedJob.java +++ b/router/java/src/net/i2p/router/tunnel/pool/OnCreatedJob.java @@ -13,17 +13,13 @@ import net.i2p.util.Log; class OnCreatedJob extends JobImpl { private Log _log; private TunnelPool _pool; - private Object _buildToken; private PooledTunnelCreatorConfig _cfg; - private boolean _fake; - public OnCreatedJob(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, boolean fake, Object buildToken) { + public OnCreatedJob(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg) { super(ctx); _log = ctx.logManager().getLog(OnCreatedJob.class); _pool = pool; _cfg = cfg; - _fake = fake; - _buildToken = buildToken; } public String getName() { return "Tunnel built"; } public void runJob() { @@ -34,17 +30,16 @@ class OnCreatedJob extends JobImpl { getContext().tunnelDispatcher().joinOutbound(_cfg); } _pool.addTunnel(_cfg); - TestJob testJob = (_cfg.getLength() > 1 ? new TestJob(getContext(), _cfg, _pool, _buildToken) : null); - RebuildJob rebuildJob = (_fake ? null : new RebuildJob(getContext(), _cfg, _pool, _buildToken)); - ExpireJob expireJob = new ExpireJob(getContext(), _cfg, _pool, _buildToken); + TestJob testJob = (_cfg.getLength() > 1 ? new TestJob(getContext(), _cfg, _pool) : null); + RebuildJob rebuildJob = new RebuildJob(getContext(), _cfg, _pool); + ExpireJob expireJob = new ExpireJob(getContext(), _cfg, _pool); _cfg.setTunnelPool(_pool); _cfg.setTestJob(testJob); _cfg.setRebuildJob(rebuildJob); _cfg.setExpireJob(expireJob); if (_cfg.getLength() > 1) // no need to test 0 hop tunnels getContext().jobQueue().addJob(testJob); - if (!_fake) // if we built a 0 hop tunnel in response to a failure, don't rebuild - getContext().jobQueue().addJob(rebuildJob); + getContext().jobQueue().addJob(rebuildJob); // always try to rebuild (ignored if too many) getContext().jobQueue().addJob(expireJob); } } \ No newline at end of file diff --git a/router/java/src/net/i2p/router/tunnel/pool/RebuildJob.java b/router/java/src/net/i2p/router/tunnel/pool/RebuildJob.java index 902ad9235..7f40af6f4 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/RebuildJob.java +++ b/router/java/src/net/i2p/router/tunnel/pool/RebuildJob.java @@ -11,20 +11,18 @@ import net.i2p.router.tunnel.TunnelCreatorConfig; */ class RebuildJob extends JobImpl { private TunnelPool _pool; - private Object _buildToken; private TunnelCreatorConfig _cfg; - public RebuildJob(RouterContext ctx, TunnelCreatorConfig cfg, TunnelPool pool, Object buildToken) { + public RebuildJob(RouterContext ctx, TunnelCreatorConfig cfg, TunnelPool pool) { super(ctx); _pool = pool; _cfg = cfg; - _buildToken = buildToken; long rebuildOn = cfg.getExpiration() - pool.getSettings().getRebuildPeriod(); rebuildOn -= ctx.random().nextInt(pool.getSettings().getRebuildPeriod()*2); getTiming().setStartAfter(rebuildOn); } public String getName() { return "Rebuild tunnel"; } public void runJob() { - _pool.getBuilder().buildTunnel(getContext(), _pool, _buildToken); + _pool.getBuilder().buildTunnel(getContext(), _pool); } } \ No newline at end of file diff --git a/router/java/src/net/i2p/router/tunnel/pool/TestJob.java b/router/java/src/net/i2p/router/tunnel/pool/TestJob.java index 5a2d4366f..1c7517098 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TestJob.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TestJob.java @@ -24,19 +24,17 @@ import net.i2p.util.Log; class TestJob extends JobImpl { private Log _log; private TunnelPool _pool; - private Object _buildToken; private PooledTunnelCreatorConfig _cfg; private boolean _found; /** base to randomize the test delay on */ private static final int TEST_DELAY = 60*1000; - public TestJob(RouterContext ctx, PooledTunnelCreatorConfig cfg, TunnelPool pool, Object buildToken) { + public TestJob(RouterContext ctx, PooledTunnelCreatorConfig cfg, TunnelPool pool) { super(ctx); _log = ctx.logManager().getLog(TestJob.class); _pool = pool; _cfg = cfg; - _buildToken = buildToken; getTiming().setStartAfter(getDelay() + ctx.clock().now()); ctx.statManager().createRateStat("tunnel.testFailedTime", "How long did the failure take (max of 60s for full timeout)?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelBuilder.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelBuilder.java index 22ca20419..501ed3b5b 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelBuilder.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelBuilder.java @@ -27,50 +27,42 @@ public class TunnelBuilder { * jobs are built. This call does not block. * */ - public void buildTunnel(RouterContext ctx, TunnelPool pool, Object poolToken) { - buildTunnel(ctx, pool, false, poolToken); + public void buildTunnel(RouterContext ctx, TunnelPool pool) { + buildTunnel(ctx, pool, false); } - public void buildTunnel(RouterContext ctx, TunnelPool pool, boolean fake, Object poolToken) { - if (!pool.keepBuilding(poolToken)) - return; - + public void buildTunnel(RouterContext ctx, TunnelPool pool, boolean zeroHop) { // this is probably overkill (ya think?) pool.refreshSettings(); - PooledTunnelCreatorConfig cfg = configTunnel(ctx, pool, fake); - if ( (cfg == null) && (!fake) ) { - RetryJob j = new RetryJob(ctx, pool, poolToken); + PooledTunnelCreatorConfig cfg = configTunnel(ctx, pool, zeroHop); + if (cfg == null) { + RetryJob j = new RetryJob(ctx, pool); j.getTiming().setStartAfter(ctx.clock().now() + ctx.random().nextInt(30*1000)); ctx.jobQueue().addJob(j); return; } - OnCreatedJob onCreated = new OnCreatedJob(ctx, pool, cfg, fake, poolToken); - RetryJob onFailed= (fake ? null : new RetryJob(ctx, pool, poolToken)); + OnCreatedJob onCreated = new OnCreatedJob(ctx, pool, cfg); + RetryJob onFailed= (zeroHop ? null : new RetryJob(ctx, pool)); // queue up a job to request the endpoint to join the tunnel, which then // requeues up another job for earlier hops, etc, until it reaches the // gateway. after the gateway is confirmed, onCreated is fired - RequestTunnelJob req = new RequestTunnelJob(ctx, cfg, onCreated, onFailed, cfg.getLength()-1, fake, pool.getSettings().isExploratory()); - if (fake) // lets get it done inline, as we /need/ it asap + RequestTunnelJob req = new RequestTunnelJob(ctx, cfg, onCreated, onFailed, cfg.getLength()-1, zeroHop, pool.getSettings().isExploratory()); + if (zeroHop || (cfg.getLength() <= 1) ) // lets get it done inline, as we /need/ it asap req.runJob(); else ctx.jobQueue().addJob(req); } - private PooledTunnelCreatorConfig configTunnel(RouterContext ctx, TunnelPool pool, boolean fake) { + private PooledTunnelCreatorConfig configTunnel(RouterContext ctx, TunnelPool pool, boolean zeroHop) { Log log = ctx.logManager().getLog(TunnelBuilder.class); TunnelPoolSettings settings = pool.getSettings(); long expiration = ctx.clock().now() + settings.getDuration(); List peers = null; - long failures = countFailures(ctx); - boolean failing = (failures > 5) && (pool.getSettings().getAllowZeroHop()); - boolean failsafe = false; - if (failing && (ctx.random().nextInt(100) < failures) ) - failsafe = true; - if (fake || failsafe) { + if (zeroHop) { peers = new ArrayList(1); peers.add(ctx.routerHash()); - if ( (failsafe) && (log.shouldLog(Log.WARN)) ) + if (log.shouldLog(Log.WARN)) log.warn("Building failsafe tunnel for " + pool); } else { peers = pool.getSelector().selectPeers(ctx, settings); @@ -80,10 +72,10 @@ public class TunnelBuilder { // the pool is refusing 0 hop tunnels if (peers == null) { if (log.shouldLog(Log.ERROR)) - log.error("No peers to put in the new tunnel! selectPeers returned null! boo, hiss! fake=" + fake); + log.error("No peers to put in the new tunnel! selectPeers returned null! boo, hiss! fake=" + zeroHop); } else { if (log.shouldLog(Log.ERROR)) - log.error("No peers to put in the new tunnel! selectPeers returned an empty list?! fake=" + fake); + log.error("No peers to put in the new tunnel! selectPeers returned an empty list?! fake=" + zeroHop); } return null; } @@ -108,36 +100,20 @@ public class TunnelBuilder { return cfg; } - private long countFailures(RouterContext ctx) { - RateStat rs = ctx.statManager().getRate("tunnel.testFailedTime"); - if (rs == null) - return 0; - Rate r = rs.getRate(10*60*1000); - if (r == null) - return 0; - else - return r.getCurrentEventCount(); - } - /** * If the building fails, try, try again. * */ private class RetryJob extends JobImpl { private TunnelPool _pool; - private Object _buildToken; - public RetryJob(RouterContext ctx, TunnelPool pool, Object buildToken) { + public RetryJob(RouterContext ctx, TunnelPool pool) { super(ctx); _pool = pool; - _buildToken = buildToken; } - public String getName() { return "tunnel create failed"; } + public String getName() { return "Tunnel create failed"; } public void runJob() { // yikes, nothing left, lets get some backup (if we're allowed) - if ( (_pool.selectTunnel() == null) && (_pool.getSettings().getAllowZeroHop()) ) - _pool.buildFake(); - - buildTunnel(getContext(), _pool, _buildToken); + _pool.refreshBuilders(); } } } diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java index b51965156..64f49da85 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java @@ -30,14 +30,6 @@ public class TunnelPool { private boolean _alive; private long _lifetimeProcessed; - /** - * list of pool tokens (Object) passed around during building/rebuilding/etc. - * if/when the token is removed from this list, that sequence of building/rebuilding/etc - * should cease (though others may continue). - * - */ - private List _tokens; - public TunnelPool(RouterContext ctx, TunnelPoolManager mgr, TunnelPoolSettings settings, TunnelPeerSelector sel, TunnelBuilder builder) { _context = ctx; _log = ctx.logManager().getLog(TunnelPool.class); @@ -46,7 +38,6 @@ public class TunnelPool { _tunnels = new ArrayList(settings.getLength() + settings.getBackupQuantity()); _peerSelector = sel; _builder = builder; - _tokens = new ArrayList(settings.getBackupQuantity() + settings.getQuantity()); _alive = false; _lifetimeProcessed = 0; refreshSettings(); @@ -70,102 +61,39 @@ public class TunnelPool { } public void shutdown() { _alive = false; - synchronized (_tokens) { _tokens.clear(); } + } + + private int countUsableTunnels() { + int valid = 0; + synchronized (_tunnels) { + for (int i = 0; i < _tunnels.size(); i++) { + TunnelInfo info = (TunnelInfo)_tunnels.get(i); + if (info.getExpiration() > _context.clock().now() + 3*_settings.getRebuildPeriod()) + valid++; + } + } + return valid; } - private int refreshBuilders() { + /** + * Fire up as many buildTunnel tasks as necessary, returning how many + * were added + * + */ + int refreshBuilders() { + if (!_alive) return 0; // only start up new build tasks if we need more of 'em int target = _settings.getQuantity() + _settings.getBackupQuantity(); - int oldTokenCount = 0; - List newTokens = null; - synchronized (_tokens) { - oldTokenCount = _tokens.size(); - while (_tokens.size() > target) - _tokens.remove(0); - if (_tokens.size() < target) { - int wanted = target - _tokens.size(); - newTokens = new ArrayList(wanted); - for (int i = 0; i < wanted; i++) { - Object token = new Object(); - newTokens.add(token); - _tokens.add(token); - } - } - } + int usableTunnels = countUsableTunnels(); - if (newTokens != null) { - if (_log.shouldLog(Log.INFO)) - _log.info(toString() + ": refreshing builders, previously had " + oldTokenCount + if ( (target > usableTunnels) && (_log.shouldLog(Log.INFO)) ) + _log.info(toString() + ": refreshing builders, previously had " + usableTunnels + ", want a total of " + target + ", creating " - + newTokens.size() + " new ones."); - for (int i = 0; i < newTokens.size(); i++) { - Object token = newTokens.get(i); - if (_log.shouldLog(Log.DEBUG)) - _log.debug(toString() + ": Building a tunnel with the token " + token); - _builder.buildTunnel(_context, this, token); - } - return newTokens.size(); - } else { - return 0; - } - } - - /** do we still need this sequence of build/rebuild/etc to continue? */ - public boolean keepBuilding(Object token) { - boolean connected = true; - boolean rv = false; - int remaining = 0; - int wanted = _settings.getQuantity() + _settings.getBackupQuantity(); - if ( (_settings.getDestination() != null) && (!_context.clientManager().isLocal(_settings.getDestination())) ) - connected = false; - synchronized (_tokens) { - if (!connected) { - // client disconnected, so stop rebuilding this series - _tokens.remove(token); - rv = false; - } else { - rv = _tokens.contains(token); - } - remaining = _tokens.size(); - } + + (target-usableTunnels) + " new ones."); + for (int i = usableTunnels; i < target; i++) + _builder.buildTunnel(_context, this); - if (remaining <= 0) { - _manager.removeTunnels(_settings.getDestination()); - } - - if (!rv) { - if (_log.shouldLog(Log.INFO)) - _log.info(toString() + ": keepBuilding does NOT want building to continue (want " - + wanted + ", have " + remaining); - } else { - boolean needed = true; - int valid = 0; - synchronized (_tunnels) { - if (_tunnels.size() > wanted) { - for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo info = (TunnelInfo)_tunnels.get(i); - if (info.getExpiration() > _context.clock().now() + 3*_settings.getRebuildPeriod()) { - valid++; - if (valid >= wanted*2) - break; - } - } - if (valid >= wanted*2) - needed = false; - } - } - - if (!needed) { - if (_log.shouldLog(Log.WARN)) - _log.warn(toString() + ": keepBuilding wants building to continue, but not " - + " with the current object... # tunnels = " + valid + ", wanted = " + wanted); - synchronized (_tokens) { - _tokens.remove(token); - } - return false; - } - } - return rv; + return (target > usableTunnels ? target-usableTunnels : 0); } void refreshSettings() { @@ -210,7 +138,7 @@ public class TunnelPool { } if (_alive && _settings.getAllowZeroHop()) - buildFake(); + buildFallback(); if (allowRecurseOnFail) return selectTunnel(false); else @@ -244,6 +172,8 @@ public class TunnelPool { } } + int getTunnelCount() { synchronized (_tunnels) { return _tunnels.size(); } } + public TunnelBuilder getBuilder() { return _builder; } public TunnelPoolSettings getSettings() { return _settings; } public void setSettings(TunnelPoolSettings settings) { @@ -274,6 +204,8 @@ public class TunnelPool { if (ls != null) _context.clientManager().requestLeaseSet(_settings.getDestination(), ls); + + refreshBuilders(); } public void removeTunnel(TunnelInfo info) { @@ -298,9 +230,17 @@ public class TunnelPool { _log.warn(toString() + ": unable to build a new leaseSet on removal (" + remaining + " remaining), request a new tunnel"); if (_settings.getAllowZeroHop()) - buildFake(); + buildFallback(); } } + + boolean connected = true; + if ( (_settings.getDestination() != null) && (!_context.clientManager().isLocal(_settings.getDestination())) ) + connected = false; + if ( (getTunnelCount() <= 0) && (!connected) ) { + _manager.removeTunnels(_settings.getDestination()); + return; + } refreshBuilders(); } @@ -326,7 +266,7 @@ public class TunnelPool { _log.warn(toString() + ": unable to build a new leaseSet on failure (" + remaining + " remaining), request a new tunnel"); if (remaining < _settings.getBackupQuantity() + _settings.getQuantity()) - buildFake(false); + buildFallback(); } } refreshBuilders(); @@ -350,43 +290,23 @@ public class TunnelPool { + " remaining), request a new tunnel"); if ( (remaining < _settings.getBackupQuantity() + _settings.getQuantity()) && (_settings.getAllowZeroHop()) ) - buildFake(); + buildFallback(); } } } - void buildFake() { buildFake(true); } - void buildFake(boolean zeroHop) { + void buildFallback() { int quantity = _settings.getBackupQuantity() + _settings.getQuantity(); - boolean needed = true; - synchronized (_tunnels) { - if (_tunnels.size() > quantity) { - int valid = 0; - for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo info = (TunnelInfo)_tunnels.get(i); - if (info.getExpiration() > _context.clock().now() + 3*_settings.getRebuildPeriod()) { - valid++; - if (valid >= quantity) - break; - } - } - if (valid >= quantity) - needed = false; - } - } - - if (!needed) return; + int usable = countUsableTunnels(); + if (usable >= quantity) return; if (_log.shouldLog(Log.INFO)) - _log.info(toString() + ": building a fake tunnel (allow zeroHop? " + zeroHop + ")"); - Object tempToken = new Object(); - synchronized (_tokens) { - _tokens.add(tempToken); - } - _builder.buildTunnel(_context, this, zeroHop, tempToken); - synchronized (_tokens) { - _tokens.remove(tempToken); - } + _log.info(toString() + ": building a fallback tunnel (usable: " + usable + " needed: " + quantity + ")"); + if ( (usable == 0) && (_settings.getAllowZeroHop()) ) + _builder.buildTunnel(_context, this, true); + else + _builder.buildTunnel(_context, this); + refreshBuilders(); } /** 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 1aa5f6cec..a486ddb8d 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java @@ -26,12 +26,14 @@ import net.i2p.router.TunnelInfo; import net.i2p.router.TunnelManagerFacade; import net.i2p.router.TunnelPoolSettings; import net.i2p.router.tunnel.HopConfig; +import net.i2p.util.Log; /** * */ public class TunnelPoolManager implements TunnelManagerFacade { private RouterContext _context; + private Log _log; /** Hash (destination) to TunnelPool */ private Map _clientInboundPools; /** Hash (destination) to TunnelPool */ @@ -41,6 +43,7 @@ public class TunnelPoolManager implements TunnelManagerFacade { public TunnelPoolManager(RouterContext ctx) { _context = ctx; + _log = ctx.logManager().getLog(TunnelPoolManager.class); HandlerJobBuilder builder = new HandleTunnelCreateMessageJob.Builder(ctx); ctx.inNetMessagePool().registerHandlerJobBuilder(TunnelCreateMessage.MESSAGE_TYPE, builder); @@ -63,7 +66,7 @@ public class TunnelPoolManager implements TunnelManagerFacade { public TunnelInfo selectInboundTunnel() { TunnelInfo info = _inboundExploratory.selectTunnel(); if (info == null) { - _inboundExploratory.buildFake(); + _inboundExploratory.buildFallback(); // still can be null, but probably not info = _inboundExploratory.selectTunnel(); } @@ -80,6 +83,9 @@ public class TunnelPoolManager implements TunnelManagerFacade { if (pool != null) { return pool.selectTunnel(); } + if (_log.shouldLog(Log.CRIT)) + _log.log(Log.CRIT, "wtf, want the inbound tunnel for " + destination.calculateHash().toBase64() + + " but there isn't a pool?"); return null; } @@ -87,7 +93,7 @@ public class TunnelPoolManager implements TunnelManagerFacade { public TunnelInfo selectOutboundTunnel() { TunnelInfo info = _outboundExploratory.selectTunnel(); if (info == null) { - _outboundExploratory.buildFake(); + _outboundExploratory.buildFallback(); // still can be null, but probably not info = _outboundExploratory.selectTunnel(); } @@ -224,6 +230,10 @@ public class TunnelPoolManager implements TunnelManagerFacade { public void removeTunnels(Hash destination) { if (destination == null) return; + if (_context.clientManager().isLocal(destination)) { + if (_log.shouldLog(Log.CRIT)) + _log.log(Log.CRIT, "wtf, why are you removing the pool for " + destination.toBase64(), new Exception("i did it")); + } TunnelPool inbound = null; TunnelPool outbound = null; synchronized (_clientInboundPools) { @@ -268,7 +278,7 @@ public class TunnelPoolManager implements TunnelManagerFacade { } public String getName() { return "Bootstrap tunnel pool"; } public void runJob() { - _pool.buildFake(false); + _pool.buildFallback(); } }