*/
#include "list.h"
-#include "class.h"
#include "client.h"
#include "ircd.h"
#include "ircd_alloc.h"
+#include "ircd_reply.h"
#include "ircd_string.h"
#include "listener.h"
#include "match.h"
#ifdef DEBUGMODE
static struct liststats {
int inuse;
-} cloc, crem, users, servs, links, classs;
+} cloc, crem, users, servs, links;
#endif
+static unsigned int localClientAllocCount;
+static struct Client* localClientFreeList;
+
+static unsigned int remoteClientAllocCount;
+static struct Client* remoteClientFreeList;
+
+static unsigned int slinkAllocCount;
+static struct SLink* slinkFreeList;
+
void init_list(void)
{
+ struct Client* cptr;
+ int i;
+ /*
+ * pre-allocate MAXCONNECTIONS local clients
+ */
+ for (i = 0; i < MAXCONNECTIONS; ++i) {
+ cptr = (struct Client*) MyMalloc(CLIENT_LOCAL_SIZE);
+ cli_next(cptr) = localClientFreeList;
+ localClientFreeList = cptr;
+ ++localClientAllocCount;
+ }
+
#ifdef DEBUGMODE
memset(&cloc, 0, sizeof(cloc));
memset(&crem, 0, sizeof(crem));
memset(&users, 0, sizeof(users));
memset(&servs, 0, sizeof(servs));
memset(&links, 0, sizeof(links));
- memset(&classs, 0, sizeof(classs));
#endif
}
*/
struct Client* make_client(struct Client *from, int status)
{
- struct Client *cptr = NULL;
- size_t size = CLIENT_REMOTE_SIZE;
-
+ struct Client* cptr = 0;
/*
* Check freelists first to see if we can grab a client without
* having to call malloc.
*/
- if (!from)
- size = CLIENT_LOCAL_SIZE;
-
- cptr = (struct Client*) MyMalloc(size);
- assert(0 != cptr);
- /*
- * NOTE: Do not remove this, a lot of code depends on the entire
- * structure being zeroed out
- */
- memset(cptr, 0, size); /* All variables are 0 by default */
+ if (from) {
+ /*
+ * remote client
+ */
+ if ((cptr = remoteClientFreeList))
+ remoteClientFreeList = cli_next(cptr);
+ else {
+ cptr = (struct Client*) MyMalloc(CLIENT_REMOTE_SIZE);
+ ++remoteClientAllocCount;
+ }
+ assert(0 != cptr);
+ /*
+ * NOTE: Do not remove this, a lot of code depends on the entire
+ * structure being zeroed out
+ */
+ memset(cptr, 0, CLIENT_REMOTE_SIZE); /* All variables are 0 by default */
+ cli_from(cptr) = from;
+ }
+ else {
+ /*
+ * local client
+ */
+ if ((cptr = localClientFreeList))
+ localClientFreeList = cli_next(cptr);
+ else {
+ cptr = (struct Client*) MyMalloc(CLIENT_LOCAL_SIZE);
+ ++localClientAllocCount;
+ }
+ assert(0 != cptr);
+ /*
+ * NOTE: Do not remove this, a lot of code depends on the entire
+ * structure being zeroed out
+ */
+ memset(cptr, 0, CLIENT_LOCAL_SIZE); /* All variables are 0 by default */
+ cli_fd(cptr) = -1;
+ cli_local(cptr) = 1;
+ cli_since(cptr) = cli_lasttime(cptr) = cli_firsttime(cptr) = CurrentTime;
+ cli_lastnick(cptr) = TStime();
+ cli_nextnick(cptr) = CurrentTime - NICK_DELAY;
+ cli_nexttarget(cptr) = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1));
+ cli_handler(cptr) = UNREGISTERED_HANDLER;
+ cli_from(cptr) = cptr; /* 'from' of local client is self! */
+ }
+ cli_status(cptr) = status;
+ cli_hnext(cptr) = cptr;
+ strcpy(cli_username(cptr), "unknown");
#ifdef DEBUGMODE
- if (size == CLIENT_LOCAL_SIZE)
- cloc.inuse++;
- else
+ if (from)
crem.inuse++;
+ else
+ cloc.inuse++;
#endif
- /* Note: structure is zero (memset) */
- cptr->from = from ? from : cptr; /* 'from' of local client is self! */
- cptr->status = status;
- cptr->hnext = cptr;
- strcpy(cptr->username, "unknown");
-
- if (CLIENT_LOCAL_SIZE == size) {
- cptr->fd = -1;
- cptr->local = 1;
- cptr->since = cptr->lasttime = cptr->firsttime = CurrentTime;
- cptr->lastnick = TStime();
- cptr->nextnick = CurrentTime - NICK_DELAY;
- cptr->nexttarget = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1));
- cptr->handler = UNREGISTERED_HANDLER;
- }
return cptr;
}
-void free_client(struct Client *cptr)
+void free_client(struct Client* cptr)
{
- if (cptr && cptr->local) {
- /*
- * make sure we have cleaned up local resources
- */
- if (cptr->dns_reply)
- --cptr->dns_reply->ref_count;
- if (-1 < cptr->fd)
- close(cptr->fd);
- DBufClear(&cptr->sendQ);
- DBufClear(&cptr->recvQ);
- if (cptr->listener)
- release_listener(cptr->listener);
- }
+ if (!cptr)
+ return;
/*
* forget to remove the client from the hash table?
*/
- assert(cptr->hnext == cptr);
+ assert(cli_hnext(cptr) == cptr);
+
+#ifdef DEBUGMODE
+ if (cli_local(cptr))
+ --cloc.inuse;
+ else
+ --crem.inuse;
+#endif
- MyFree(cptr);
+ if (cli_local(cptr)) {
+ /*
+ * make sure we have cleaned up local resources
+ */
+ if (cli_dns_reply(cptr))
+ --(cli_dns_reply(cptr))->ref_count;
+ if (-1 < cli_fd(cptr)) {
+ close(cli_fd(cptr));
+ }
+ MsgQClear(&(cli_sendQ(cptr)));
+ DBufClear(&(cli_recvQ(cptr)));
+ if (cli_listener(cptr))
+ release_listener(cli_listener(cptr));
+ cli_next(cptr) = localClientFreeList;
+ localClientFreeList = cptr;
+ }
+ else {
+ cli_next(cptr) = remoteClientFreeList;
+ remoteClientFreeList = cptr;
+ }
}
struct Server *make_server(struct Client *cptr)
{
- struct Server *serv = cptr->serv;
+ struct Server *serv = cli_serv(cptr);
if (!serv)
{
#ifdef DEBUGMODE
servs.inuse++;
#endif
- cptr->serv = serv;
+ cli_serv(cptr) = serv;
+ cli_serv(cptr)->lag = 60000;
*serv->by = '\0';
DupString(serv->last_error_msg, "<>"); /* String must be non-empty */
}
- return cptr->serv;
+ return cli_serv(cptr);
}
/*
*/
void remove_client_from_list(struct Client *cptr)
{
- if (cptr->prev)
- cptr->prev->next = cptr->next;
+ if (cli_prev(cptr))
+ cli_next(cli_prev(cptr)) = cli_next(cptr);
else {
- GlobalClientList = cptr->next;
- GlobalClientList->prev = 0;
+ GlobalClientList = cli_next(cptr);
+ cli_prev(GlobalClientList) = 0;
}
- if (cptr->next)
- cptr->next->prev = cptr->prev;
+ if (cli_next(cptr))
+ cli_prev(cli_next(cptr)) = cli_prev(cptr);
- cptr->next = cptr->prev = 0;
+ cli_next(cptr) = cli_prev(cptr) = 0;
- if (IsUser(cptr) && cptr->user) {
+ if (IsUser(cptr) && cli_user(cptr)) {
add_history(cptr, 0);
off_history(cptr);
}
- if (cptr->user) {
- free_user(cptr->user);
- cptr->user = 0;
+ if (cli_user(cptr)) {
+ free_user(cli_user(cptr));
+ cli_user(cptr) = 0;
}
- if (cptr->serv) {
- if (cptr->serv->user) {
- free_user(cptr->serv->user);
- cptr->serv->user = 0;
+ if (cli_serv(cptr)) {
+ if (cli_serv(cptr)->user) {
+ free_user(cli_serv(cptr)->user);
+ cli_serv(cptr)->user = 0;
}
- if (cptr->serv->client_list)
- MyFree(cptr->serv->client_list);
- MyFree(cptr->serv->last_error_msg);
- MyFree(cptr->serv);
+ if (cli_serv(cptr)->client_list)
+ MyFree(cli_serv(cptr)->client_list);
+ MyFree(cli_serv(cptr)->last_error_msg);
+ MyFree(cli_serv(cptr));
#ifdef DEBUGMODE
--servs.inuse;
#endif
}
-#ifdef DEBUGMODE
- if (cptr->local)
- --cloc.inuse;
- else
- --crem.inuse;
-#endif
free_client(cptr);
}
* this should mean the "me" is the bottom most item in the list.
* XXX - don't always count on the above, things change
*/
- cptr->prev = 0;
- cptr->next = GlobalClientList;
+ cli_prev(cptr) = 0;
+ cli_next(cptr) = GlobalClientList;
GlobalClientList = cptr;
- if (cptr->next)
- cptr->next->prev = cptr;
+ if (cli_next(cptr))
+ cli_prev(cli_next(cptr)) = cptr;
}
/*
*/
struct SLink *find_user_link(struct SLink *lp, struct Client *ptr)
{
- if (ptr)
- while (lp)
- {
+ if (ptr) {
+ while (lp) {
if (lp->value.cptr == ptr)
return (lp);
lp = lp->next;
}
+ }
return NULL;
}
-struct SLink *make_link(void)
+struct SLink* make_link(void)
{
- struct SLink *lp;
-
- lp = (struct SLink*) MyMalloc(sizeof(struct SLink));
+ struct SLink* lp = slinkFreeList;
+ if (lp)
+ slinkFreeList = lp->next;
+ else {
+ lp = (struct SLink*) MyMalloc(sizeof(struct SLink));
+ ++slinkAllocCount;
+ }
assert(0 != lp);
#ifdef DEBUGMODE
links.inuse++;
return lp;
}
-void free_link(struct SLink *lp)
+void free_link(struct SLink* lp)
{
- MyFree(lp);
+ if (lp) {
+ lp->next = slinkFreeList;
+ slinkFreeList = lp;
+ }
#ifdef DEBUGMODE
links.inuse--;
#endif
MyFree(lp);
}
-struct ConfClass *make_class(void)
-{
- struct ConfClass *tmp;
-
- tmp = (struct ConfClass*) MyMalloc(sizeof(struct ConfClass));
- assert(0 != tmp);
-#ifdef DEBUGMODE
- classs.inuse++;
-#endif
- return tmp;
-}
-
-void free_class(struct ConfClass * tmp)
-{
- MyFree(tmp);
-#ifdef DEBUGMODE
- classs.inuse--;
-#endif
-}
-
#ifdef DEBUGMODE
void send_listinfo(struct Client *cptr, char *name)
{
int inuse = 0, mem = 0, tmp = 0;
- sendto_one(cptr, ":%s %d %s :Local: inuse: %d(%d)",
- me.name, RPL_STATSDEBUG, name, inuse += cloc.inuse,
- tmp = cloc.inuse * CLIENT_LOCAL_SIZE);
+ send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Local: inuse: %d(%d)",
+ inuse += cloc.inuse, tmp = cloc.inuse * CLIENT_LOCAL_SIZE);
mem += tmp;
- sendto_one(cptr, ":%s %d %s :Remote: inuse: %d(%d)",
- me.name, RPL_STATSDEBUG, name,
- crem.inuse, tmp = crem.inuse * CLIENT_REMOTE_SIZE);
+ send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Remote: inuse: %d(%d)",
+ crem.inuse, tmp = crem.inuse * CLIENT_REMOTE_SIZE);
mem += tmp;
inuse += crem.inuse;
- sendto_one(cptr, ":%s %d %s :Users: inuse: %d(%d)",
- me.name, RPL_STATSDEBUG, name, users.inuse,
- tmp = users.inuse * sizeof(struct User));
- mem += tmp;
- inuse += users.inuse,
- sendto_one(cptr, ":%s %d %s :Servs: inuse: %d(%d)",
- me.name, RPL_STATSDEBUG, name, servs.inuse,
- tmp = servs.inuse * sizeof(struct Server));
+ send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Users: inuse: %d(%d)",
+ users.inuse, tmp = users.inuse * sizeof(struct User));
mem += tmp;
- inuse += servs.inuse,
- sendto_one(cptr, ":%s %d %s :Links: inuse: %d(%d)",
- me.name, RPL_STATSDEBUG, name, links.inuse,
- tmp = links.inuse * sizeof(struct SLink));
+ inuse += users.inuse;
+ send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Servs: inuse: %d(%d)",
+ servs.inuse, tmp = servs.inuse * sizeof(struct Server));
mem += tmp;
- inuse += links.inuse,
- sendto_one(cptr, ":%s %d %s :Classes: inuse: %d(%d)",
- me.name, RPL_STATSDEBUG, name, classs.inuse,
- tmp = classs.inuse * sizeof(struct ConfClass));
+ inuse += servs.inuse;
+ send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Links: inuse: %d(%d)",
+ links.inuse, tmp = links.inuse * sizeof(struct SLink));
mem += tmp;
- inuse += classs.inuse,
- sendto_one(cptr, ":%s %d %s :Confs: inuse: %d(%d)",
- me.name, RPL_STATSDEBUG, name, GlobalConfCount,
- tmp = GlobalConfCount * sizeof(struct ConfItem));
+ inuse += links.inuse;
+ send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Confs: inuse: %d(%d)",
+ GlobalConfCount, tmp = GlobalConfCount * sizeof(struct ConfItem));
mem += tmp;
- inuse += GlobalConfCount,
- sendto_one(cptr, ":%s %d %s :Totals: inuse %d %d",
- me.name, RPL_STATSDEBUG, name, inuse, mem);
+ inuse += GlobalConfCount;
+ send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Totals: inuse %d %d",
+ inuse, mem);
}
#endif