+int
+remove_reject_mask(const char *mask1, const char *mask2)
+{
+ rb_dlink_node *ptr, *next;
+ rb_patricia_node_t *pnode;
+ reject_t *rdata;
+ uint32_t hashv;
+ int n = 0;
+
+ hashv = 0;
+ if (mask1 != NULL)
+ hashv ^= fnv_hash_upper((const unsigned char *)mask1, 32);
+ if (mask2 != NULL)
+ hashv ^= fnv_hash_upper((const unsigned char *)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);
+ rb_free(rdata);
+ rb_patricia_remove(reject_tree, pnode);
+ n++;
+ }
+ }
+ return n;
+}
+
+int
+throttle_add(struct sockaddr *addr)
+{
+ throttle_t *t;
+ rb_patricia_node_t *pnode;
+
+ if((pnode = rb_match_ip(throttle_tree, addr)) != NULL)
+ {
+ t = pnode->data;
+
+ if(t->count > ConfigFileEntry.throttle_count)
+ {
+ ServerStats.is_thr++;
+ return 1;
+ }
+ /* Stop penalizing them after they've been throttled */
+ t->last = rb_current_time();
+ t->count++;
+
+ } else {
+ int bitlen = 32;
+#ifdef RB_IPV6
+ if(GET_SS_FAMILY(addr) == AF_INET6)
+ bitlen = 128;
+#endif
+ t = rb_malloc(sizeof(throttle_t));
+ t->last = rb_current_time();
+ t->count = 1;
+ pnode = make_and_lookup_ip(throttle_tree, addr, bitlen);
+ pnode->data = t;
+ rb_dlinkAdd(pnode, &t->node, &throttle_list);
+ }
+ return 0;
+}
+
+int
+is_throttle_ip(struct sockaddr *addr)
+{
+ throttle_t *t;
+ rb_patricia_node_t *pnode;
+ int duration;
+
+ if((pnode = rb_match_ip(throttle_tree, addr)) != NULL)
+ {
+ t = pnode->data;
+ if(t->count > ConfigFileEntry.throttle_count)
+ {
+ duration = t->last + ConfigFileEntry.throttle_duration - rb_current_time();
+ return duration > 0 ? duration : 1;
+ }
+ }
+ return 0;
+}
+
+static void
+throttle_expires(void *unused)
+{
+ rb_dlink_node *ptr, *next;
+ rb_patricia_node_t *pnode;
+ throttle_t *t;
+
+ RB_DLINK_FOREACH_SAFE(ptr, next, throttle_list.head)
+ {
+ pnode = ptr->data;
+ t = pnode->data;
+
+ if(t->last + ConfigFileEntry.throttle_duration > rb_current_time())
+ continue;
+
+ rb_dlinkDelete(ptr, &throttle_list);
+ rb_free(t);
+ rb_patricia_remove(throttle_tree, pnode);
+ }
+}
+