Keep propagated bans in a dictionary, not a list
This commit is contained in:
parent
8b7110d6ba
commit
ce376a21cc
8 changed files with 84 additions and 69 deletions
|
@ -338,7 +338,7 @@ extern struct admin_info AdminInfo; /* defined in ircd.c */
|
|||
|
||||
extern rb_dlink_list service_list;
|
||||
|
||||
extern rb_dlink_list prop_bans;
|
||||
extern rb_dictionary *prop_bans_dict;
|
||||
|
||||
typedef enum temp_list
|
||||
{
|
||||
|
@ -357,8 +357,11 @@ extern void init_s_conf(void);
|
|||
extern struct ConfItem *make_conf(void);
|
||||
extern void free_conf(struct ConfItem *);
|
||||
|
||||
extern rb_dlink_node *find_prop_ban(unsigned int status, const char *user, const char *host);
|
||||
extern void deactivate_conf(struct ConfItem *, rb_dlink_node *, time_t);
|
||||
extern struct ConfItem *find_prop_ban(unsigned int status, const char *user, const char *host);
|
||||
extern void add_prop_ban(struct ConfItem *);
|
||||
extern void remove_prop_ban(struct ConfItem *);
|
||||
extern bool lookup_prop_ban(struct ConfItem *);
|
||||
extern void deactivate_conf(struct ConfItem *, time_t);
|
||||
extern void replace_old_ban(struct ConfItem *);
|
||||
|
||||
extern void read_conf_files(bool cold);
|
||||
|
|
|
@ -62,22 +62,24 @@ extern char yy_linebuf[16384]; /* defined in ircd_lexer.l */
|
|||
|
||||
static rb_bh *confitem_heap = NULL;
|
||||
|
||||
rb_dlink_list prop_bans;
|
||||
|
||||
rb_dlink_list temp_klines[LAST_TEMP_TYPE];
|
||||
rb_dlink_list temp_dlines[LAST_TEMP_TYPE];
|
||||
rb_dlink_list service_list;
|
||||
|
||||
rb_dictionary *prop_bans_dict;
|
||||
|
||||
/* internally defined functions */
|
||||
static void set_default_conf(void);
|
||||
static void validate_conf(void);
|
||||
static void read_conf(void);
|
||||
static void clear_out_old_conf(void);
|
||||
|
||||
static void expire_prop_bans(void *list);
|
||||
static void expire_prop_bans(void *);
|
||||
static void expire_temp_kd(void *list);
|
||||
static void reorganise_temp_kd(void *list);
|
||||
|
||||
static int cmp_prop_ban(const void *, const void *);
|
||||
|
||||
FILE *conf_fbfile_in;
|
||||
extern char yytext[];
|
||||
|
||||
|
@ -89,8 +91,9 @@ void
|
|||
init_s_conf(void)
|
||||
{
|
||||
confitem_heap = rb_bh_create(sizeof(struct ConfItem), CONFITEM_HEAP_SIZE, "confitem_heap");
|
||||
prop_bans_dict = rb_dictionary_create("prop_bans", cmp_prop_ban);
|
||||
|
||||
rb_event_addish("expire_prop_bans", expire_prop_bans, &prop_bans, 60);
|
||||
rb_event_addish("expire_prop_bans", expire_prop_bans, NULL, 60);
|
||||
|
||||
rb_event_addish("expire_temp_klines", expire_temp_kd, &temp_klines[TEMP_MIN], 60);
|
||||
rb_event_addish("expire_temp_dlines", expire_temp_kd, &temp_dlines[TEMP_MIN], 60);
|
||||
|
@ -1080,32 +1083,53 @@ valid_wild_card(const char *luser, const char *lhost)
|
|||
return 0;
|
||||
}
|
||||
|
||||
rb_dlink_node *
|
||||
find_prop_ban(unsigned int status, const char *user, const char *host)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct ConfItem *aconf;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, prop_bans.head)
|
||||
int cmp_prop_ban(const void *a_, const void *b_)
|
||||
{
|
||||
aconf = ptr->data;
|
||||
const struct ConfItem *a = a_, *b = b_;
|
||||
int r;
|
||||
|
||||
if((aconf->status & ~CONF_ILLEGAL) == status &&
|
||||
(!user || !aconf->user ||
|
||||
!irccmp(aconf->user, user)) &&
|
||||
!irccmp(aconf->host, host))
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
if ((a->status & ~CONF_ILLEGAL) > (int)(b->status & ~CONF_ILLEGAL)) return 1;
|
||||
if ((a->status & ~CONF_ILLEGAL) < (int)(b->status & ~CONF_ILLEGAL)) return -1;
|
||||
|
||||
r = irccmp(a->host, b->host);
|
||||
if (r) return r;
|
||||
|
||||
if (a->user && b->user)
|
||||
return irccmp(a->user, b->user);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
deactivate_conf(struct ConfItem *aconf, rb_dlink_node *ptr, time_t now)
|
||||
add_prop_ban(struct ConfItem *aconf)
|
||||
{
|
||||
rb_dictionary_add(prop_bans_dict, aconf, aconf);
|
||||
}
|
||||
|
||||
struct ConfItem *
|
||||
find_prop_ban(unsigned status, const char *user, const char *host)
|
||||
{
|
||||
struct ConfItem key = {.status = status, .user = (char *)user, .host = (char *)host};
|
||||
return rb_dictionary_retrieve(prop_bans_dict, &key);
|
||||
}
|
||||
|
||||
void
|
||||
remove_prop_ban(struct ConfItem *aconf)
|
||||
{
|
||||
rb_dictionary_delete(prop_bans_dict, aconf);
|
||||
}
|
||||
|
||||
bool lookup_prop_ban(struct ConfItem *aconf)
|
||||
{
|
||||
return rb_dictionary_retrieve(prop_bans_dict, aconf) == aconf;
|
||||
}
|
||||
|
||||
void
|
||||
deactivate_conf(struct ConfItem *aconf, time_t now)
|
||||
{
|
||||
int i;
|
||||
|
||||
s_assert(ptr->data == aconf);
|
||||
|
||||
switch (aconf->status)
|
||||
{
|
||||
case CONF_KILL:
|
||||
|
@ -1146,7 +1170,7 @@ deactivate_conf(struct ConfItem *aconf, rb_dlink_node *ptr, time_t now)
|
|||
else
|
||||
{
|
||||
if (aconf->lifetime != 0)
|
||||
rb_dlinkDestroy(ptr, &prop_bans);
|
||||
remove_prop_ban(aconf);
|
||||
if (aconf->clients == 0)
|
||||
free_conf(aconf);
|
||||
else
|
||||
|
@ -1160,13 +1184,11 @@ deactivate_conf(struct ConfItem *aconf, rb_dlink_node *ptr, time_t now)
|
|||
void
|
||||
replace_old_ban(struct ConfItem *aconf)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct ConfItem *oldconf;
|
||||
|
||||
ptr = find_prop_ban(aconf->status, aconf->user, aconf->host);
|
||||
if(ptr != NULL)
|
||||
oldconf = find_prop_ban(aconf->status, aconf->user, aconf->host);
|
||||
if (oldconf != NULL)
|
||||
{
|
||||
oldconf = ptr->data;
|
||||
/* Remember at least as long as the old one. */
|
||||
if(oldconf->lifetime > aconf->lifetime)
|
||||
aconf->lifetime = oldconf->lifetime;
|
||||
|
@ -1180,23 +1202,21 @@ replace_old_ban(struct ConfItem *aconf)
|
|||
aconf->lifetime = aconf->hold;
|
||||
/* Tell deactivate_conf() to destroy it. */
|
||||
oldconf->lifetime = rb_current_time();
|
||||
deactivate_conf(oldconf, ptr, oldconf->lifetime);
|
||||
deactivate_conf(oldconf, oldconf->lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
expire_prop_bans(void *list)
|
||||
expire_prop_bans(void *unused)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
rb_dlink_node *next_ptr;
|
||||
struct ConfItem *aconf;
|
||||
time_t now;
|
||||
rb_dictionary_iter state;
|
||||
|
||||
now = rb_current_time();
|
||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, ((rb_dlink_list *) list)->head)
|
||||
{
|
||||
aconf = ptr->data;
|
||||
|
||||
RB_DICTIONARY_FOREACH(aconf, &state, prop_bans_dict)
|
||||
{
|
||||
if(aconf->lifetime <= now ||
|
||||
(aconf->hold <= now &&
|
||||
!(aconf->status & CONF_ILLEGAL)))
|
||||
|
@ -1212,7 +1232,7 @@ expire_prop_bans(void *list)
|
|||
aconf->host ? aconf->host : "*");
|
||||
|
||||
/* will destroy or mark illegal */
|
||||
deactivate_conf(aconf, ptr, now);
|
||||
deactivate_conf(aconf, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -472,14 +472,12 @@ send_capabilities(struct Client *client_p, unsigned int cap_can_send)
|
|||
static void
|
||||
burst_ban(struct Client *client_p)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct ConfItem *aconf;
|
||||
const char *type;
|
||||
rb_dictionary_iter state;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, prop_bans.head)
|
||||
RB_DICTIONARY_FOREACH(aconf, &state, prop_bans_dict)
|
||||
{
|
||||
aconf = ptr->data;
|
||||
|
||||
/* Skip expired stuff. */
|
||||
if(aconf->lifetime < rb_current_time())
|
||||
continue;
|
||||
|
|
|
@ -82,7 +82,6 @@ m_ban(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
|
|||
static void
|
||||
ms_ban(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct ConfItem *aconf;
|
||||
unsigned int ntype;
|
||||
const char *oper, *stype;
|
||||
|
@ -90,6 +89,7 @@ ms_ban(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
|||
char *p;
|
||||
int act;
|
||||
int valid;
|
||||
bool new = false;
|
||||
|
||||
now = rb_current_time();
|
||||
if (strlen(parv[1]) != 1)
|
||||
|
@ -127,11 +127,10 @@ ms_ban(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
|||
oper = IsServer(source_p) ? source_p->name : get_oper_name(source_p);
|
||||
else
|
||||
oper = parv[7];
|
||||
ptr = find_prop_ban(ntype, parv[2], parv[3]);
|
||||
if (ptr != NULL)
|
||||
aconf = find_prop_ban(ntype, parv[2], parv[3]);
|
||||
if (aconf != NULL)
|
||||
{
|
||||
/* We already know about this ban mask. */
|
||||
aconf = ptr->data;
|
||||
if (aconf->created > created ||
|
||||
(aconf->created == created &&
|
||||
aconf->lifetime >= lifetime))
|
||||
|
@ -158,7 +157,7 @@ ms_ban(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
|||
if (aconf->lifetime <= now)
|
||||
return;
|
||||
/* Deactivate, it will be reactivated later if appropriate. */
|
||||
deactivate_conf(aconf, ptr, now);
|
||||
deactivate_conf(aconf, now);
|
||||
rb_free(aconf->user);
|
||||
aconf->user = NULL;
|
||||
rb_free(aconf->host);
|
||||
|
@ -176,8 +175,8 @@ ms_ban(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
|||
aconf = make_conf();
|
||||
aconf->status = CONF_ILLEGAL | ntype;
|
||||
aconf->lifetime = lifetime;
|
||||
rb_dlinkAddAlloc(aconf, &prop_bans);
|
||||
act = hold != created && hold > now;
|
||||
new = true;
|
||||
}
|
||||
aconf->flags &= ~CONF_FLAGS_MYOPER;
|
||||
aconf->flags |= CONF_FLAGS_TEMPORARY;
|
||||
|
@ -186,6 +185,8 @@ ms_ban(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
|||
aconf->info.oper = operhash_add(oper);
|
||||
aconf->created = created;
|
||||
aconf->hold = hold;
|
||||
if (new)
|
||||
add_prop_ban(aconf);
|
||||
if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL)
|
||||
aconf->passwd = rb_strdup(parv[parc - 1]);
|
||||
else
|
||||
|
|
|
@ -602,7 +602,7 @@ apply_prop_kline(struct Client *source_p, struct ConfItem *aconf,
|
|||
|
||||
replace_old_ban(aconf);
|
||||
|
||||
rb_dlinkAddAlloc(aconf, &prop_bans);
|
||||
add_prop_ban(aconf);
|
||||
add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
|
||||
|
||||
/* no oper reason.. */
|
||||
|
@ -860,11 +860,9 @@ remove_temp_kline(struct Client *source_p, struct ConfItem *aconf)
|
|||
static void
|
||||
remove_prop_kline(struct Client *source_p, struct ConfItem *aconf)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
time_t now;
|
||||
|
||||
ptr = rb_dlinkFind(aconf, &prop_bans);
|
||||
if (!ptr)
|
||||
if (!lookup_prop_ban(aconf))
|
||||
return;
|
||||
sendto_one_notice(source_p,
|
||||
":Un-klined [%s@%s] from global k-lines",
|
||||
|
@ -892,5 +890,5 @@ remove_prop_kline(struct Client *source_p, struct ConfItem *aconf)
|
|||
0,
|
||||
(int)(aconf->lifetime - aconf->created));
|
||||
remove_reject_mask(aconf->user, aconf->host);
|
||||
deactivate_conf(aconf, ptr, now);
|
||||
deactivate_conf(aconf, now);
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
|
|||
aconf->hold = rb_current_time() + temp_time;
|
||||
aconf->lifetime = aconf->hold;
|
||||
replace_old_ban(aconf);
|
||||
rb_dlinkAddAlloc(aconf, &prop_bans);
|
||||
add_prop_ban(aconf);
|
||||
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"%s added global %d min. RESV for [%s] [%s]",
|
||||
|
@ -312,7 +312,7 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
|
|||
aconf->hold = rb_current_time() + temp_time;
|
||||
aconf->lifetime = aconf->hold;
|
||||
replace_old_ban(aconf);
|
||||
rb_dlinkAddAlloc(aconf, &prop_bans);
|
||||
add_prop_ban(aconf);
|
||||
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"%s added global %d min. RESV for [%s] [%s]",
|
||||
|
@ -511,8 +511,7 @@ remove_resv(struct Client *source_p, const char *name, int propagated)
|
|||
sendto_one_notice(source_p, ":Cannot remove global RESV %s on specific servers", name);
|
||||
return;
|
||||
}
|
||||
ptr = rb_dlinkFind(aconf, &prop_bans);
|
||||
if(ptr == NULL)
|
||||
if (!lookup_prop_ban(aconf))
|
||||
return;
|
||||
sendto_one_notice(source_p, ":RESV for [%s] is removed", name);
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
|
@ -534,7 +533,7 @@ remove_resv(struct Client *source_p, const char *name, int propagated)
|
|||
(unsigned long)aconf->created,
|
||||
0,
|
||||
(int)(aconf->lifetime - aconf->created));
|
||||
deactivate_conf(aconf, ptr, now);
|
||||
deactivate_conf(aconf, now);
|
||||
return;
|
||||
}
|
||||
else if(propagated && rb_dlink_list_length(&cluster_conf_list) > 0)
|
||||
|
@ -585,8 +584,7 @@ remove_resv(struct Client *source_p, const char *name, int propagated)
|
|||
sendto_one_notice(source_p, ":Cannot remove global RESV %s on specific servers", name);
|
||||
return;
|
||||
}
|
||||
ptr = rb_dlinkFind(aconf, &prop_bans);
|
||||
if(ptr == NULL)
|
||||
if (!lookup_prop_ban(aconf))
|
||||
return;
|
||||
sendto_one_notice(source_p, ":RESV for [%s] is removed", name);
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
|
@ -608,7 +606,7 @@ remove_resv(struct Client *source_p, const char *name, int propagated)
|
|||
(unsigned long)aconf->created,
|
||||
0,
|
||||
(int)(aconf->lifetime - aconf->created));
|
||||
deactivate_conf(aconf, ptr, now);
|
||||
deactivate_conf(aconf, now);
|
||||
return;
|
||||
}
|
||||
else if(propagated && rb_dlink_list_length(&cluster_conf_list) > 0)
|
||||
|
|
|
@ -503,13 +503,11 @@ static void
|
|||
stats_prop_klines(struct Client *source_p)
|
||||
{
|
||||
struct ConfItem *aconf;
|
||||
rb_dlink_node *ptr;
|
||||
char *user, *host, *pass, *oper_reason;
|
||||
rb_dictionary_iter state;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, prop_bans.head)
|
||||
RB_DICTIONARY_FOREACH(aconf, &state, prop_bans_dict)
|
||||
{
|
||||
aconf = ptr->data;
|
||||
|
||||
/* Skip non-klines and deactivated klines. */
|
||||
if (aconf->status != CONF_KILL)
|
||||
continue;
|
||||
|
|
|
@ -285,7 +285,7 @@ apply_xline(struct Client *source_p, const char *name, const char *reason, int t
|
|||
aconf->lifetime = aconf->hold;
|
||||
|
||||
replace_old_ban(aconf);
|
||||
rb_dlinkAddAlloc(aconf, &prop_bans);
|
||||
add_prop_ban(aconf);
|
||||
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"%s added global %d min. X-Line for [%s] [%s]",
|
||||
|
@ -475,8 +475,7 @@ remove_xline(struct Client *source_p, const char *name, bool propagated)
|
|||
sendto_one_notice(source_p, ":Cannot remove global X-Line %s on specific servers", name);
|
||||
return;
|
||||
}
|
||||
ptr = rb_dlinkFind(aconf, &prop_bans);
|
||||
if(ptr == NULL)
|
||||
if (!lookup_prop_ban(aconf))
|
||||
return;
|
||||
sendto_one_notice(source_p, ":X-Line for [%s] is removed", name);
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
|
@ -499,7 +498,7 @@ remove_xline(struct Client *source_p, const char *name, bool propagated)
|
|||
0,
|
||||
(int)(aconf->lifetime - aconf->created));
|
||||
remove_reject_mask(aconf->host, NULL);
|
||||
deactivate_conf(aconf, ptr, now);
|
||||
deactivate_conf(aconf, now);
|
||||
return;
|
||||
}
|
||||
else if(propagated && rb_dlink_list_length(&cluster_conf_list))
|
||||
|
|
Loading…
Reference in a new issue