SSU2: Fix peer test throttling

Only throttle messages 1 and 2
Send limit response on throttle
Throttle IPv6 based on first 8 bytes only
This commit is contained in:
zzz
2022-07-05 07:37:51 -04:00
parent ec3a88dc34
commit 9a9722dd3e
2 changed files with 22 additions and 15 deletions

View File

@@ -25,12 +25,12 @@ class IPThrottler {
*/
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
// for IPv6 we use a hash of the first 8 bytes
Integer key;
if (ip.length == 4)
key = toInt(ip);
else
key = Integer.valueOf(SipHash.hashCode(ip));
key = hashCode(ip);
return _counter.increment(key) > _max;
}
@@ -41,6 +41,15 @@ class IPThrottler {
return Integer.valueOf(rv);
}
/** @since 0.9.55 */
private static Integer hashCode(byte ip[]) {
int rv = 0;
for (int i = 0; i < 8; i++) {
rv ^= ip[i] << (i * 4);
}
return Integer.valueOf(rv);
}
private class Cleaner implements SimpleTimer.TimedEvent {
public void timeReached() {
_counter.clear();

View File

@@ -984,22 +984,9 @@ class PeerTestManager {
return;
}
}
if (_throttle.shouldThrottle(fromIP)) {
if (_log.shouldLog(Log.WARN))
_log.warn("PeerTest throttle from " + Addresses.toString(fromIP, fromPort));
return;
}
// common checks
// use the same counter for both from and to IPs
if (_throttle.shouldThrottle(testIP)) {
if (_log.shouldLog(Log.WARN))
_log.warn("PeerTest throttle to " + Addresses.toString(testIP, testPort));
return;
}
if (msg >= 1 && msg <= 4) {
if (fromPeer == null) {
if (_log.shouldWarn())
@@ -1070,6 +1057,14 @@ class PeerTestManager {
_transport.send(packet);
return;
}
if (_throttle.shouldThrottle(fromIP)) {
if (_log.shouldLog(Log.WARN))
_log.warn("PeerTest throttle from " + Addresses.toString(fromIP, fromPort));
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_LIMIT,
Hash.FAKE_HASH, data, fromPeer);
_transport.send(packet);
return;
}
Hash alice = fromPeer.getRemotePeer();
RouterInfo aliceRI = _context.netDb().lookupRouterInfoLocally(alice);
if (aliceRI == null) {
@@ -1157,6 +1152,9 @@ class PeerTestManager {
!_transport.isValid(testIP) ||
_transport.isTooClose(testIP)) {
rcode = SSU2Util.TEST_REJECT_CHARLIE_ADDRESS;
} else if (_throttle.shouldThrottle(fromIP) ||
_throttle.shouldThrottle(testIP)) {
rcode = SSU2Util.TEST_REJECT_CHARLIE_LIMIT;
} else {
// bob should have sent it to us. Don't bother to lookup
// remotely if he didn't, or it was out-of-order or lost.