diff --git a/include/packet.h b/include/packet.h index 7962e6b3..6f7e3d3b 100644 --- a/include/packet.h +++ b/include/packet.h @@ -48,7 +48,7 @@ extern PF read_ctrl_packet; extern PF read_packet; -extern PF flood_recalc; +extern EVH flood_recalc; extern void flood_endgrace(struct Client *); #endif /* INCLUDED_packet_h */ diff --git a/src/client.c b/src/client.c index ecc87224..f8894da3 100644 --- a/src/client.c +++ b/src/client.c @@ -126,6 +126,7 @@ init_client(void) rb_event_addish("check_pings", check_pings, NULL, 30); rb_event_addish("free_exited_clients", &free_exited_clients, NULL, 4); rb_event_addish("exit_aborted_clients", exit_aborted_clients, NULL, 1); + rb_event_add("flood_recalc", flood_recalc, NULL, 1); nd_dict = irc_dictionary_create(irccmp); } diff --git a/src/packet.c b/src/packet.c index 6d203a1b..f1d87cdc 100644 --- a/src/packet.c +++ b/src/packet.c @@ -165,43 +165,63 @@ flood_endgrace(struct Client *client_p) client_p->localClient->sent_parsed = 0; } -/* - * flood_recalc - * - * recalculate the number of allowed flood lines. this should be called - * once a second on any given client. We then attempt to flush some data. - */ -void -flood_recalc(int fd, void *data) -{ - struct Client *client_p = data; - struct LocalUser *lclient_p = client_p->localClient; - - /* This can happen in the event that the client detached. */ - if(!lclient_p) - return; - - /* allow a bursting client their allocation per second, allow - * a client whos flooding an extra 2 per second - */ - if(IsFloodDone(client_p)) - lclient_p->sent_parsed -= 2; - else - lclient_p->sent_parsed = 0; - - if(lclient_p->sent_parsed < 0) - lclient_p->sent_parsed = 0; - - if(--lclient_p->actually_read < 0) - lclient_p->actually_read = 0; - - parse_client_queued(client_p); - - if(IsAnyDead(client_p)) - return; - - /* and finally, reset the flood check */ - rb_setflush(fd, 1000, flood_recalc, client_p); +/* + * flood_recalc + * + * recalculate the number of allowed flood lines. this should be called + * once a second on any given client. We then attempt to flush some data. + */ +void +flood_recalc(void *unused) +{ + rb_dlink_node *ptr, *next; + struct Client *client_p; + + RB_DLINK_FOREACH_SAFE(ptr, next, lclient_list.head) + { + client_p = ptr->data; + + if(unlikely(IsMe(client_p))) + continue; + + if(unlikely(client_p->localClient == NULL)) + continue; + + if(IsFloodDone(client_p)) + client_p->localClient->sent_parsed -= 2; + else + client_p->localClient->sent_parsed = 0; + + if(client_p->localClient->sent_parsed < 0) + client_p->localClient->sent_parsed = 0; + + if(--client_p->localClient->actually_read < 0) + client_p->localClient->actually_read = 0; + + parse_client_queued(client_p); + + if(unlikely(IsAnyDead(client_p))) + continue; + + } + + RB_DLINK_FOREACH_SAFE(ptr, next, unknown_list.head) + { + client_p = ptr->data; + + if(client_p->localClient == NULL) + continue; + + client_p->localClient->sent_parsed--; + + if(client_p->localClient->sent_parsed < 0) + client_p->localClient->sent_parsed = 0; + + if(--client_p->localClient->actually_read < 0) + client_p->localClient->actually_read = 0; + + parse_client_queued(client_p); + } } /*