diff --git a/router/java/src/net/i2p/data/i2np/DatabaseLookupMessage.java b/router/java/src/net/i2p/data/i2np/DatabaseLookupMessage.java index ef133abb0..feac9d75f 100644 --- a/router/java/src/net/i2p/data/i2np/DatabaseLookupMessage.java +++ b/router/java/src/net/i2p/data/i2np/DatabaseLookupMessage.java @@ -36,11 +36,11 @@ public class DatabaseLookupMessage extends I2NPMessageImpl { private TunnelId _replyTunnel; private Set _dontIncludePeers; - private static volatile long _currentLookupPeriod; - private static volatile int _currentLookupCount; + private static volatile long _currentLookupPeriod = 0; + private static volatile int _currentLookupCount = 0; // if we try to send over 20 netDb lookups in 10 seconds, we're acting up private static final long LOOKUP_THROTTLE_PERIOD = 10*1000; - private static final long LOOKUP_THROTTLE_MAX = 20; + private static final long LOOKUP_THROTTLE_MAX = 50; public DatabaseLookupMessage(I2PAppContext context) { super(context); @@ -49,27 +49,37 @@ public class DatabaseLookupMessage extends I2NPMessageImpl { setDontIncludePeers(null); context.statManager().createRateStat("router.throttleNetDbDoSSend", "How many netDb lookup messages we are sending during a period with a DoS detected", "Throttle", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 }); + + // we do this in the writeMessage so we know that we have all the data + int dosCount = detectDoS(context); + if (dosCount > 0) { + _log.log(Log.CRIT, "Are we flooding the network with NetDb messages? (" + dosCount + " messages so far)", new Exception("Flood cause")); + } } - private static boolean detectDoS(I2PAppContext context) { + /** + * Return number of netDb messages in this period, if flood, else 0 + * + */ + private static int detectDoS(I2PAppContext context) { + int count = _currentLookupCount++; // now lets check for DoS long now = context.clock().now(); if (_currentLookupPeriod + LOOKUP_THROTTLE_PERIOD > now) { // same period, check for DoS - _currentLookupCount++; - if (_currentLookupCount >= LOOKUP_THROTTLE_MAX) { - context.statManager().addRateData("router.throttleNetDbDoSSend", _currentLookupCount, 0); - return true; + if (count >= LOOKUP_THROTTLE_MAX) { + context.statManager().addRateData("router.throttleNetDbDoSSend", count, 0); + return count; } else { // no DoS, at least, not yet - return false; + return 0; } } else { // on to the next period, reset counter, no DoS // (no, I'm not worried about concurrency here) _currentLookupPeriod = now; _currentLookupCount = 1; - return true; + return 0; } } @@ -139,16 +149,7 @@ public class DatabaseLookupMessage extends I2NPMessageImpl { protected byte[] writeMessage() throws I2NPMessageException, IOException { if (_key == null) throw new I2NPMessageException("Key being searched for not specified"); if (_fromHash == null) throw new I2NPMessageException("From address not specified"); - - // we do this in the writeMessage so we know that we have all the data - boolean isDoS = detectDoS(_context); - if (isDoS) { - _log.log(Log.CRIT, "Are we flooding the network with NetDb lookup messages for " - + _key.toBase64() + " (reply through " + _fromHash + " / " + _replyTunnel + ")", - new Exception("Flood cause")); - } - ByteArrayOutputStream os = new ByteArrayOutputStream(32); try { _key.writeBytes(os);