summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2015-07-20 05:25:11 +0200
committerYorhel <git@yorhel.nl>2015-07-20 05:25:11 +0200
commitc720511e81fe093175926e9ba06cb857a763b4a3 (patch)
tree98e2b0d2a37493306618d007b5d5d1cd23702bbd
parentc1bc3e9da4a48d3354c46cc39e833b185a69377e (diff)
Multi::API: Throttle "throttled" error replies
This is to save system resources when a misbehaving client keeps sending commands while it's being throttled. It also protects against trivial DoS attacks.
-rw-r--r--lib/Multi/API.pm16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/Multi/API.pm b/lib/Multi/API.pm
index 36b4be5c..2385e11d 100644
--- a/lib/Multi/API.pm
+++ b/lib/Multi/API.pm
@@ -30,7 +30,8 @@ my %O = (
max_results_lists => 100, # For get votelist/vnlist/wishlist
default_results => 10,
throttle_cmd => [ 6, 100 ], # interval between each command, allowed burst
- throttle_sql => [ 60, 1 ], # sql time multiplier, allowed burst (in sql time)
+ throttle_sql => [ 60, 1 ], # sql time multiplier, allowed burst (in sql time)
+ throttle_thr => [ 2, 10 ], # interval between "throttled" replies, allowed burst
);
@@ -164,10 +165,19 @@ sub cmd_read {
# check for thottle rule violation
for ('cmd', 'sql') {
my $left = throttle $O{"throttle_$_"}, "api_${_}_$c->{cid}", 0;
+ next if !$left;
+
+ # Too many throttle rule violations? Misbehaving client, disconnect.
+ if(throttle $O{throttle_thr}, "api_thr_$c->{cid}") {
+ writelog $c, 'Too many throttled replies, disconnecting.';
+ $c->{h}->destroy;
+ delete $C{$c->{id}};
+ return;
+ }
+
return cerr $c, throttled => 'Throttle limit reached.', type => $_,
minwait => int(10*($left))/10+1,
- fullwait => int(10*($left + $O{"throttle_$_"}[0] * $O{"throttle_$_"}[1]))/10+1
- if $left;
+ fullwait => int(10*($left + $O{"throttle_$_"}[0] * $O{"throttle_$_"}[1]))/10+1;
}
# update commands/second throttle