2 * IRC - Internet Relay Chat, ircd/class.c
3 * Copyright (C) 1990 Darren Reed
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 1, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "ircd_alloc.h"
25 #include "ircd_reply.h"
34 #define BAD_CONF_CLASS ((unsigned int)-1)
35 #define BAD_PING ((unsigned int)-2)
36 #define BAD_CLIENT_CLASS ((unsigned int)-3)
38 static struct ConnectionClass* connClassList;
39 static unsigned int connClassAllocCount;
41 const struct ConnectionClass* get_class_list(void)
46 struct ConnectionClass* make_class(void)
48 struct ConnectionClass *tmp;
50 tmp = (struct ConnectionClass*) MyMalloc(sizeof(struct ConnectionClass));
52 ++connClassAllocCount;
56 void free_class(struct ConnectionClass* tmp)
60 --connClassAllocCount;
65 * init_class - initialize the class list
69 connClassList = (struct ConnectionClass*) make_class();
71 ConClass(connClassList) = 0;
72 ConFreq(connClassList) = CONNECTFREQUENCY;
73 PingFreq(connClassList) = PINGFREQUENCY;
74 MaxLinks(connClassList) = MAXIMUM_LINKS;
75 MaxSendq(connClassList) = DEFAULTMAXSENDQLENGTH;
76 Links(connClassList) = 0;
77 connClassList->next = 0;
81 * class_mark_delete - mark classes for delete
82 * We don't delete the class table, rather mark all entries
83 * for deletion. The table is cleaned up by class_delete_marked(). - avalon
84 * XXX - This destroys data
86 void class_mark_delete(void)
88 struct ConnectionClass* p;
89 assert(0 != connClassList);
91 for (p = connClassList->next; p; p = p->next)
92 p->maxLinks = BAD_CONF_CLASS;
97 * delete classes marked for deletion
98 * XXX - memory leak, no one deletes classes that become unused
101 void class_delete_marked(void)
103 struct ConnectionClass* cl;
104 struct ConnectionClass* prev;
106 Debug((DEBUG_DEBUG, "Class check:"));
108 for (prev = cl = connClassList; cl; cl = prev->next) {
109 Debug((DEBUG_DEBUG, "Class %d : CF: %d PF: %d ML: %d LI: %d SQ: %d",
110 ConClass(cl), ConFreq(cl), PingFreq(cl), MaxLinks(cl), Links(cl), MaxSendq(cl)));
112 * unlink marked classes, delete unreferenced ones
114 if (BAD_CONF_CLASS == cl->maxLinks) {
115 prev->next = cl->next;
124 unsigned int get_conf_class(const struct ConfItem* aconf)
126 if ((aconf) && (aconf->confClass))
127 return (ConfClass(aconf));
129 Debug((DEBUG_DEBUG, "No Class For %s", (aconf) ? aconf->name : "*No Conf*"));
131 return (BAD_CONF_CLASS);
134 unsigned int get_conf_ping(const struct ConfItem *aconf)
136 if ((aconf) && (aconf->confClass))
137 return (ConfPingFreq(aconf));
139 Debug((DEBUG_DEBUG, "No Ping For %s", (aconf) ? aconf->name : "*No Conf*"));
144 unsigned int get_client_class(struct Client *acptr)
147 struct ConnectionClass *cl;
148 unsigned int retc = BAD_CLIENT_CLASS;
150 if (acptr && !IsMe(acptr) && (acptr->confs))
151 for (tmp = acptr->confs; tmp; tmp = tmp->next)
153 if (!tmp->value.aconf || !(cl = tmp->value.aconf->confClass))
155 if (ConClass(cl) > retc || retc == BAD_CLIENT_CLASS)
159 Debug((DEBUG_DEBUG, "Returning Class %d For %s", retc, acptr->name));
164 unsigned int get_client_ping(struct Client *acptr)
166 unsigned int ping = 0;
168 struct ConfItem *aconf;
175 aconf = link->value.aconf;
176 if (aconf->status & (CONF_CLIENT | CONF_SERVER)) {
177 ping2 = get_conf_ping(aconf);
178 if ((ping2 != BAD_PING) && ((ping > ping2) || !ping))
185 ping = PINGFREQUENCY;
186 Debug((DEBUG_DEBUG, "No Attached Confs for: %s", acptr->name));
189 ping = PINGFREQUENCY;
190 Debug((DEBUG_DEBUG, "Client %s Ping %d", acptr->name, ping));
194 unsigned int get_con_freq(struct ConnectionClass * clptr)
197 return (ConFreq(clptr));
199 return (CONNECTFREQUENCY);
203 * When adding a class, check to see if it is already present first.
204 * if so, then update the information for that class, rather than create
205 * a new entry for it and later delete the old entry.
206 * if no present entry is found, then create a new one and add it in
207 * immeadiately after the first one (class 0).
209 void add_class(unsigned int conClass, unsigned int ping, unsigned int confreq,
210 unsigned int maxli, unsigned int sendq)
212 struct ConnectionClass* t;
213 struct ConnectionClass* p;
215 t = find_class(conClass);
216 if ((t == connClassList) && (conClass != 0))
218 p = (struct ConnectionClass *) make_class();
224 Debug((DEBUG_DEBUG, "Add Class %u: cf: %u pf: %u ml: %u sq: %d",
225 conClass, confreq, ping, maxli, sendq));
226 ConClass(p) = conClass;
227 ConFreq(p) = confreq;
230 MaxSendq(p) = (sendq > 0) ? sendq : DEFAULTMAXSENDQLENGTH;
235 struct ConnectionClass* find_class(unsigned int cclass)
237 struct ConnectionClass *cltmp;
239 for (cltmp = connClassList; cltmp; cltmp = cltmp->next) {
240 if (ConClass(cltmp) == cclass)
243 return connClassList;
246 void report_classes(struct Client *sptr)
248 struct ConnectionClass *cltmp;
250 for (cltmp = connClassList; cltmp; cltmp = cltmp->next)
251 send_reply(sptr, RPL_STATSYLINE, 'Y', ConClass(cltmp), PingFreq(cltmp),
252 ConFreq(cltmp), MaxLinks(cltmp), MaxSendq(cltmp));
255 unsigned int get_sendq(struct Client *cptr)
258 assert(0 != cptr->local);
261 return cptr->max_sendq;
263 else if (cptr->confs) {
265 struct ConnectionClass* cl;
267 for (tmp = cptr->confs; tmp; tmp = tmp->next) {
268 if (!tmp->value.aconf || !(cl = tmp->value.aconf->confClass))
270 if (ConClass(cl) != BAD_CLIENT_CLASS) {
271 cptr->max_sendq = MaxSendq(cl);
272 return cptr->max_sendq;
276 return DEFAULTMAXSENDQLENGTH;
279 void class_send_meminfo(struct Client* cptr)
281 send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Classes: inuse: %d(%d)",
282 connClassAllocCount, connClassAllocCount * sizeof(struct ConnectionClass));