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 2b24d0909..2fd58533d 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnThrottler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnThrottler.java @@ -46,10 +46,11 @@ class ConnThrottler { * Checks both individual and total. Increments before checking. */ boolean shouldThrottle(Hash h) { + // do this first, so we don't increment total if individual throttled + if (_max > 0 && this.counter.increment(h) > _max) + return true; if (_totalMax > 0 && _currentTotal.incrementAndGet() > _totalMax) return true; - if (_max > 0) - return this.counter.increment(h) > _max; return false; } 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 61be04bca..0b4919cf3 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java @@ -395,6 +395,46 @@ class ConnectionManager { if (from == null) return "null"; Hash h = from.calculateHash(); + + // As of 0.9.9, run the blacklist checks BEFORE the port counters, + // so blacklisted dests will not increment the counters and + // possibly trigger total-counter blocks for others. + + // if the sig is absent or bad it will be caught later (in CPH) + if (_defaultOptions.isAccessListEnabled() && + !_defaultOptions.getAccessList().contains(h)) + return "not whitelisted"; + if (_defaultOptions.isBlacklistEnabled() && + _defaultOptions.getBlacklist().contains(h)) + return "blacklisted"; + String hashes = _context.getProperty(PROP_BLACKLIST, ""); + if (!_currentBlacklist.equals(hashes)) { + // rebuild _globalBlacklist when property changes + synchronized(_globalBlacklist) { + if (hashes.length() > 0) { + Set newSet = new HashSet(); + StringTokenizer tok = new StringTokenizer(hashes, ",; "); + while (tok.hasMoreTokens()) { + String hashstr = tok.nextToken(); + Hash hh = ConvertToHash.getHash(hashstr); + if (hh != null) + newSet.add(hh); + else + _log.error("Bad blacklist entry: " + hashstr); + } + _globalBlacklist.addAll(newSet); + _globalBlacklist.retainAll(newSet); + _currentBlacklist = hashes; + } else { + _globalBlacklist.clear(); + _currentBlacklist = ""; + } + } + } + if (hashes.length() > 0 && _globalBlacklist.contains(h)) + return "blacklisted globally"; + + String throttled = null; // always call all 3 to increment all counters if (_minuteThrottler != null && _minuteThrottler.shouldThrottle(h)) { @@ -439,42 +479,8 @@ class ConnectionManager { " or total limit of " + _defaultOptions.getMaxTotalConnsPerDay() + " per day"; } - if (throttled != null) - return throttled; - // if the sig is absent or bad it will be caught later (in CPH) - if (_defaultOptions.isAccessListEnabled() && - !_defaultOptions.getAccessList().contains(h)) - return "not whitelisted"; - if (_defaultOptions.isBlacklistEnabled() && - _defaultOptions.getBlacklist().contains(h)) - return "blacklisted"; - String hashes = _context.getProperty(PROP_BLACKLIST, ""); - if (!_currentBlacklist.equals(hashes)) { - // rebuild _globalBlacklist when property changes - synchronized(_globalBlacklist) { - if (hashes.length() > 0) { - Set newSet = new HashSet(); - StringTokenizer tok = new StringTokenizer(hashes, ",; "); - while (tok.hasMoreTokens()) { - String hashstr = tok.nextToken(); - Hash hh = ConvertToHash.getHash(hashstr); - if (hh != null) - newSet.add(hh); - else - _log.error("Bad blacklist entry: " + hashstr); - } - _globalBlacklist.addAll(newSet); - _globalBlacklist.retainAll(newSet); - _currentBlacklist = hashes; - } else { - _globalBlacklist.clear(); - _currentBlacklist = ""; - } - } - } - if (hashes.length() > 0 && _globalBlacklist.contains(h)) - return "blacklisted globally"; - return null; + + return throttled; } diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java index b14b4a223..e2336e19b 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java @@ -754,27 +754,27 @@ class ConnectionOptions extends I2PSocketOptionsImpl { public Set getBlacklist() { return _blackList; } private void initLists(ConnectionOptions opts) { - _accessListEnabled = opts.isAccessListEnabled(); - _blackListEnabled = opts.isBlacklistEnabled(); _accessList = opts.getAccessList(); _blackList = opts.getBlacklist(); + _accessListEnabled = opts.isAccessListEnabled(); + _blackListEnabled = opts.isBlacklistEnabled(); } private void initLists(Properties opts) { - _accessListEnabled = getBool(opts, PROP_ENABLE_ACCESS_LIST, false); - _blackListEnabled = getBool(opts, PROP_ENABLE_BLACKLIST, false); + boolean accessListEnabled = getBool(opts, PROP_ENABLE_ACCESS_LIST, false); + boolean blackListEnabled = getBool(opts, PROP_ENABLE_BLACKLIST, false); // Don't think these would ever be accessed simultaneously, // but avoid concurrent modification just in case Set accessList, blackList; - if (_accessListEnabled) + if (accessListEnabled) accessList = new HashSet(); else accessList = Collections.EMPTY_SET; - if (_blackListEnabled) + if (blackListEnabled) blackList = new HashSet(); else blackList = Collections.EMPTY_SET; - if (_accessListEnabled || _blackListEnabled) { + if (accessListEnabled || blackListEnabled) { String hashes = opts.getProperty(PROP_ACCESS_LIST); if (hashes == null) return; @@ -792,6 +792,8 @@ class ConnectionOptions extends I2PSocketOptionsImpl { } _accessList = accessList; _blackList = blackList; + _accessListEnabled = accessListEnabled; + _blackListEnabled = blackListEnabled; if (_accessListEnabled && _accessList.isEmpty()) error("Connection access list enabled but no valid entries; no peers can connect"); else if (_blackListEnabled && _blackList.isEmpty()) diff --git a/history.txt b/history.txt index 2442e4999..95fc709d2 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,14 @@ +2013-10-25 zzz + * Streaming: + - Check blacklist/whitelist before connection limits, so + a blacklisted peer does not increment the counters + - Don't increment total throttle if peer is throttled + - Fix blacklist NPE after config change (ticket #1070) + * Transports: Reduce connection idle time sooner + 2013-10-24 zzz + * i2psnark: Drop incoming connections on HTTP port + * I2PTunnel: Don't let uncaught exception kill server acceptor (ticket #1070) * I2PTunnel standard, HTTP, and IRC servers: Route connections to specific targets based on incoming I2P port with custom option targetForPort.xxxx=myserver:yyyy diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index f2522cd4e..7ca1a3ec2 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 = 9; + public final static long BUILD = 10; /** for example "-test" */ public final static String EXTRA = "";