Minor cleanup to command throttling code:

* Deduce allow_read from the client's state (IsFloodDone) rather than
   storing it in LocalUser.
 * Fix the documentation (in oper /info), however strange
   client_flood_burst_rate and client_flood_burst_max may seem, that is
   how they currently work.
This commit is contained in:
Jilles Tjoelker 2011-10-04 00:46:00 +02:00
parent f9dda63969
commit d182b85454
6 changed files with 17 additions and 50 deletions

View file

@ -252,7 +252,7 @@ struct LocalUser
* to avoid flooding. * to avoid flooding.
* -- adrian * -- adrian
*/ */
int allow_read; /* how many we're allowed to read in this second */ int dummy1;
int dummy0; int dummy0;
int sent_parsed; /* how many messages we've parsed in this second */ int sent_parsed; /* how many messages we've parsed in this second */
time_t last_knock; /* time of last knock */ time_t last_knock; /* time of last knock */

View file

@ -27,29 +27,6 @@
#ifndef INCLUDED_packet_h #ifndef INCLUDED_packet_h
#define INCLUDED_packet_h #define INCLUDED_packet_h
/*
* this hides in here rather than a config.h because it really shouldn't
* be tweaked unless you *REALLY REALLY* know what you're doing!
* Remember, messages are only anti-flooded on incoming from the client, not on
* incoming from a server for a given client, so if you tweak this you risk
* allowing a client to flood differently depending upon where they are on
* the network..
* -- adrian
*/
/* MAX_FLOOD is the amount of lines in a 'burst' we allow from a client,
* anything beyond MAX_FLOOD is limited to about one line per second.
*
* MAX_FLOOD_BURST is the amount of lines we allow from a client who has
* just connected. this allows clients to rejoin multiple channels
* without being so heavily penalised they excess flood.
*/
/*
* spb: Made these configurable
*/
#define MAX_FLOOD ConfigFileEntry.client_flood_burst_max
#define MAX_FLOOD_BURST ConfigFileEntry.client_flood_burst_rate
extern PF read_packet; extern PF read_packet;
extern EVH flood_recalc; extern EVH flood_recalc;
extern void flood_endgrace(struct Client *); extern void flood_endgrace(struct Client *);

View file

@ -131,13 +131,13 @@ static struct InfoStruct info_table[] = {
"client_flood_burst_rate", "client_flood_burst_rate",
OUTPUT_DECIMAL, OUTPUT_DECIMAL,
&ConfigFileEntry.client_flood_burst_rate, &ConfigFileEntry.client_flood_burst_rate,
"Rate at which burst lines are processed", "Maximum lines per second during flood grace period, times client_flood_message_time",
}, },
{ {
"client_flood_burst_max", "client_flood_burst_max",
OUTPUT_DECIMAL, OUTPUT_DECIMAL,
&ConfigFileEntry.client_flood_burst_max, &ConfigFileEntry.client_flood_burst_max,
"Number of lines to permit at client_flood_burst_rate", "Number of lines to process at once before delaying, times client_flood_message_time",
}, },
{ {
"client_flood_message_num", "client_flood_message_num",

View file

@ -45,16 +45,17 @@ static void
parse_client_queued(struct Client *client_p) parse_client_queued(struct Client *client_p)
{ {
int dolen = 0; int dolen = 0;
int checkflood = 1; int allow_read;
if(IsAnyDead(client_p)) if(IsAnyDead(client_p))
return; return;
if(IsUnknown(client_p)) if(IsUnknown(client_p))
{ {
allow_read = ConfigFileEntry.client_flood_burst_max;
for (;;) for (;;)
{ {
if(client_p->localClient->sent_parsed >= client_p->localClient->allow_read) if(client_p->localClient->sent_parsed >= allow_read)
break; break;
dolen = rb_linebuf_get(&client_p->localClient-> dolen = rb_linebuf_get(&client_p->localClient->
@ -96,9 +97,15 @@ parse_client_queued(struct Client *client_p)
} }
else if(IsClient(client_p)) else if(IsClient(client_p))
{ {
if(IsFloodDone(client_p))
allow_read = ConfigFileEntry.client_flood_burst_max;
else
allow_read = ConfigFileEntry.client_flood_burst_rate;
/* allow opers 4 times the amount of messages as users. why 4?
* why not. :) --fl_
*/
if(IsOper(client_p) && ConfigFileEntry.no_oper_flood) if(IsOper(client_p) && ConfigFileEntry.no_oper_flood)
checkflood = 0; allow_read *= 4;
/* /*
* Handle flood protection here - if we exceed our flood limit on * Handle flood protection here - if we exceed our flood limit on
* messages in this loop, we simply drop out of the loop prematurely. * messages in this loop, we simply drop out of the loop prematurely.
@ -119,16 +126,7 @@ parse_client_queued(struct Client *client_p)
* as sent_parsed will always hover around the allow_read limit * as sent_parsed will always hover around the allow_read limit
* and no 'bursts' will be permitted. * and no 'bursts' will be permitted.
*/ */
if(checkflood) if(client_p->localClient->sent_parsed >= allow_read)
{
if(client_p->localClient->sent_parsed >= client_p->localClient->allow_read)
break;
}
/* allow opers 4 times the amount of messages as users. why 4?
* why not. :) --fl_
*/
else if(client_p->localClient->sent_parsed >= (4 * client_p->localClient->allow_read))
break; break;
dolen = rb_linebuf_get(&client_p->localClient-> dolen = rb_linebuf_get(&client_p->localClient->
@ -156,11 +154,8 @@ flood_endgrace(struct Client *client_p)
{ {
SetFloodDone(client_p); SetFloodDone(client_p);
/* Drop their flood limit back down */ /* sent_parsed could be way over client_flood_burst_max but under
client_p->localClient->allow_read = MAX_FLOOD; * client_flood_burst_rate so reset it.
/* sent_parsed could be way over MAX_FLOOD but under MAX_FLOOD_BURST,
* so reset it.
*/ */
client_p->localClient->sent_parsed = 0; client_p->localClient->sent_parsed = 0;
} }

View file

@ -185,7 +185,6 @@ release_auth_client(struct AuthRequest *auth)
* us. This is what read_packet() does. * us. This is what read_packet() does.
* -- adrian * -- adrian
*/ */
client->localClient->allow_read = MAX_FLOOD;
rb_dlinkAddTail(client, &client->node, &global_client_list); rb_dlinkAddTail(client, &client->node, &global_client_list);
read_packet(client->localClient->F, client); read_packet(client->localClient->F, client);
} }

View file

@ -260,8 +260,6 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
return -1; return -1;
client_p->localClient->last = rb_current_time(); client_p->localClient->last = rb_current_time();
/* Straight up the maximum rate of flooding... */
source_p->localClient->allow_read = MAX_FLOOD_BURST;
/* XXX - fixme. we shouldnt have to build a users buffer twice.. */ /* XXX - fixme. we shouldnt have to build a users buffer twice.. */
if(!IsGotId(source_p) && (strchr(username, '[') != NULL)) if(!IsGotId(source_p) && (strchr(username, '[') != NULL))
@ -545,8 +543,6 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
if(++Count.total > Count.max_tot) if(++Count.total > Count.max_tot)
Count.max_tot = Count.total; Count.max_tot = Count.total;
source_p->localClient->allow_read = MAX_FLOOD_BURST;
Count.totalrestartcount++; Count.totalrestartcount++;
s_assert(source_p->localClient != NULL); s_assert(source_p->localClient != NULL);