diff --git a/history.txt b/history.txt index 44c8a9288..fba494287 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,11 @@ +2011-03-02 zzz + * BuildHandler: + - Limit request queue size + - Concurrent request queue + - Remove dead code for queued rely handling + * OutNetMessage: Remove dead code + * Tunnel cleanups, final, javadoc + * 2011-03-02 0.8.4 released 2011-02-27 zzz diff --git a/router/java/src/net/i2p/router/InNetMessagePool.java b/router/java/src/net/i2p/router/InNetMessagePool.java index 4e6846b46..d6067b2b3 100644 --- a/router/java/src/net/i2p/router/InNetMessagePool.java +++ b/router/java/src/net/i2p/router/InNetMessagePool.java @@ -81,7 +81,6 @@ public class InNetMessagePool implements Service { _shortCircuitGatewayJob = new SharedShortCircuitGatewayJob(context); } _log = _context.logManager().getLog(InNetMessagePool.class); - _alive = false; _context.statManager().createRateStat("inNetPool.dropped", "How often do we drop a message", "InNetPool", new long[] { 60*60*1000l }); _context.statManager().createRateStat("inNetPool.droppedDeliveryStatusDelay", "How long after a delivery status message is created do we receive it back again (for messages that are too slow to be handled)", "InNetPool", new long[] { 60*60*1000l }); _context.statManager().createRateStat("inNetPool.duplicate", "How often do we receive a duplicate message", "InNetPool", new long[] { 60*60*1000l }); @@ -89,12 +88,20 @@ public class InNetMessagePool implements Service { _context.statManager().createRateStat("inNetPool.droppedDbLookupResponseMessage", "How often we drop a slow-to-arrive db search response", "InNetPool", new long[] { 60*60*1000l }); } + /** + * @return previous builder for this message type, or null + * @throws AIOOBE if i2npMessageType is greater than MAX_I2NP_MESSAGE_TYPE + */ public HandlerJobBuilder registerHandlerJobBuilder(int i2npMessageType, HandlerJobBuilder builder) { HandlerJobBuilder old = _handlerJobBuilders[i2npMessageType]; _handlerJobBuilders[i2npMessageType] = builder; return old; } + /** + * @return previous builder for this message type, or null + * @throws AIOOBE if i2npMessageType is greater than MAX_I2NP_MESSAGE_TYPE + */ public HandlerJobBuilder unregisterHandlerJobBuilder(int i2npMessageType) { HandlerJobBuilder old = _handlerJobBuilders[i2npMessageType]; _handlerJobBuilders[i2npMessageType] = null; @@ -102,12 +109,14 @@ public class InNetMessagePool implements Service { } /** - * Add a new message to the pool, returning the number of messages in the - * pool so that the comm system can throttle inbound messages. If there is + * Add a new message to the pool. + * If there is * a HandlerJobBuilder for the inbound message type, the message is loaded * into a job created by that builder and queued up for processing instead * (though if the builder doesn't create a job, it is added to the pool) * + * @return -1 for some types of errors but not all; 0 otherwise + * (was queue length, long ago) */ public int add(I2NPMessage messageBody, RouterIdentity fromRouter, Hash fromRouterHash) { long exp = messageBody.getMessageExpiration(); diff --git a/router/java/src/net/i2p/router/OutNetMessage.java b/router/java/src/net/i2p/router/OutNetMessage.java index 0c430b07e..07fd8259c 100644 --- a/router/java/src/net/i2p/router/OutNetMessage.java +++ b/router/java/src/net/i2p/router/OutNetMessage.java @@ -29,8 +29,8 @@ import net.i2p.util.Log; * */ public class OutNetMessage { - private Log _log; - private RouterContext _context; + private final Log _log; + private final RouterContext _context; private RouterInfo _target; private I2NPMessage _message; /** cached message class name, for use after we discard the message */ @@ -50,7 +50,7 @@ public class OutNetMessage { private long _sendBegin; private long _transmitBegin; private Exception _createdBy; - private long _created; + private final long _created; /** for debugging, contains a mapping of even name to Long (e.g. "begin sending", "handleOutbound", etc) */ private HashMap _timestamps; /** diff --git a/router/java/src/net/i2p/router/OutNetMessagePool.java b/router/java/src/net/i2p/router/OutNetMessagePool.java index 8e057ff49..6b5ddfaab 100644 --- a/router/java/src/net/i2p/router/OutNetMessagePool.java +++ b/router/java/src/net/i2p/router/OutNetMessagePool.java @@ -18,24 +18,18 @@ import net.i2p.util.Log; * that wants to send a message, and the communication subsystem periodically * retrieves messages for delivery. * + * Actually, this doesn't 'pool' anything, it calls the comm system directly. + * Nor does it organize by priority. But perhaps it could someday. */ public class OutNetMessagePool { - private Log _log; - private RouterContext _context; + private final Log _log; + private final RouterContext _context; public OutNetMessagePool(RouterContext context) { _context = context; _log = _context.logManager().getLog(OutNetMessagePool.class); } - /** - * Remove the highest priority message, or null if none are available. - * - */ - public OutNetMessage getNext() { - return null; - } - /** * Add a new message to the pool * @@ -47,8 +41,8 @@ public class OutNetMessagePool { return; } - if (_log.shouldLog(Log.INFO)) - _log.info("Adding outbound message to " + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Adding outbound message to " + msg.getTarget().getIdentity().getHash().toBase64().substring(0,6) + " with id " + msg.getMessage().getUniqueId() + " expiring on " + msg.getMessage().getMessageExpiration() @@ -70,7 +64,7 @@ public class OutNetMessagePool { return false; } if (msg.getTarget() == null) { - _log.error("No target in the OutNetMessage: " + msg, new Exception("Definitely a fuckup")); + _log.error("No target in the OutNetMessage: " + msg, new Exception()); return false; } if (msg.getPriority() < 0) { @@ -83,38 +77,4 @@ public class OutNetMessagePool { } return true; } - - /** - * Clear any messages that have expired, enqueuing any appropriate jobs - * - */ - public void clearExpired() { - // noop - } - - /** - * Retrieve the number of messages, regardless of priority. - * - */ - public int getCount() { return 0; } - - /** - * Retrieve the number of messages at the given priority. This can be used for - * subsystems that maintain a pool of messages to be sent whenever there is spare time, - * where all of these 'spare' messages are of the same priority. - * - */ - public int getCount(int priority) { return 0; } - - public void dumpPoolInfo() { return; } - - private static class ReverseIntegerComparator implements Comparator { - public int compare(Object lhs, Object rhs) { - if ( (lhs == null) || (rhs == null) ) return 0; // invalid, but never used - if ( !(lhs instanceof Integer) || !(rhs instanceof Integer)) return 0; - Integer lv = (Integer)lhs; - Integer rv = (Integer)rhs; - return - (lv.compareTo(rv)); - } - } } diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index a411b0099..87e5bffca 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 = 0; + public final static long BUILD = 1; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index 266561cbc..81cf89340 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -459,9 +459,9 @@ public class TransportManager implements TransportEventListener { if (_log.shouldLog(Log.DEBUG)) _log.debug("I2NPMessage received: " + message.getClass().getName(), new Exception("Where did I come from again?")); try { - int num = _context.inNetMessagePool().add(message, fromRouter, fromRouterHash); + _context.inNetMessagePool().add(message, fromRouter, fromRouterHash); if (_log.shouldLog(Log.DEBUG)) - _log.debug("Added to in pool: "+ num); + _log.debug("Added to in pool"); } catch (IllegalArgumentException iae) { if (_log.shouldLog(Log.WARN)) _log.warn("Error receiving message", iae); 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 0ccb53fbd..6d1099410 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java @@ -22,9 +22,9 @@ import net.i2p.util.Log; import net.i2p.util.VersionComparator; /** - * + * Methods for creating Tunnel Build Messages, i.e. requests */ -class BuildRequestor { +abstract class BuildRequestor { private static final List ORDER = new ArrayList(TunnelBuildMessage.MAX_RECORD_COUNT); static { for (int i = 0; i < TunnelBuildMessage.MAX_RECORD_COUNT; i++) @@ -37,7 +37,7 @@ class BuildRequestor { * expl. vs. client, uptime, and network conditions. * Put the expiration in the PTCC. * - * Also, perhaps, save the PTCC even after expiration for an extended time, + * Also, we now save the PTCC even after expiration for an extended time, * so can we use a successfully built tunnel anyway. * */ @@ -49,12 +49,16 @@ class BuildRequestor { /** some randomization is added on to this */ private static final int BUILD_MSG_TIMEOUT = 60*1000; + /** + * "paired tunnels" means using a client's own inbound tunnel to receive the + * reply for an outbound build request, and using a client's own outbound tunnel + * to send an inbound build request. + * This is more secure than using the router's exploratory tunnels, as it + * makes correlation of multiple clients more difficult. + */ private static boolean usePairedTunnels(RouterContext ctx) { - String val = ctx.getProperty("router.usePairedTunnels"); - if ( (val == null) || (Boolean.valueOf(val).booleanValue()) ) - return true; - else - return false; + return true; + //return ctx.getBooleanPropertyDefaultTrue("router.usePairedTunnels"); } /** new style requests need to fill in the tunnel IDs before hand */ @@ -321,9 +325,9 @@ class BuildRequestor { * 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; + final TunnelPool _pool; + final PooledTunnelCreatorConfig _cfg; + final BuildExecutor _exec; private TunnelBuildFirstHopFailJob(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, BuildExecutor exec) { super(ctx); _cfg = cfg; 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 e2271ec90..e82c4a8b0 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/ExpireJob.java +++ b/router/java/src/net/i2p/router/tunnel/pool/ExpireJob.java @@ -5,16 +5,21 @@ import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.router.tunnel.TunnelCreatorConfig; +/** + * This runs twice for each tunnel. + * The first time, remove it from the LeaseSet. + * The second time, stop accepting data for it. + */ class ExpireJob extends JobImpl { - private TunnelPool _pool; - private TunnelCreatorConfig _cfg; + private final TunnelPool _pool; + private final TunnelCreatorConfig _cfg; private boolean _leaseUpdated; - private long _dropAfter; + private final long _dropAfter; + public ExpireJob(RouterContext ctx, TunnelCreatorConfig cfg, TunnelPool pool) { super(ctx); _pool = pool; _cfg = cfg; - _leaseUpdated = false; // we act as if this tunnel expires a random skew before it actually does // so we rebuild out of sync. otoh, we will honor tunnel messages on it // up through the full lifetime of the tunnel, plus a clock skew, since @@ -28,9 +33,11 @@ class ExpireJob extends JobImpl { cfg.setExpiration(expire); getTiming().setStartAfter(expire); } + public String getName() { return "Expire tunnel"; } + public void runJob() { if (!_leaseUpdated) { _pool.removeTunnel(_cfg); 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 7c64df958..e63e681b3 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TestJob.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TestJob.java @@ -22,9 +22,9 @@ import net.i2p.router.message.PayloadGarlicConfig; import net.i2p.util.Log; class TestJob extends JobImpl { - private Log _log; - private TunnelPool _pool; - private PooledTunnelCreatorConfig _cfg; + private final Log _log; + private final TunnelPool _pool; + private final PooledTunnelCreatorConfig _cfg; private boolean _found; private TunnelInfo _outTunnel; private TunnelInfo _replyTunnel; @@ -39,9 +39,10 @@ class TestJob extends JobImpl { public TestJob(RouterContext ctx, PooledTunnelCreatorConfig cfg, TunnelPool pool) { super(ctx); _log = ctx.logManager().getLog(TestJob.class); - _pool = pool; _cfg = cfg; - if (_pool == null) + if (pool != null) + _pool = pool; + else _pool = cfg.getTunnelPool(); if ( (_pool == null) && (_log.shouldLog(Log.ERROR)) ) _log.error("Invalid tunnel test configuration: no pool for " + cfg, new Exception("origin")); @@ -61,7 +62,9 @@ class TestJob extends JobImpl { ctx.statManager().createRateStat("tunnel.testAborted", "Tunnel test could not occur, since there weren't any tunnels to test with", "Tunnels", RATES); } + public String getName() { return "Test tunnel"; } + public void runJob() { if (_pool == null) return; @@ -246,9 +249,10 @@ class TestJob extends JobImpl { } private class ReplySelector implements MessageSelector { - private RouterContext _context; - private long _id; - private long _expiration; + private final RouterContext _context; + private final long _id; + private final long _expiration; + public ReplySelector(RouterContext ctx, long id, long expiration) { _context = ctx; _id = id; @@ -257,7 +261,9 @@ class TestJob extends JobImpl { } public boolean continueMatching() { return !_found && _context.clock().now() < _expiration; } + public long getExpiration() { return _expiration; } + public boolean isMatch(I2NPMessage message) { if (message instanceof DeliveryStatusMessage) { return ((DeliveryStatusMessage)message).getMessageId() == _id; @@ -280,9 +286,13 @@ class TestJob extends JobImpl { private class OnTestReply extends JobImpl implements ReplyJob { private long _successTime; private OutNetMessage _sentMessage; + public OnTestReply(RouterContext ctx) { super(ctx); } + public String getName() { return "Tunnel test success"; } + public void setSentMessage(OutNetMessage m) { _sentMessage = m; } + public void runJob() { if (_sentMessage != null) getContext().messageRegistry().unregisterPending(_sentMessage); @@ -292,6 +302,7 @@ class TestJob extends JobImpl { testFailed(_successTime); _found = true; } + // who cares about the details... public void setMessage(I2NPMessage message) { _successTime = getContext().clock().now() - ((DeliveryStatusMessage)message).getArrival(); @@ -310,12 +321,15 @@ class TestJob extends JobImpl { * Test failed (boo, hiss) */ private class OnTestTimeout extends JobImpl { - private long _started; + private final long _started; + public OnTestTimeout(RouterContext ctx) { super(ctx); _started = ctx.clock().now(); } + public String getName() { return "Tunnel test timeout"; } + public void runJob() { if (_log.shouldLog(Log.WARN)) _log.warn("Timeout: found? " + _found); 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 03fa5bd71..c432bfe9e 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java @@ -22,21 +22,21 @@ import net.i2p.stat.RateStat; import net.i2p.util.Log; /** - * + * A group of tunnels for the router or a particular client, in a single direction. */ public class TunnelPool { private final List _inProgress = new ArrayList(); - private RouterContext _context; - private Log _log; + private final RouterContext _context; + private final Log _log; private TunnelPoolSettings _settings; private final ArrayList _tunnels; - private TunnelPeerSelector _peerSelector; - private TunnelPoolManager _manager; + private final TunnelPeerSelector _peerSelector; + private final TunnelPoolManager _manager; private boolean _alive; private long _lifetimeProcessed; private TunnelInfo _lastSelected; private long _lastSelectionPeriod; - private int _expireSkew; + private final int _expireSkew; private long _started; private long _lastRateUpdate; private long _lastLifetimeProcessed; @@ -50,14 +50,9 @@ public class TunnelPool { _settings = settings; _tunnels = new ArrayList(settings.getLength() + settings.getBackupQuantity()); _peerSelector = sel; - _alive = false; - _lastSelectionPeriod = 0; - _lastSelected = null; - _lifetimeProcessed = 0; _expireSkew = _context.random().nextInt(90*1000); _started = System.currentTimeMillis(); _lastRateUpdate = _started; - _lastLifetimeProcessed = 0; _rateName = "tunnel.Bps." + (_settings.isExploratory() ? "exploratory" : _settings.getDestinationNickname()) + (_settings.isInbound() ? ".in" : ".out"); @@ -412,11 +407,12 @@ public class TunnelPool { } } + /** noop for outbound */ void refreshLeaseSet() { - if (_log.shouldLog(Log.DEBUG)) - _log.debug(toString() + ": refreshing leaseSet on tunnel expiration (but prior to grace timeout)"); - LeaseSet ls = null; if (_settings.isInbound() && (_settings.getDestination() != null) ) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug(toString() + ": refreshing leaseSet on tunnel expiration (but prior to grace timeout)"); + LeaseSet ls = null; synchronized (_tunnels) { ls = locked_buildNewLeaseSet(); } @@ -427,7 +423,7 @@ public class TunnelPool { } /** - * Return true if a fallback tunnel is built + * @return true if a fallback tunnel is built * */ boolean buildFallback() { @@ -851,6 +847,7 @@ public class TunnelPool { } PooledTunnelCreatorConfig configureNewTunnel() { return configureNewTunnel(false); } + private PooledTunnelCreatorConfig configureNewTunnel(boolean forceZeroHop) { TunnelPoolSettings settings = getSettings(); List peers = null; 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 3a53be552..59eec7d81 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java @@ -37,8 +37,8 @@ import net.i2p.util.SimpleTimer; * */ public class TunnelPoolManager implements TunnelManagerFacade { - private RouterContext _context; - private Log _log; + private final RouterContext _context; + private final Log _log; /** Hash (destination) to TunnelPool */ private final Map _clientInboundPools; /** Hash (destination) to TunnelPool */ @@ -61,7 +61,6 @@ public class TunnelPoolManager implements TunnelManagerFacade { _clientInboundPools = new ConcurrentHashMap(4); _clientOutboundPools = new ConcurrentHashMap(4); - _isShutdown = false; _executor = new BuildExecutor(ctx, this); I2PThread execThread = new I2PThread(_executor, "BuildExecutor"); execThread.setDaemon(true);