diff options
author | Yorhel <git@yorhel.nl> | 2015-07-20 05:25:11 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2015-07-20 05:25:11 +0200 |
commit | c720511e81fe093175926e9ba06cb857a763b4a3 (patch) | |
tree | 98e2b0d2a37493306618d007b5d5d1cd23702bbd | |
parent | c1bc3e9da4a48d3354c46cc39e833b185a69377e (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.pm | 16 |
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 |