From 8633ef9513da87e4457e6374cd16895723dddb26 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Wed, 12 Sep 2012 21:52:12 +0000 Subject: [PATCH] * Streaming: Don't send a RST to an hour/day limited peer, or blacklisted, or non-whitelisted, to not waste outbound bandwidth --- .../i2p/client/streaming/ConnThrottler.java | 14 ++++++++++++- .../client/streaming/ConnectionManager.java | 21 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnThrottler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnThrottler.java index baa3d52e39..69f0bb8571 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnThrottler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnThrottler.java @@ -38,7 +38,9 @@ class ConnThrottler { SimpleScheduler.getInstance().addPeriodicEvent(new Cleaner(), period); } - /** increments before checking */ + /** + * Checks both individual and total. Increments before checking. + */ boolean shouldThrottle(Hash h) { if (_totalMax > 0 && _currentTotal.incrementAndGet() > _totalMax) return true; @@ -47,6 +49,16 @@ class ConnThrottler { return false; } + /** + * Checks individual count only. Does not increment. + * @since 0.9.3 + */ + boolean isThrottled(Hash h) { + if (_max > 0) + return this.counter.count(h) > _max; + return false; + } + private class Cleaner implements SimpleTimer.TimedEvent { public void timeReached() { if (_totalMax > 0) diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java index 885b72cdc9..3547b55440 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java @@ -202,7 +202,26 @@ class ConnectionManager { _context.statManager().addRateData("stream.receiveActive", active, total); if (reject) { - PacketLocal reply = new PacketLocal(_context, synPacket.getOptionalFrom()); + Destination from = synPacket.getOptionalFrom(); + if (from == null) + return null; + if (_dayThrottler != null || _hourThrottler != null) { + Hash h = from.calculateHash(); + if ((_hourThrottler != null && _hourThrottler.isThrottled(h)) || + (_dayThrottler != null && _dayThrottler.isThrottled(h)) || + (_defaultOptions.isAccessListEnabled() && !_defaultOptions.getAccessList().contains(h)) || + (_defaultOptions.isBlacklistEnabled() && _defaultOptions.getBlacklist().contains(h))) { + // A signed RST packet + ElGamal + session tags is fairly expensive, so + // once the hour/day limit is hit for a particular peer, don't even send it. + // Ditto for blacklist / whitelist + // This is a tradeoff, because it will keep retransmitting the SYN for a while, + // thus more inbound, but let's not spend several KB on the outbound. + if (_log.shouldLog(Log.INFO)) + _log.info("Dropping RST to " + h); + return null; + } + } + PacketLocal reply = new PacketLocal(_context, from); reply.setFlag(Packet.FLAG_RESET); reply.setFlag(Packet.FLAG_SIGNATURE_INCLUDED); reply.setAckThrough(synPacket.getSequenceNum()); -- GitLab