X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/8017ad2d27300cee40fde463a542cf9376f61b78..8e69bb4e903f428b14e2950cce9be39dc8ddd12c:/src/reject.c diff --git a/src/reject.c b/src/reject.c index 1073321..afdfc85 100644 --- a/src/reject.c +++ b/src/reject.c @@ -33,18 +33,20 @@ #include "reject.h" #include "s_stats.h" #include "msg.h" +#include "hash.h" static patricia_tree_t *reject_tree; -dlink_list delay_exit; -static dlink_list reject_list; +rb_dlink_list delay_exit; +static rb_dlink_list reject_list; static patricia_tree_t *unknown_tree; struct reject_data { - dlink_node rnode; + rb_dlink_node rnode; time_t time; unsigned int count; + uint32_t mask_hashv; }; static patricia_tree_t *unknown_tree; @@ -53,9 +55,9 @@ static void reject_exit(void *unused) { struct Client *client_p; - dlink_node *ptr, *ptr_next; + rb_dlink_node *ptr, *ptr_next; - DLINK_FOREACH_SAFE(ptr, ptr_next, delay_exit.head) + RB_DLINK_FOREACH_SAFE(ptr, ptr_next, delay_exit.head) { client_p = ptr->data; if(IsDead(client_p)) @@ -79,7 +81,7 @@ reject_exit(void *unused) } close_connection(client_p); SetDead(client_p); - dlinkAddAlloc(client_p, &dead_list); + rb_dlinkAddAlloc(client_p, &dead_list); } delay_exit.head = delay_exit.tail = NULL; @@ -89,11 +91,11 @@ reject_exit(void *unused) static void reject_expires(void *unused) { - dlink_node *ptr, *next; + rb_dlink_node *ptr, *next; patricia_node_t *pnode; struct reject_data *rdata; - DLINK_FOREACH_SAFE(ptr, next, reject_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head) { pnode = ptr->data; rdata = pnode->data; @@ -101,7 +103,7 @@ reject_expires(void *unused) if(rdata->time + ConfigFileEntry.reject_duration > CurrentTime) continue; - dlinkDelete(ptr, &reject_list); + rb_dlinkDelete(ptr, &reject_list); MyFree(rdata); patricia_remove(reject_tree, pnode); } @@ -118,15 +120,22 @@ init_reject(void) void -add_reject(struct Client *client_p) +add_reject(struct Client *client_p, const char *mask1, const char *mask2) { patricia_node_t *pnode; struct reject_data *rdata; + uint32_t hashv; /* Reject is disabled */ if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0) return; + hashv = 0; + if (mask1 != NULL) + hashv ^= fnv_hash_upper(mask1, 32); + if (mask2 != NULL) + hashv ^= fnv_hash_upper(mask2, 32); + if((pnode = match_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip)) != NULL) { rdata = pnode->data; @@ -142,10 +151,11 @@ add_reject(struct Client *client_p) #endif pnode = make_and_lookup_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip, bitlen); pnode->data = rdata = MyMalloc(sizeof(struct reject_data)); - dlinkAddTail(pnode, &rdata->rnode, &reject_list); + rb_dlinkAddTail(pnode, &rdata->rnode, &reject_list); rdata->time = CurrentTime; rdata->count = 1; } + rdata->mask_hashv = hashv; } int @@ -169,9 +179,9 @@ check_reject(struct Client *client_p) { ServerStats->is_rej++; SetReject(client_p); - comm_setselect(client_p->localClient->fd, FDLIST_NONE, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0); + rb_setselect(client_p->localClient->F->fd, FDLIST_NONE, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0); SetClosing(client_p); - dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &delay_exit); + rb_dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &delay_exit); return 1; } } @@ -182,22 +192,22 @@ check_reject(struct Client *client_p) void flush_reject(void) { - dlink_node *ptr, *next; + rb_dlink_node *ptr, *next; patricia_node_t *pnode; struct reject_data *rdata; - DLINK_FOREACH_SAFE(ptr, next, reject_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head) { pnode = ptr->data; rdata = pnode->data; - dlinkDelete(ptr, &reject_list); + rb_dlinkDelete(ptr, &reject_list); MyFree(rdata); patricia_remove(reject_tree, pnode); } } int -remove_reject(const char *ip) +remove_reject_ip(const char *ip) { patricia_node_t *pnode; @@ -209,7 +219,7 @@ remove_reject(const char *ip) if((pnode = match_string(reject_tree, ip)) != NULL) { struct reject_data *rdata = pnode->data; - dlinkDelete(&rdata->rnode, &reject_list); + rb_dlinkDelete(&rdata->rnode, &reject_list); MyFree(rdata); patricia_remove(reject_tree, pnode); return 1; @@ -217,6 +227,35 @@ remove_reject(const char *ip) return 0; } +int +remove_reject_mask(const char *mask1, const char *mask2) +{ + rb_dlink_node *ptr, *next; + patricia_node_t *pnode; + struct reject_data *rdata; + uint32_t hashv; + int n = 0; + + hashv = 0; + if (mask1 != NULL) + hashv ^= fnv_hash_upper(mask1, 32); + if (mask2 != NULL) + hashv ^= fnv_hash_upper(mask2, 32); + RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head) + { + pnode = ptr->data; + rdata = pnode->data; + if (rdata->mask_hashv == hashv) + { + rb_dlinkDelete(ptr, &reject_list); + MyFree(rdata); + patricia_remove(reject_tree, pnode); + n++; + } + } + return n; +} + int add_unknown_ip(struct Client *client_p) @@ -238,9 +277,9 @@ add_unknown_ip(struct Client *client_p) { SetExUnknown(client_p); SetReject(client_p); - comm_setselect(client_p->localClient->fd, FDLIST_NONE, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0); + rb_setselect(client_p->localClient->F->fd, FDLIST_NONE, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0); SetClosing(client_p); - dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &delay_exit); + rb_dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &delay_exit); return 1; }