diff options
author | Yorhel <git@yorhel.nl> | 2010-12-05 11:12:53 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2010-12-05 11:12:53 +0100 |
commit | 70d7a53944cdbad062323be453d2061e6e8d84b7 (patch) | |
tree | 89b48e2b1f2e2eb8a6d80930e15287657ea20fd3 /lib/Multi/API.pm | |
parent | fe8256c5a45e053c96c88d6518b13e9003e2a058 (diff) |
API: Throttle the commands and sqltime per IP instead of per user
Makes more sense, anyway.
Diffstat (limited to 'lib/Multi/API.pm')
-rw-r--r-- | lib/Multi/API.pm | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/lib/Multi/API.pm b/lib/Multi/API.pm index 7c9a7d49..72751478 100644 --- a/lib/Multi/API.pm +++ b/lib/Multi/API.pm @@ -29,8 +29,8 @@ sub TRUE () { JSON::XS::true } sub FALSE () { JSON::XS::false } -# Global throttle hash, key = username, value = [ cmd_time, sql_time ] -# TODO: clean up items in this hash when username isn't connected anymore and throttle times < current time +# Global throttle hash, key = ip, value = [ cmd_time, sql_time ] +# TODO: clean up items in this hash when ip isn't connected anymore and throttle times < current time my %throttle; @@ -277,12 +277,17 @@ sub client_connect { ErrorEvent => 'client_error', InputEvent => 'client_input', ); + + # link this connection to the entry in %throttle (create if not exists) + $throttle{$ip} = [ time, time ] if !$throttle{$ip}; + $_[HEAP]{c}{ $w->ID() } = { wheel => $w, ip => $ip, connected => time, cmds => 0, cmd_err => 0, + throttle => $throttle{$ip}, # username, client, clientver are added after logging in }; $_[KERNEL]->yield(log => $_[HEAP]{c}{ $w->ID() }, 'Connected'); @@ -312,11 +317,7 @@ sub client_input { # parse error? return cerr $c, $arg->[0]{id}, $arg->[0]{msg} if !defined $cmd; - # handle login command - return $_[KERNEL]->yield(login => $c, $arg) if $cmd eq 'login'; - return cerr $c, needlogin => 'Not logged in.' if !$c->{username}; - - # update throttle array of the current user + # make sure the throttle values for this connection are at least the current time my $time = time; $_ < $time && ($_ = $time) for @{$c->{throttle}}; @@ -333,6 +334,10 @@ sub client_input { # update commands/second throttle $c->{throttle}[0] += $_[HEAP]{throttle_cmd}[0]; + # handle login command + return $_[KERNEL]->yield(login => $c, $arg) if $cmd eq 'login'; + return cerr $c, needlogin => 'Not logged in.' if !$c->{username}; + # handle get command if($cmd eq 'get') { return cerr $c, parse => 'Invalid arguments to get command' if @$arg < 3 || @$arg > 4 @@ -399,10 +404,6 @@ sub login_res { # num, res, [ c, arg ] my $encrypted = sha256_hex($VNDB::S{global_salt}.encode_utf8($arg->{password}).encode_utf8($res->[0]{salt})); return cerr $c, auth => "Wrong password for user '$arg->{username}'" if lc($encrypted) ne lc($res->[0]{passwd}); - # link this connection to the users' throttle array (create this if necessary) - $throttle{$arg->{username}} = [ time, time ] if !$throttle{$arg->{username}}; - $c->{throttle} = $throttle{$arg->{username}}; - $c->{username} = $arg->{username}; $c->{client} = $arg->{client}; $c->{clientver} = $arg->{clientver}; |