forked from I2P_Developers/i2p.i2p
* 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:
@@ -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);
|
||||||
|
Reference in New Issue
Block a user