From c720511e81fe093175926e9ba06cb857a763b4a3 Mon Sep 17 00:00:00 2001 From: Yorhel Date: Mon, 20 Jul 2015 05:25:11 +0200 Subject: 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. --- lib/Multi/API.pm | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'lib/Multi') 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 -- cgit v1.2.3