From 3002877654f452935d230aa28d1b10f27e0d1648 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Mon, 15 Feb 2010 00:31:17 +0100 Subject: [PATCH] target change: Overwrite the least recently used target with a new one. --- include/client.h | 6 ++++-- include/s_newconf.h | 3 --- modules/core/m_message.c | 37 ++++++++++++++++++++----------------- src/s_user.c | 4 +++- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/include/client.h b/include/client.h index 22b7662..4920fb6 100644 --- a/include/client.h +++ b/include/client.h @@ -53,7 +53,9 @@ struct Blacklist; #define IDLEN 10 -#define TGCHANGE_NUM 10 /* how many targets we keep track of */ +#define TGCHANGE_NUM 10 /* how many targets we keep track of */ +#define TGCHANGE_INITIAL 10 /* initial free targets (normal) */ +#define TGCHANGE_INITIAL_LOW 4 /* initial free targets (possible spambot) */ /* * pre declare structs @@ -258,7 +260,7 @@ struct LocalUser /* target change stuff */ uint32_t targets[TGCHANGE_NUM]; /* targets were aware of (fnv32(use_id(target_p))) */ - unsigned int targinfo[2]; /* cyclic array, no in use */ + unsigned int targets_free; /* free targets */ time_t target_last; /* last time we cleared a slot */ struct ListClient *safelist_data; diff --git a/include/s_newconf.h b/include/s_newconf.h index c0cc561..bee3df7 100644 --- a/include/s_newconf.h +++ b/include/s_newconf.h @@ -60,9 +60,6 @@ extern void init_s_newconf(void); extern void clear_s_newconf(void); extern void clear_s_newconf_bans(void); -#define FREE_TARGET(x) ((x)->localClient->targinfo[0]) -#define USED_TARGETS(x) ((x)->localClient->targinfo[1]) - typedef struct { char *ip; diff --git a/modules/core/m_message.c b/modules/core/m_message.c index 5af579f..8b90052 100644 --- a/modules/core/m_message.c +++ b/modules/core/m_message.c @@ -642,10 +642,6 @@ msg_channel_flags(int p_or_n, const char *command, struct Client *client_p, command, c, chptr->chname, text); } -#define PREV_FREE_TARGET(x) ((FREE_TARGET(x) == 0) ? TGCHANGE_NUM - 1 : FREE_TARGET(x) - 1) -#define PREV_TARGET(i) ((i == 0) ? i = TGCHANGE_NUM - 1 : --i) -#define NEXT_TARGET(i) ((i == TGCHANGE_NUM - 1) ? i = 0 : ++i) - static void expire_tgchange(void *unused) { @@ -671,6 +667,7 @@ add_target(struct Client *source_p, struct Client *target_p) { int i, j; uint32_t hashv; + uint32_t *targets; /* can msg themselves or services without using any target slots */ if(source_p == target_p || IsService(target_p)) @@ -685,17 +682,22 @@ add_target(struct Client *source_p, struct Client *target_p) return 1; hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32); + targets = source_p->localClient->targets; - if(USED_TARGETS(source_p)) + /* check for existing target, and move it to the head */ + for(i = 0; i < TGCHANGE_NUM; i++) { - /* hunt for an existing target */ - for(i = PREV_FREE_TARGET(source_p), j = USED_TARGETS(source_p); - j; --j, PREV_TARGET(i)) + if(targets[i] == hashv) { - if(source_p->localClient->targets[i] == hashv) - return 1; + for(j = i; j > 0; j--) + targets[j] = targets[j - 1]; + targets[0] = hashv; + return 1; } + } + if(source_p->localClient->targets_free < TGCHANGE_NUM) + { /* first message after connect, we may only start clearing * slots after this message --anfl */ @@ -707,15 +709,15 @@ add_target(struct Client *source_p, struct Client *target_p) /* clear as many targets as we can */ else if((i = (rb_current_time() - source_p->localClient->target_last) / 60)) { - if(i > USED_TARGETS(source_p)) - USED_TARGETS(source_p) = 0; + if(i + source_p->localClient->targets_free > TGCHANGE_NUM) + source_p->localClient->targets_free = TGCHANGE_NUM; else - USED_TARGETS(source_p) -= i; + source_p->localClient->targets_free += i; source_p->localClient->target_last = rb_current_time(); } /* cant clear any, full target list */ - else if(USED_TARGETS(source_p) == TGCHANGE_NUM) + else if(source_p->localClient->targets_free == 0) { ServerStats.is_tgch++; add_tgchange(source_p->sockhost); @@ -731,9 +733,10 @@ add_target(struct Client *source_p, struct Client *target_p) SetTGChange(source_p); } - source_p->localClient->targets[FREE_TARGET(source_p)] = hashv; - NEXT_TARGET(FREE_TARGET(source_p)); - ++USED_TARGETS(source_p); + for(i = TGCHANGE_NUM - 1; i > 0; i--) + targets[i] = targets[i - 1]; + targets[0] = hashv; + source_p->localClient->targets_free--; return 1; } diff --git a/src/s_user.c b/src/s_user.c index b774e90..d8be934 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -561,7 +561,9 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char /* they get a reduced limit */ if(find_tgchange(source_p->sockhost)) - USED_TARGETS(source_p) = 6; + source_p->localClient->targets_free = TGCHANGE_INITIAL_LOW; + else + source_p->localClient->targets_free = TGCHANGE_INITIAL; monitor_signon(source_p); user_welcome(source_p);