diff --git a/include/reject.h b/include/reject.h index c6e27eed..95e2c43d 100644 --- a/include/reject.h +++ b/include/reject.h @@ -32,12 +32,14 @@ void init_reject(void); int check_reject(rb_fde_t *F, struct sockaddr *addr); void add_reject(struct Client *, const char *mask1, const char *mask2); +int is_reject_ip(struct sockaddr *addr); void flush_reject(void); int remove_reject_ip(const char *ip); int remove_reject_mask(const char *mask1, const char *mask2); unsigned long delay_exit_length(void); int throttle_add(struct sockaddr *addr); +int is_throttle_ip(struct sockaddr *addr); unsigned long throttle_size(void); diff --git a/modules/m_testline.c b/modules/m_testline.c index 0bcba6ea..215f48d9 100644 --- a/modules/m_testline.c +++ b/modules/m_testline.c @@ -39,6 +39,7 @@ #include "numeric.h" #include "s_conf.h" #include "s_newconf.h" +#include "reject.h" static int mo_testline(struct Client *, struct Client *, int, const char **); static int mo_testgecos(struct Client *, struct Client *, int, const char **); @@ -69,6 +70,7 @@ mo_testline(struct Client *client_p, struct Client *source_p, int parc, const ch char *p; int host_mask; int type; + int duration; mask = LOCAL_COPY(parv[1]); @@ -136,6 +138,21 @@ mo_testline(struct Client *client_p, struct Client *source_p, int parc, const ch return 0; } + /* Otherwise, aconf is an exempt{} */ + if(aconf == NULL && + (duration = is_reject_ip((struct sockaddr *)&ip))) + sendto_one(source_p, form_str(RPL_TESTLINE), + me.name, source_p->name, + '!', + duration / 60, + host, "Reject cache"); + if(aconf == NULL && + (duration = is_throttle_ip((struct sockaddr *)&ip))) + sendto_one(source_p, form_str(RPL_TESTLINE), + me.name, source_p->name, + '!', + duration / 60, + host, "Throttled"); } if (username != NULL) diff --git a/src/reject.c b/src/reject.c index 6e226ca5..c9c7d455 100644 --- a/src/reject.c +++ b/src/reject.c @@ -211,6 +211,31 @@ check_reject(rb_fde_t *F, struct sockaddr *addr) return 0; } +int +is_reject_ip(struct sockaddr *addr) +{ + rb_patricia_node_t *pnode; + reject_t *rdata; + int duration; + + /* Reject is disabled */ + if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0) + return 0; + + pnode = rb_match_ip(reject_tree, addr); + if(pnode != NULL) + { + rdata = pnode->data; + + if(rdata->count > (unsigned long)ConfigFileEntry.reject_after_count) + { + duration = rdata->time + ConfigFileEntry.reject_duration - rb_current_time(); + return duration > 0 ? duration : 1; + } + } + return 0; +} + void flush_reject(void) { @@ -312,6 +337,25 @@ throttle_add(struct sockaddr *addr) 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) {