package net.i2p.router.transport.udp;
import net.i2p.util.ObjectCounter;
import net.i2p.util.SimpleTimer;
import net.i2p.util.SimpleTimer2;
import net.i2p.util.SipHash;
/**
* Count IPs
*
* @since 0.9.3
*/
class IPThrottler {
private ObjectCounter<Integer> _counter;
private final int _max;
public IPThrottler(int max, long time) {
_max = max;
_counter = new ObjectCounter<Integer>();
SimpleTimer2.getInstance().addPeriodicEvent(new Cleaner(), time);
}
/**
* Increments before checking
*/
public boolean shouldThrottle(byte[] ip) {
// for IPv4 we simply use the IP;
// for IPv6 we use a secure hash as an attacker could select the lower bytes
Integer key;
if (ip.length == 4)
key = toInt(ip);
else
key = Integer.valueOf(SipHash.hashCode(ip));
return _counter.increment(key) > _max;
}
private static Integer toInt(byte ip[]) {
int rv = 0;
for (int i = 0; i < 4; i++)
rv |= (ip[i] & 0xff) << ((3-i)*8);
return Integer.valueOf(rv);
}
private class Cleaner implements SimpleTimer.TimedEvent {
public void timeReached() {
_counter.clear();
}
}
}