/[svn]/ircd-hybrid/trunk/src/conf_class.c
ViewVC logotype

Contents of /ircd-hybrid/trunk/src/conf_class.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1654 - (show annotations)
Fri Nov 16 19:39:37 2012 UTC (7 years, 7 months ago) by michael
File MIME type: text/x-chdr
File size: 8657 byte(s)
- Implemented memory pool allocator which basically is taken from Tor's
  mempool allocator for Tor cells
- Fixed compile warnings in conf_class.c
- ./configure --enable-assert works again

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 *
4 * Copyright (C) 2002 by the past and present ircd coders, and others.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22 /*! \file
23 * \brief Configuration managment for class{} blocks
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "ircd_defs.h"
30 #include "conf.h"
31 #include "s_serv.h"
32 #include "resv.h"
33 #include "channel.h"
34 #include "client.h"
35 #include "event.h"
36 #include "hook.h"
37 #include "irc_string.h"
38 #include "s_bsd.h"
39 #include "ircd.h"
40 #include "listener.h"
41 #include "hostmask.h"
42 #include "modules.h"
43 #include "numeric.h"
44 #include "fdlist.h"
45 #include "log.h"
46 #include "send.h"
47 #include "s_gline.h"
48 #include "memory.h"
49 #include "irc_res.h"
50 #include "userhost.h"
51 #include "s_user.h"
52 #include "channel_mode.h"
53 #include "parse.h"
54 #include "s_misc.h"
55 #include "conf_db.h"
56
57
58 struct ClassItem *class_default;
59
60 static dlink_list class_list = { NULL, NULL, 0 };
61
62
63 const dlink_list *
64 class_get_list(void)
65 {
66 return &class_list;
67 }
68
69 struct ClassItem *
70 class_make(void)
71 {
72 struct ClassItem *class = MyMalloc(sizeof(*class));
73
74 class->active = 1;
75 class->con_freq = DEFAULT_CONNECTFREQUENCY;
76 class->ping_freq = DEFAULT_PINGFREQUENCY;
77 class->max_total = MAXIMUM_LINKS_DEFAULT;
78 class->max_sendq = DEFAULT_SENDQ;
79 class->max_recvq = DEFAULT_RECVQ;
80
81 dlinkAdd(class, &class->node, &class_list);
82
83 return class;
84 }
85
86 void
87 class_free(struct ClassItem *class)
88 {
89 assert(class);
90 assert(class->active == 0);
91 assert(class->ref_count == 0);
92
93 dlinkDelete(&class->node, &class_list);
94 MyFree(class->name);
95 MyFree(class);
96 }
97
98 void
99 class_init(void)
100 {
101 (class_default = class_make())->name = xstrdup("default");
102 }
103
104 const char *
105 get_client_class(const dlink_list *const list)
106 {
107 const dlink_node *ptr = NULL;
108
109 if ((ptr = list->head)) {
110 const struct MaskItem *conf = ptr->data;
111
112 assert(conf->class);
113 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
114
115 return conf->class->name;
116 }
117
118 return class_default->name;
119 }
120
121 unsigned int
122 get_client_ping(const dlink_list *const list)
123 {
124 const dlink_node *ptr = NULL;
125
126 if ((ptr = list->head)) {
127 const struct MaskItem *conf = ptr->data;
128
129 assert(conf->class);
130 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
131
132 return conf->class->ping_freq;
133 }
134
135 return class_default->ping_freq;
136 }
137
138 unsigned int
139 get_sendq(const dlink_list *const list)
140 {
141 const dlink_node *ptr = NULL;
142
143 if ((ptr = list->head)) {
144 const struct MaskItem *conf = ptr->data;
145
146 assert(conf->class);
147 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
148
149 return conf->class->max_sendq;
150 }
151
152 return class_default->max_sendq;
153 }
154
155 unsigned int
156 get_recvq(const dlink_list *const list)
157 {
158 const dlink_node *ptr = NULL;
159
160 if ((ptr = list->head)) {
161 const struct MaskItem *conf = ptr->data;
162
163 assert(conf->class);
164 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
165
166 return conf->class->max_recvq;
167 }
168
169 return class_default->max_recvq;
170 }
171
172 /*
173 * inputs - Integer (Number of class)
174 * output - Pointer to ClassItem struct. Non-NULL expected
175 * side effects - NONE
176 */
177 struct ClassItem *
178 class_find(const char *name, int active)
179 {
180 dlink_node *ptr = NULL;
181
182 DLINK_FOREACH(ptr, class_list.head) {
183 struct ClassItem *class = ptr->data;
184
185 if (!irccmp(class->name, name))
186 return active && !class->active ? NULL : class;
187 }
188
189 return NULL;
190 }
191
192 /*
193 * We don't delete the class table, rather mark all entries for deletion.
194 * The table is cleaned up by delete_marked_classes. - avalon
195 */
196 void
197 class_mark_for_deletion(void)
198 {
199 dlink_node *ptr = NULL;
200
201 DLINK_FOREACH_PREV(ptr, class_list.tail->prev)
202 ((struct ClassItem *)ptr->data)->active = 0;
203 }
204
205 void
206 class_delete_marked(void)
207 {
208 dlink_node *ptr = NULL, *ptr_next = NULL;
209
210 DLINK_FOREACH_SAFE(ptr, ptr_next, class_list.head) {
211 struct ClassItem *class = ptr->data;
212
213 if (!class->active && !class->ref_count)
214 {
215 destroy_cidr_class(class);
216 class_free(class);
217 }
218 }
219 }
220
221 /*
222 * cidr_limit_reached
223 *
224 * inputs - int flag allowing over_rule of limits
225 * - pointer to the ip to be added
226 * - pointer to the class
227 * output - non zero if limit reached
228 * 0 if limit not reached
229 * side effects -
230 */
231 int
232 cidr_limit_reached(int over_rule,
233 struct irc_ssaddr *ip, struct ClassItem *class)
234 {
235 dlink_node *ptr = NULL;
236 struct CidrItem *cidr = NULL;
237
238 if (class->number_per_cidr == 0)
239 return 0;
240
241 if (ip->ss.ss_family == AF_INET)
242 {
243 if (class->cidr_bitlen_ipv4 == 0)
244 return 0;
245
246 DLINK_FOREACH(ptr, class->list_ipv4.head)
247 {
248 cidr = ptr->data;
249 if (match_ipv4(ip, &cidr->mask, class->cidr_bitlen_ipv4))
250 {
251 if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
252 return -1;
253 cidr->number_on_this_cidr++;
254 return 0;
255 }
256 }
257 cidr = MyMalloc(sizeof(struct CidrItem));
258 cidr->number_on_this_cidr = 1;
259 cidr->mask = *ip;
260 mask_addr(&cidr->mask, class->cidr_bitlen_ipv4);
261 dlinkAdd(cidr, &cidr->node, &class->list_ipv4);
262 }
263 #ifdef IPV6
264 else if (class->cidr_bitlen_ipv6 > 0)
265 {
266 DLINK_FOREACH(ptr, class->list_ipv6.head)
267 {
268 cidr = ptr->data;
269 if (match_ipv6(ip, &cidr->mask, class->cidr_bitlen_ipv6))
270 {
271 if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
272 return -1;
273 cidr->number_on_this_cidr++;
274 return 0;
275 }
276 }
277 cidr = MyMalloc(sizeof(struct CidrItem));
278 cidr->number_on_this_cidr = 1;
279 cidr->mask = *ip;
280 mask_addr(&cidr->mask, class->cidr_bitlen_ipv6);
281 dlinkAdd(cidr, &cidr->node, &class->list_ipv6);
282 }
283 #endif
284 return 0;
285 }
286
287 /*
288 * remove_from_cidr_check
289 *
290 * inputs - pointer to the ip to be removed
291 * - pointer to the class
292 * output - NONE
293 * side effects -
294 */
295 void
296 remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
297 {
298 dlink_node *ptr = NULL;
299 dlink_node *next_ptr = NULL;
300 struct CidrItem *cidr;
301
302 if (aclass->number_per_cidr == 0)
303 return;
304
305 if (ip->ss.ss_family == AF_INET)
306 {
307 if (aclass->cidr_bitlen_ipv4 == 0)
308 return;
309
310 DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
311 {
312 cidr = ptr->data;
313 if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
314 {
315 cidr->number_on_this_cidr--;
316 if (cidr->number_on_this_cidr == 0)
317 {
318 dlinkDelete(ptr, &aclass->list_ipv4);
319 MyFree(cidr);
320 return;
321 }
322 }
323 }
324 }
325 #ifdef IPV6
326 else if (aclass->cidr_bitlen_ipv6 > 0)
327 {
328 DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
329 {
330 cidr = ptr->data;
331 if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
332 {
333 cidr->number_on_this_cidr--;
334 if (cidr->number_on_this_cidr == 0)
335 {
336 dlinkDelete(ptr, &aclass->list_ipv6);
337 MyFree(cidr);
338 return;
339 }
340 }
341 }
342 }
343 #endif
344 }
345
346 void
347 rebuild_cidr_list(struct ClassItem *class)
348 {
349 dlink_node *ptr;
350
351 destroy_cidr_class(class);
352
353 DLINK_FOREACH(ptr, local_client_list.head)
354 {
355 struct Client *client_p = ptr->data;
356 struct MaskItem *conf = client_p->localClient->confs.tail->data;
357
358 if (conf && (conf->type == CONF_CLIENT))
359 if (conf->class == class)
360 cidr_limit_reached(1, &client_p->localClient->ip, class);
361 }
362 }
363
364 /*
365 * destroy_cidr_list
366 *
367 * inputs - pointer to class dlink list of cidr blocks
368 * output - none
369 * side effects - completely destroys the class link list of cidr blocks
370 */
371 static void
372 destroy_cidr_list(dlink_list *list)
373 {
374 dlink_node *ptr = NULL, *next_ptr = NULL;
375
376 DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
377 {
378 dlinkDelete(ptr, list);
379 MyFree(ptr->data);
380 }
381 }
382
383 /*
384 * destroy_cidr_class
385 *
386 * inputs - pointer to class
387 * output - none
388 * side effects - completely destroys the class link list of cidr blocks
389 */
390 void
391 destroy_cidr_class(struct ClassItem *class)
392 {
393 destroy_cidr_list(&class->list_ipv4);
394 destroy_cidr_list(&class->list_ipv6);
395 }

Properties

Name Value
svn:executable *
svn:keywords Id

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28