1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-10 01:03:12 +02:00

- Rework the client management code to use a circular queue and set of

circular queues for hashtable.
This commit is contained in:
William Pitcock
2012-11-21 22:49:32 +00:00
parent d2ef4a9b10
commit 9853fa54f4
21 changed files with 78 additions and 163 deletions
+1 -1
View File
@@ -47,7 +47,7 @@
#endif
#include "ircsprintf.h"
#include "list.h"
#ifdef DEVELOP_CVS
#define ID_Copyright(x) static char id_copyright[] = x
+2 -1
View File
@@ -38,7 +38,7 @@ extern char *getreply(int);
extern MODVAR Member *freemember;
extern MODVAR Membership *freemembership;
extern MODVAR MembershipL *freemembershipL;
extern MODVAR aClient *client, me, *local[];
extern MODVAR aClient me, *local[];
extern MODVAR aChannel *channel;
extern MODVAR struct stats *ircstp;
extern MODVAR int bootopt;
@@ -151,6 +151,7 @@ extern MODVAR int R_do_dns, R_fin_dns, R_fin_dnsc, R_fail_dns,
R_do_id, R_fin_id, R_fail_id;
#endif
extern struct list_head client_list;
extern inline aCommand *find_Command(char *cmd, short token, int flags);
extern aCommand *find_Command_simple(char *cmd);
extern aChannel *find_channel(char *, aChannel *);
+2 -1
View File
@@ -993,7 +993,8 @@ typedef struct {
#define SSLFLAG_NOSTARTTLS 0x8
struct Client {
struct Client *next, *prev, *hnext;
struct list_head client_list;
struct list_head client_hash;
anUser *user; /* ...defined, if this is a User */
aServer *serv; /* ...defined, if this is a server */
TS lastnick; /* TimeStamp on nick */
+20 -87
View File
@@ -30,7 +30,7 @@
ID_Copyright("(C) 1991 Darren Reed");
ID_Notes("2.10 7/3/93");
static aHashEntry clientTable[U_MAX];
static struct list_head clientTable[U_MAX];
static aHashEntry channelTable[CH_MAX];
/*
@@ -160,7 +160,10 @@ unsigned int hash_whowas_name(char *name)
*/
void clear_client_hash_table(void)
{
memset((char *)clientTable, '\0', sizeof(aHashEntry) * U_MAX);
int i;
for (i = 0; i < U_MAX; i++)
INIT_LIST_HEAD(&clientTable[i]);
}
void clear_channel_hash_table(void)
@@ -191,10 +194,7 @@ int add_to_client_hash_table(char *name, aClient *cptr)
if (loop.tainted)
return 0;
hashv = hash_nick_name(name);
cptr->hnext = (aClient *)clientTable[hashv].list;
clientTable[hashv].list = (void *)cptr;
clientTable[hashv].links++;
clientTable[hashv].hits++;
list_add(&cptr->client_hash, &clientTable[hashv]);
return 0;
}
/*
@@ -216,33 +216,13 @@ int add_to_channel_hash_table(char *name, aChannel *chptr)
*/
int del_from_client_hash_table(char *name, aClient *cptr)
{
aClient *tmp, *prev = NULL;
unsigned int hashv;
hashv = hash_nick_name(name);
for (tmp = (aClient *)clientTable[hashv].list; tmp; tmp = tmp->hnext)
if (!list_empty(&cptr->client_hash))
{
if (tmp == cptr)
{
if (prev)
prev->hnext = tmp->hnext;
else
clientTable[hashv].list = (void *)tmp->hnext;
tmp->hnext = NULL;
if (clientTable[hashv].links > 0)
{
clientTable[hashv].links--;
return 1;
}
else
/*
* Should never actually return from here and if we do it
* is an error/inconsistency in the hash table.
*/
return -1;
}
prev = tmp;
ircd_log(LOG_ERROR, "cptr->client_hash.next %p .prev %p",
cptr->client_hash.next, cptr->client_hash.prev);
list_del(&cptr->client_hash);
}
return 0;
}
/*
@@ -283,19 +263,15 @@ int del_from_channel_hash_table(char *name, aChannel *chptr)
aClient *hash_find_client(char *name, aClient *cptr)
{
aClient *tmp;
aHashEntry *tmp3;
unsigned int hashv;
hashv = hash_nick_name(name);
tmp3 = &clientTable[hashv];
/*
* Got the bucket, now search the chain.
*/
for (tmp = (aClient *)tmp3->list; tmp; tmp = tmp->hnext)
list_for_each_entry(tmp, &clientTable[hashv], client_hash)
{
if (smycmp(name, tmp->name) == 0)
{
return (tmp);
}
}
return (cptr);
/*
* If the member of the hashtable we found isnt at the top of its
@@ -318,24 +294,25 @@ aClient *hash_find_client(char *name, aClient *cptr)
aClient *hash_find_nickserver(char *name, aClient *cptr)
{
aClient *tmp;
aHashEntry *tmp3;
unsigned int hashv;
char *serv;
serv = (char *)strchr(name, '@');
*serv++ = '\0';
hashv = hash_nick_name(name);
tmp3 = &clientTable[hashv];
/*
* Got the bucket, now search the chain.
*/
for (tmp = (aClient *)tmp3->list; tmp; tmp = tmp->hnext)
list_for_each_entry(tmp, &clientTable[hashv], client_hash)
{
if (smycmp(name, tmp->name) == 0 && tmp->user &&
smycmp(serv, tmp->user->server) == 0)
{
*--serv = '\0';
return (tmp);
}
}
*--serv = '\0';
return (cptr);
@@ -346,18 +323,10 @@ aClient *hash_find_nickserver(char *name, aClient *cptr)
aClient *hash_find_server(char *server, aClient *cptr)
{
aClient *tmp;
#if 0
char *t;
char ch;
#endif
aHashEntry *tmp3;
unsigned int hashv;
hashv = hash_nick_name(server);
tmp3 = &clientTable[hashv];
for (tmp = (aClient *)tmp3->list; tmp; tmp = tmp->hnext)
list_for_each_entry(tmp, &clientTable[hashv], client_hash)
{
if (!IsServer(tmp) && !IsMe(tmp))
continue;
@@ -367,42 +336,6 @@ aClient *hash_find_server(char *server, aClient *cptr)
}
}
/*
* Whats happening in this next loop ? Well, it takes a name like
* foo.bar.edu and proceeds to earch for *.edu and then *.bar.edu.
* This is for checking full server names against masks although it
* isnt often done this way in lieu of using matches().
*/
/* why in god's name would we ever want to do something like this?
* commented out, probably to be removed sooner or later - lucas
*/
#if 0
t = ((char *)server + strlen(server));
for (;;)
{
t--;
for (; t > server; t--)
if (*(t + 1) == '.')
break;
if (*t == '*' || t == server)
break;
ch = *t;
*t = '*';
/*
* Dont need to check IsServer() here since nicknames cant have
* *'s in them anyway.
*/
if (((tmp = hash_find_client(t, cptr))) != cptr)
{
*t = ch;
return (tmp);
}
*t = ch;
}
#endif
return (cptr);
}
+1 -2
View File
@@ -104,7 +104,6 @@ char REPORT_DO_DNS[256], REPORT_FIN_DNS[256], REPORT_FIN_DNSC[256],
extern ircstats IRCstats;
aClient me; /* That's me */
MODVAR char *me_hash;
aClient *client = &me; /* Pointer to beginning of Client list */
extern char backupbuf[8192];
#ifdef _WIN32
extern void CleanUpSegv(int sig);
@@ -1493,7 +1492,6 @@ int InitwIRCD(int argc, char *argv[])
strlcpy(me.name, me.sockhost, sizeof(me.name));
me.hopcount = 0;
me.authfd = -1;
me.next = NULL;
me.user = NULL;
me.from = &me;
me.class = (ConfigItem_class *) conf_listen;
@@ -1504,6 +1502,7 @@ int InitwIRCD(int argc, char *argv[])
me_hash = find_or_add(me.name);
me.serv->up = me_hash;
me.serv->numeric = conf_me->numeric;
add_client_to_list(&me);
add_server_to_table(&me);
timeofday = time(NULL);
me.lasttime = me.since = me.firsttime = TStime();
+9 -23
View File
@@ -70,6 +70,7 @@ MODVAR Member *freemember = NULL;
MODVAR Membership *freemembership = NULL;
MODVAR MembershipL *freemembershipL = NULL;
MODVAR int numclients = 0;
MODVAR struct list_head client_list;
void initlists(void)
{
@@ -81,6 +82,8 @@ void initlists(void)
bzero((char *)&links, sizeof(links));
bzero((char *)&classs, sizeof(classs));
#endif
INIT_LIST_HEAD(&client_list);
}
void outofmemory(void)
@@ -125,14 +128,14 @@ aClient *make_client(aClient *from, aClient *servr)
/* Note: structure is zero (calloc) */
cptr->from = from ? from : cptr; /* 'from' of local client is self! */
cptr->next = NULL; /* For machines with NON-ZERO NULL pointers >;) */
cptr->prev = NULL;
cptr->hnext = NULL;
cptr->user = NULL;
cptr->serv = NULL;
cptr->srvptr = servr;
cptr->status = STAT_UNKNOWN;
INIT_LIST_HEAD(&cptr->client_list);
INIT_LIST_HEAD(&cptr->client_hash);
(void)strcpy(cptr->username, "unknown");
if (size == CLIENT_LOCAL_SIZE)
{
@@ -296,17 +299,8 @@ void remove_client_from_list(aClient *cptr)
#endif
)
IRCstats.unknown--;
list_del(&cptr->client_list);
checklist();
if (cptr->prev)
cptr->prev->next = cptr->next;
else
{
client = cptr->next;
if (client)
client->prev = NULL;
}
if (cptr->next)
cptr->next->prev = cptr->prev;
if (IsPerson(cptr)) /* Only persons can have been added before */
{
add_history(cptr, 0);
@@ -343,15 +337,7 @@ void remove_client_from_list(aClient *cptr)
*/
void add_client_to_list(aClient *cptr)
{
/*
* since we always insert new clients to the top of the list,
* this should mean the "me" is the bottom most item in the list.
*/
cptr->next = client;
client = cptr;
if (cptr->next)
cptr->next->prev = cptr;
return;
list_add(&cptr->client_list, &client_list);
}
/*
+4 -4
View File
@@ -94,7 +94,7 @@ ModuleHeader MOD_HEADER(m_sasl)
*/
static aClient *decode_puid(char *puid)
{
aClient *client;
aClient *cptr;
char *it, *it2;
unsigned int slot;
int cookie = 0;
@@ -118,12 +118,12 @@ static aClient *decode_puid(char *puid)
if (slot >= MAXCONNECTIONS)
return NULL;
client = local[slot];
cptr = local[slot];
if (cookie && client->sasl_cookie != cookie)
if (cookie && cptr->sasl_cookie != cookie)
return NULL;
return client;
return cptr;
}
/*
+3 -2
View File
@@ -830,7 +830,8 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
cptr->name, cptr->info);
}
}
for (acptr = &me; acptr; acptr = acptr->prev)
list_for_each_entry_reverse(acptr, &client_list, client_list)
{
/* acptr->from == acptr for acptr == cptr */
if (acptr->from == cptr)
@@ -880,7 +881,7 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
}
}
/* Synching nick information */
for (acptr = &me; acptr; acptr = acptr->prev)
list_for_each_entry_reverse(acptr, &client_list, client_list)
{
/* acptr->from == acptr for acptr == cptr */
if (acptr->from == cptr)
+3 -8
View File
@@ -106,15 +106,10 @@ CMD_FUNC(m_squit)
{
server = parv[1];
/*
** The following allows wild cards in SQUIT. Only usefull
** when the command is issued by an oper.
/* We used to allow wildcards here, but this wasn't really a good
* idea because it made the behaviour of SQUIT unpredictable. --nenolod
*/
for (acptr = client;
(acptr = next_client(acptr, server));
acptr = acptr->next)
if (IsServer(acptr) || IsMe(acptr))
break;
acptr = find_client(server, NULL);
if (acptr && IsMe(acptr))
{
acptr = cptr;
+3 -3
View File
@@ -534,7 +534,7 @@ int stats_links(aClient *sptr, char *para)
link_p->leafmask, link_p->servername, link_p->leafdepth);
}
#ifdef DEBUGMODE
for (acptr = client; acptr; acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
if (MyConnect(acptr) && acptr->serv && !IsMe(acptr))
{
if (!acptr->serv->conf)
@@ -893,7 +893,7 @@ int stats_mem(aClient *sptr, char *para)
count_watch_memory(&wlh, &wlhm);
wwm = sizeof(aName) * NICKNAMEHISTORYLENGTH;
for (acptr = client; acptr; acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
{
if (MyConnect(acptr))
{
@@ -1647,7 +1647,7 @@ int stats_linkinfoint(aClient *sptr, char *para, int all)
#endif
}
#ifdef DEBUGMODE
for (acptr = client; acptr; acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
{
if (IsServer(acptr))
sendto_one(sptr, ":%s NOTICE %s :Server %s is %s",
+1 -1
View File
@@ -97,7 +97,7 @@ long oldumodes;
{
SVSNOOP = 1;
sendto_ops("This server has been placed in NOOP mode");
for (acptr = &me; acptr; acptr = acptr->prev)
list_for_each_entry(acptr, &client_list, client_list)
{
if (MyClient(acptr) && IsAnOper(acptr))
{
+1 -1
View File
@@ -1490,7 +1490,7 @@ char spamfilter_user[NICKLEN + USERLEN + HOSTLEN + REALLEN + 64]; /* n!u@h:r */
int matches = 0;
aClient *acptr;
for (acptr = client; acptr; acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
if (IsPerson(acptr))
{
spamfilter_build_user_string(spamfilter_user, acptr->name, acptr);
+2 -2
View File
@@ -128,7 +128,7 @@ DLLFUNC CMD_FUNC(m_trace)
{
aClient *ac2ptr;
ac2ptr = next_client(client, tname);
ac2ptr = find_client(tname, NULL);
sendto_one(sptr, rpl_str(RPL_TRACELINK), me.name, parv[0],
version, debugmode, tname, ac2ptr->from->name);
return 0;
@@ -148,7 +148,7 @@ DLLFUNC CMD_FUNC(m_trace)
if (doall) {
for (acptr = client; acptr; acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
#ifdef SHOW_INVISIBLE_LUSERS
if (IsPerson(acptr))
link_u[acptr->from->slot]++;
+1 -1
View File
@@ -660,7 +660,7 @@ int oper = IsAnOper(sptr);
aClient *acptr;
who_flags |= WF_WILDCARD;
for (acptr = client; acptr; acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
{
int cansee;
char status[20];
+2 -2
View File
@@ -172,8 +172,8 @@ int w_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
if (wilds)
continue;
for (acptr = client; (acptr = next_client(acptr, nick));
acptr = acptr->next)
acptr = find_client(nick, NULL);
{
if (IsServer(acptr))
continue;
+1 -1
View File
@@ -116,7 +116,7 @@ aClient inline *find_name(char *name, aClient *cptr)
return (c2ptr);
if (!index(name, '*'))
return c2ptr;
for (c2ptr = client; c2ptr; c2ptr = c2ptr->next)
list_for_each_entry(c2ptr, &client_list, client_list)
{
if (!IsServer(c2ptr) && !IsMe(c2ptr))
continue;
+3 -5
View File
@@ -633,9 +633,8 @@ int exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment)
/*
* First, remove the clients on the server itself.
*/
for (acptr = client; acptr; acptr = next)
list_for_each_entry_safe(acptr, next, &client_list, client_list)
{
next = acptr->next;
if (IsClient(acptr) && (acptr->srvptr == sptr))
exit_one_client(NULL, acptr,
&me, comment1, 1);
@@ -646,9 +645,8 @@ int exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment)
* the one we just lost.
*/
recurse++;
for (acptr = client; acptr; acptr = next)
list_for_each_entry_safe(acptr, next, &client_list, client_list)
{
next = acptr->next;
if (IsServer(acptr) && acptr->srvptr == sptr)
exit_client(sptr, acptr, sptr, comment1); /* RECURSION */
/*
@@ -853,7 +851,7 @@ int counted = 0;
aClient *acptr;
char text[2048];
for (acptr = client; acptr; acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
{
if (IsOper(acptr) && !IsHideOper(acptr))
counted++;
+5 -1
View File
@@ -1275,7 +1275,10 @@ aClient *find_match_server(char *mask)
if (BadPtr(mask))
return NULL;
for (acptr = client, collapse(mask); acptr; acptr = acptr->next)
collapse(mask);
list_for_each_entry(acptr, &client_list, client_list)
{
if (!IsServer(acptr) && !IsMe(acptr))
continue;
@@ -1283,6 +1286,7 @@ aClient *find_match_server(char *mask)
break;
continue;
}
return acptr;
}
+8 -11
View File
@@ -206,15 +206,18 @@ aClient *next_client(aClient *next, char *ch)
aClient *tmp = next;
next = find_client(ch, tmp);
if (tmp && tmp->prev == next)
if (tmp && list_empty(&next->client_list))
return NULL;
if (next != tmp)
return next;
for (; next; next = next->next)
tmp = next;
list_for_each_entry(next, &next->client_list, client_list)
{
if (!match(ch, next->name) || !match(next->name, ch))
break;
}
return next;
}
@@ -262,9 +265,7 @@ int hunt_server(aClient *cptr, aClient *sptr, char *command, int server, int pa
if (acptr->from == sptr->from && !MyConnect(acptr))
acptr = NULL;
if (!acptr)
for (acptr = client, (void)collapse(parv[server]);
(acptr = next_client(acptr, parv[server]));
acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
{
if (acptr->from == sptr->from && !MyConnect(acptr))
continue;
@@ -341,9 +342,7 @@ int hunt_server_token(aClient *cptr, aClient *sptr, char *command, char *token,
if (acptr->from == sptr->from && !MyConnect(acptr))
acptr = NULL;
if (!acptr)
for (acptr = client, (void)collapse(parv[server]);
(acptr = next_client(acptr, parv[server]));
acptr = acptr->next)
list_for_each_entry(acptr, &acptr->client_list, client_list)
{
if (acptr->from == sptr->from && !MyConnect(acptr))
continue;
@@ -407,9 +406,7 @@ int hunt_server_token_quiet(aClient *cptr, aClient *sptr, char *command, char *
if (acptr->from == sptr->from && !MyConnect(acptr))
acptr = NULL;
if (!acptr)
for (acptr = client, (void)collapse(parv[server]);
(acptr = next_client(acptr, parv[server]));
acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
{
if (acptr->from == sptr->from && !MyConnect(acptr))
continue;
+4 -4
View File
@@ -1321,7 +1321,7 @@ void sendto_match_butone(aClient *one, aClient *from, char *mask, int what,
{
if (!cansendglobal)
continue;
for (acptr = client; acptr; acptr = acptr->next)
list_for_each_entry(acptr, &client_list, client_list)
if (IsRegisteredUser(acptr)
&& match_it(acptr, mask, what)
&& acptr->from == cptr)
@@ -1676,7 +1676,7 @@ void sendto_ops_butone(aClient *one, aClient *from, char *pattern, ...)
va_start(vl, pattern);
++sentalong_marker;
for (cptr = client; cptr; cptr = cptr->next)
list_for_each_entry(cptr, &client_list, client_list)
{
if (!SendWallops(cptr))
continue;
@@ -1710,7 +1710,7 @@ void sendto_opers_butone(aClient *one, aClient *from, char *pattern, ...)
va_start(vl, pattern);
++sentalong_marker;
for (cptr = client; cptr; cptr = cptr->next)
list_for_each_entry(cptr, &client_list, client_list)
{
if (!IsAnOper(cptr))
continue;
@@ -1741,7 +1741,7 @@ void sendto_ops_butme(aClient *from, char *pattern, ...)
va_start(vl, pattern);
++sentalong_marker;
for (cptr = client; cptr; cptr = cptr->next)
list_for_each_entry(cptr, &client_list, client_list)
{
if (!SendWallops(cptr))
continue;
+2 -2
View File
@@ -262,7 +262,7 @@ void UmodeDel(Umode *umode)
else
{
aClient *cptr;
for (cptr = client; cptr; cptr = cptr->next)
list_for_each_entry(cptr, &client_list, client_list)
{
long oldumode = 0;
if (!IsPerson(cptr))
@@ -410,7 +410,7 @@ void unload_all_unused_umodes()
}
if (!removed_umode) /* Nothing was unloaded */
return;
for (cptr = client; cptr; cptr = cptr->next)
list_for_each_entry(cptr, &client_list, client_list)
{
long oldumode = 0;
if (!IsPerson(cptr))