* Streaming: Don't send a RST to an hour/day limited peer,

or blacklisted, or non-whitelisted, to not waste outbound bandwidth
This commit is contained in:
zzz
2012-09-12 21:52:12 +00:00
parent 4666454482
commit 8633ef9513
2 changed files with 33 additions and 2 deletions

View File

@@ -38,7 +38,9 @@ class ConnThrottler {
SimpleScheduler.getInstance().addPeriodicEvent(new Cleaner(), period);
}
/** increments before checking */
/**
* Checks both individual and total. Increments before checking.
*/
boolean shouldThrottle(Hash h) {
if (_totalMax > 0 && _currentTotal.incrementAndGet() > _totalMax)
return true;
@@ -47,6 +49,16 @@ class ConnThrottler {
return false;
}
/**
* Checks individual count only. Does not increment.
* @since 0.9.3
*/
boolean isThrottled(Hash h) {
if (_max > 0)
return this.counter.count(h) > _max;
return false;
}
private class Cleaner implements SimpleTimer.TimedEvent {
public void timeReached() {
if (_totalMax > 0)

View File

@@ -202,7 +202,26 @@ class ConnectionManager {
_context.statManager().addRateData("stream.receiveActive", active, total);
if (reject) {
PacketLocal reply = new PacketLocal(_context, synPacket.getOptionalFrom());
Destination from = synPacket.getOptionalFrom();
if (from == null)
return null;
if (_dayThrottler != null || _hourThrottler != null) {
Hash h = from.calculateHash();
if ((_hourThrottler != null && _hourThrottler.isThrottled(h)) ||
(_dayThrottler != null && _dayThrottler.isThrottled(h)) ||
(_defaultOptions.isAccessListEnabled() && !_defaultOptions.getAccessList().contains(h)) ||
(_defaultOptions.isBlacklistEnabled() && _defaultOptions.getBlacklist().contains(h))) {
// A signed RST packet + ElGamal + session tags is fairly expensive, so
// once the hour/day limit is hit for a particular peer, don't even send it.
// Ditto for blacklist / whitelist
// This is a tradeoff, because it will keep retransmitting the SYN for a while,
// thus more inbound, but let's not spend several KB on the outbound.
if (_log.shouldLog(Log.INFO))
_log.info("Dropping RST to " + h);
return null;
}
}
PacketLocal reply = new PacketLocal(_context, from);
reply.setFlag(Packet.FLAG_RESET);
reply.setFlag(Packet.FLAG_SIGNATURE_INCLUDED);
reply.setAckThrough(synPacket.getSequenceNum());