* do DoS detection in constructor, so we get useful "why are we doing this"

stack traces (rather than "oh, we're doing it when... uh... writing to the socket")
* increase the throttle max, since we want to be able to send a few concurrent
This commit is contained in:
jrandom
2004-08-13 02:11:54 +00:00
committed by zzz
parent dfac7bde9c
commit 25eda1378e

View File

@@ -36,11 +36,11 @@ public class DatabaseLookupMessage extends I2NPMessageImpl {
private TunnelId _replyTunnel; private TunnelId _replyTunnel;
private Set _dontIncludePeers; private Set _dontIncludePeers;
private static volatile long _currentLookupPeriod; private static volatile long _currentLookupPeriod = 0;
private static volatile int _currentLookupCount; private static volatile int _currentLookupCount = 0;
// if we try to send over 20 netDb lookups in 10 seconds, we're acting up // 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_PERIOD = 10*1000;
private static final long LOOKUP_THROTTLE_MAX = 20; private static final long LOOKUP_THROTTLE_MAX = 50;
public DatabaseLookupMessage(I2PAppContext context) { public DatabaseLookupMessage(I2PAppContext context) {
super(context); super(context);
@@ -49,27 +49,37 @@ public class DatabaseLookupMessage extends I2NPMessageImpl {
setDontIncludePeers(null); 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 }); 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 // now lets check for DoS
long now = context.clock().now(); long now = context.clock().now();
if (_currentLookupPeriod + LOOKUP_THROTTLE_PERIOD > now) { if (_currentLookupPeriod + LOOKUP_THROTTLE_PERIOD > now) {
// same period, check for DoS // same period, check for DoS
_currentLookupCount++; if (count >= LOOKUP_THROTTLE_MAX) {
if (_currentLookupCount >= LOOKUP_THROTTLE_MAX) { context.statManager().addRateData("router.throttleNetDbDoSSend", count, 0);
context.statManager().addRateData("router.throttleNetDbDoSSend", _currentLookupCount, 0); return count;
return true;
} else { } else {
// no DoS, at least, not yet // no DoS, at least, not yet
return false; return 0;
} }
} else { } else {
// on to the next period, reset counter, no DoS // on to the next period, reset counter, no DoS
// (no, I'm not worried about concurrency here) // (no, I'm not worried about concurrency here)
_currentLookupPeriod = now; _currentLookupPeriod = now;
_currentLookupCount = 1; _currentLookupCount = 1;
return true; return 0;
} }
} }
@@ -139,16 +149,7 @@ public class DatabaseLookupMessage extends I2NPMessageImpl {
protected byte[] writeMessage() throws I2NPMessageException, IOException { protected byte[] writeMessage() throws I2NPMessageException, IOException {
if (_key == null) throw new I2NPMessageException("Key being searched for not specified"); if (_key == null) throw new I2NPMessageException("Key being searched for not specified");
if (_fromHash == null) throw new I2NPMessageException("From address 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); ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try { try {
_key.writeBytes(os); _key.writeBytes(os);