diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index 0aa29de28e..3b69e9b090 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -44,6 +44,12 @@ public class CommSystemFacadeImpl extends CommSystemFacade { private final GeoIP _geoIP; private volatile boolean _netMonitorStatus; private boolean _wasStarted; + + /** + * Disable connections for testing + * @since IPv6 + */ + private static final String PROP_DISABLED = "i2np.disable"; public CommSystemFacadeImpl(RouterContext context) { _context = context; @@ -124,23 +130,17 @@ public class CommSystemFacadeImpl extends CommSystemFacade { return sum * 1000 / frameSize; } - public List getBids(OutNetMessage msg) { - return _manager.getBids(msg); - } - public TransportBid getBid(OutNetMessage msg) { - return _manager.getBid(msg); - } - public TransportBid getNextBid(OutNetMessage msg) { - return _manager.getNextBid(msg); - } - int getTransportCount() { return _manager.getTransportCount(); } - /** Send the message out */ public void processMessage(OutNetMessage msg) { + if (isDummy()) { + // testing + GetBidsJob.fail(_context, msg); + return; + } //GetBidsJob j = new GetBidsJob(_context, this, msg); //j.runJob(); //long before = _context.clock().now(); - GetBidsJob.getBids(_context, this, msg); + GetBidsJob.getBids(_context, _manager, msg); // < 0.4 ms //_context.statManager().addRateData("transport.getBidsJobTime", _context.clock().now() - before); } @@ -569,9 +569,14 @@ public class CommSystemFacadeImpl extends CommSystemFacade { return buf.toString(); } - /** @since 0.8.13 */ + /** + * Is everything disabled for testing? + * @since 0.8.13 + */ @Override - public boolean isDummy() { return false; } + public boolean isDummy() { + return _context.getBooleanProperty(PROP_DISABLED); + } /** * Translate diff --git a/router/java/src/net/i2p/router/transport/GetBidsJob.java b/router/java/src/net/i2p/router/transport/GetBidsJob.java index 85da18c13f..676f72e163 100644 --- a/router/java/src/net/i2p/router/transport/GetBidsJob.java +++ b/router/java/src/net/i2p/router/transport/GetBidsJob.java @@ -23,22 +23,25 @@ import net.i2p.util.Log; */ class GetBidsJob extends JobImpl { private final Log _log; - private final CommSystemFacadeImpl _facade; + private final TransportManager _tmgr; private final OutNetMessage _msg; - public GetBidsJob(RouterContext ctx, CommSystemFacadeImpl facade, OutNetMessage msg) { + /** + * @deprecated unused, see static getBids() + */ + public GetBidsJob(RouterContext ctx, TransportManager tmgr, OutNetMessage msg) { super(ctx); _log = ctx.logManager().getLog(GetBidsJob.class); - _facade = facade; + _tmgr = tmgr; _msg = msg; } public String getName() { return "Fetch bids for a message to be delivered"; } public void runJob() { - getBids(getContext(), _facade, _msg); + getBids(getContext(), _tmgr, _msg); } - static void getBids(RouterContext context, CommSystemFacadeImpl facade, OutNetMessage msg) { + static void getBids(RouterContext context, TransportManager tmgr, OutNetMessage msg) { Log log = context.logManager().getLog(GetBidsJob.class); Hash to = msg.getTarget().getIdentity().getHash(); msg.timestamp("bid"); @@ -61,14 +64,14 @@ class GetBidsJob extends JobImpl { return; } - TransportBid bid = facade.getNextBid(msg); + TransportBid bid = tmgr.getNextBid(msg); if (bid == null) { int failedCount = msg.getFailedTransports().size(); if (failedCount == 0) { context.statManager().addRateData("transport.bidFailNoTransports", msg.getLifetime()); // This used to be "no common transports" but it is almost always no transports at all context.banlist().banlistRouter(to, _x("No transports (hidden or starting up?)")); - } else if (failedCount >= facade.getTransportCount()) { + } else if (failedCount >= tmgr.getTransportCount()) { context.statManager().addRateData("transport.bidFailAllTransports", msg.getLifetime()); // fail after all transports were unsuccessful context.netDb().fail(to); @@ -82,7 +85,7 @@ class GetBidsJob extends JobImpl { } - private static void fail(RouterContext context, OutNetMessage msg) { + static void fail(RouterContext context, OutNetMessage msg) { if (msg.getOnFailedSendJob() != null) { context.jobQueue().addJob(msg.getOnFailedSendJob()); } diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index eafaad165e..f56a04da50 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -123,6 +123,9 @@ public abstract class TransportImpl implements Transport { /** Per-transport connection limit */ public int getMaxConnections() { + if (_context.commSystem().isDummy()) + // testing + return 0; String style = getStyle(); // object churn String maxProp; diff --git a/router/java/src/net/i2p/router/transport/udp/IPThrottler.java b/router/java/src/net/i2p/router/transport/udp/IPThrottler.java index 5f94620621..1308c2e707 100644 --- a/router/java/src/net/i2p/router/transport/udp/IPThrottler.java +++ b/router/java/src/net/i2p/router/transport/udp/IPThrottler.java @@ -3,6 +3,7 @@ package net.i2p.router.transport.udp; import net.i2p.util.ObjectCounter; import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; +import net.i2p.util.SipHash; /** * Count IPs @@ -21,12 +22,16 @@ class IPThrottler { /** * Increments before checking - * @return true if ip.length != 4 */ public boolean shouldThrottle(byte[] ip) { - if (ip.length != 4) - return true; - return _counter.increment(toInt(ip)) > _max; + // for IPv4 we simply use the IP; + // for IPv6 we use a secure hash as an attacker could select the lower bytes + Integer key; + if (ip.length == 4) + key = toInt(ip); + else + key = Integer.valueOf(SipHash.hashCode(ip)); + return _counter.increment(key) > _max; } private static Integer toInt(byte ip[]) { diff --git a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java index 1807af3088..468c780ec7 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java @@ -253,7 +253,10 @@ class UDPReceiver { // DatagramSocket javadocs: If the message is longer than the packet's length, the message is truncated. throw new IOException("packet too large! truncated and dropped from: " + packet.getRemoteHost()); } - if (size > 0) { + if (_context.commSystem().isDummy()) { + // testing + packet.release(); + } else if (size > 0) { //FIFOBandwidthLimiter.Request req = _context.bandwidthLimiter().requestInbound(size, "UDP receiver"); //_context.bandwidthLimiter().requestInbound(req, size, "UDP receiver"); FIFOBandwidthLimiter.Request req = diff --git a/router/java/src/net/i2p/router/transport/udp/UDPSender.java b/router/java/src/net/i2p/router/transport/udp/UDPSender.java index 923dcba617..40d16253c9 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPSender.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPSender.java @@ -179,6 +179,12 @@ class UDPSender { _log.error("Dropping large UDP packet " + psz + " bytes: " + packet); return; } + if (_context.commSystem().isDummy()) { + // testing + // back to the cache + packet.release(); + return; + } try { _outboundQueue.put(packet); } catch (InterruptedException ie) {