package net.i2p.router;
import java.util.concurrent.atomic.AtomicInteger;
import net.i2p.data.Hash;
/**
* Minor extention of the router throttle to handle some DoS events and
* throttle accordingly.
*
* @deprecated unused
*/
@Deprecated
class RouterDoSThrottle extends RouterThrottleImpl {
public RouterDoSThrottle(RouterContext context) {
super(context);
context.statManager().createRateStat("router.throttleNetDbDoS", "How many netDb lookup messages have we received so far during a period with a DoS detected", "Throttle", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
}
private volatile long _currentLookupPeriod;
private final AtomicInteger _currentLookupCount = new AtomicInteger();
// if we receive over 20 netDb lookups in 10 seconds, someone is acting up
private static final long LOOKUP_THROTTLE_PERIOD = 10*1000;
private static final long LOOKUP_THROTTLE_MAX = 20;
@Override
public boolean acceptNetDbLookupRequest(Hash key) {
// if we were going to refuse it anyway, drop it
boolean shouldAccept = super.acceptNetDbLookupRequest(key);
if (!shouldAccept) return false;
// now lets check for DoS
long now = _context.clock().now();
if (_currentLookupPeriod + LOOKUP_THROTTLE_PERIOD > now) {
// same period, check for DoS
int cnt = _currentLookupCount.incrementAndGet();
if (cnt >= LOOKUP_THROTTLE_MAX) {
_context.statManager().addRateData("router.throttleNetDbDoS", cnt);
int rand = _context.random().nextInt(cnt);
if (rand > LOOKUP_THROTTLE_MAX) {
return false;
} else {
return true;
}
} else {
// no DoS, at least, not yet
return true;
}
} else {
// on to the next period, reset counter, no DoS
// (no, I'm not worried about concurrency here)
_currentLookupPeriod = now;
_currentLookupCount.set(1);
return true;
}
}
}