typedef struct _reject_data
{
rb_dlink_node rnode;
+ struct ConfItem *aconf;
+ const char *reason;
time_t time;
unsigned int count;
uint32_t mask_hashv;
{
rb_dlink_node node;
rb_fde_t *F;
+ struct ConfItem *aconf;
+ const char *reason;
} delay_t;
typedef struct _throttle
return rb_dlink_list_length(&delay_exit);
}
+static void
+reject_free(reject_t *rdata)
+{
+ struct ConfItem *aconf = rdata->aconf;
+
+ if (aconf)
+ deref_conf(aconf);
+
+ rb_free(rdata);
+}
+
static void
reject_exit(void *unused)
{
+ static char dynamic_reason[BUFSIZE];
rb_dlink_node *ptr, *ptr_next;
delay_t *ddata;
static const char *errbuf = "ERROR :Closing Link: (*** Banned (cache))\r\n";
{
ddata = ptr->data;
+ *dynamic_reason = '\0';
+
+ if (ddata->aconf)
+ {
+ snprintf(dynamic_reason, BUFSIZE, form_str(ERR_YOUREBANNEDCREEP) "\r\n",
+ me.name, "*", get_user_ban_reason(ddata->aconf));
+ rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason));
+
+ deref_conf(ddata->aconf);
+ }
+ else if (ddata->reason)
+ {
+ snprintf(dynamic_reason, BUFSIZE, ":%s 465 %s :%s\r\n",
+ me.name, "*", ddata->reason);
+ rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason));
+ }
+
rb_write(ddata->F, errbuf, strlen(errbuf));
rb_close(ddata->F);
rb_free(ddata);
continue;
rb_dlinkDelete(ptr, &reject_list);
- rb_free(rdata);
+ reject_free(rdata);
rb_patricia_remove(reject_tree, pnode);
}
}
}
void
-add_reject(struct Client *client_p, const char *mask1, const char *mask2)
+add_reject(struct Client *client_p, const char *mask1, const char *mask2, struct ConfItem *aconf, const char *reason)
{
rb_patricia_node_t *pnode;
reject_t *rdata;
else
{
int bitlen = 32;
-#ifdef RB_IPV6
if(GET_SS_FAMILY(&client_p->localClient->ip) == AF_INET6)
bitlen = 128;
-#endif
pnode = make_and_lookup_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip, bitlen);
pnode->data = rdata = rb_malloc(sizeof(reject_t));
rb_dlinkAddTail(pnode, &rdata->rnode, &reject_list);
rdata->time = rb_current_time();
rdata->count = 1;
+ rdata->aconf = NULL;
+ rdata->reason = NULL;
}
rdata->mask_hashv = hashv;
+
+ if (aconf != NULL && aconf != rdata->aconf && (aconf->status & CONF_KILL) && aconf->passwd)
+ {
+ if (rdata->aconf != NULL)
+ deref_conf(rdata->aconf);
+ aconf->clients++;
+ rdata->aconf = aconf;
+ }
+ else if (reason != NULL)
+ {
+ if (rdata->aconf != NULL)
+ deref_conf(rdata->aconf);
+ rdata->aconf = NULL;
+ rdata->reason = reason;
+ }
}
int
ddata = rb_malloc(sizeof(delay_t));
ServerStats.is_rej++;
rb_setselect(F, RB_SELECT_WRITE | RB_SELECT_READ, NULL, NULL);
+ if(rdata->aconf)
+ {
+ ddata->aconf = rdata->aconf;
+ ddata->aconf->clients++;
+ ddata->reason = NULL;
+ }
+ else if(rdata->reason)
+ {
+ ddata->reason = rdata->reason;
+ ddata->aconf = NULL;
+ }
+ else
+ {
+ ddata->aconf = NULL;
+ ddata->reason = NULL;
+ }
ddata->F = F;
rb_dlinkAdd(ddata, &ddata->node, &delay_exit);
return 1;
pnode = ptr->data;
rdata = pnode->data;
rb_dlinkDelete(ptr, &reject_list);
- rb_free(rdata);
+ reject_free(rdata);
rb_patricia_remove(reject_tree, pnode);
}
}
{
reject_t *rdata = pnode->data;
rb_dlinkDelete(&rdata->rnode, &reject_list);
- rb_free(rdata);
+ reject_free(rdata);
rb_patricia_remove(reject_tree, pnode);
return 1;
}
if (rdata->mask_hashv == hashv)
{
rb_dlinkDelete(ptr, &reject_list);
- rb_free(rdata);
+ reject_free(rdata);
rb_patricia_remove(reject_tree, pnode);
n++;
}
} 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;