ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 1633
Committed: Sun Nov 4 15:51:30 2012 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 10341 byte(s)
Log Message:
- Add conf_class.c, conf_class.h

File Contents

# User Rev Content
1 michael 1633 /*
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: conf_class.c,v 1.54 2007/10/21 21:57:05 devil Exp $
25     */
26    
27     #include "stdinc.h"
28     #include "list.h"
29     #include "ircd_defs.h"
30     #include "balloc.h"
31     #include "conf.h"
32     #include "s_serv.h"
33     #include "resv.h"
34     #include "channel.h"
35     #include "client.h"
36     #include "event.h"
37     #include "hook.h"
38     #include "irc_string.h"
39     #include "s_bsd.h"
40     #include "ircd.h"
41     #include "listener.h"
42     #include "hostmask.h"
43     #include "modules.h"
44     #include "numeric.h"
45     #include "fdlist.h"
46     #include "log.h"
47     #include "send.h"
48     #include "s_gline.h"
49     #include "memory.h"
50     #include "irc_res.h"
51     #include "userhost.h"
52     #include "s_user.h"
53     #include "channel_mode.h"
54     #include "parse.h"
55     #include "s_misc.h"
56     #include "conf_db.h"
57    
58    
59     struct ClassItem *class_default;
60    
61     static dlink_list class_list = { NULL, NULL, 0 };
62    
63    
64     const dlink_list *
65     class_get_list(void)
66     {
67     return &class_list;
68     }
69    
70     struct ClassItem *
71     class_make(void)
72     {
73     struct ClassItem *class = MyMalloc(sizeof(*class));
74    
75     dlinkAdd(class, &class->node, &class_list);
76    
77     return class;
78     }
79    
80     void
81     class_free(struct ClassItem *class)
82     {
83     assert(class);
84     assert(class->active == 0);
85     assert(class->ref_count == 0);
86    
87     dlinkDelete(&class->node, &class_list);
88     MyFree(class->name);
89     MyFree(class);
90     }
91    
92     void
93     class_init(void)
94     {
95     class_default = class_make();
96    
97     class_default->active = 1;
98     DupString(class_default->name, "default");
99     class_default->con_freq = DEFAULT_CONNECTFREQUENCY;
100     class_default->ping_freq = DEFAULT_PINGFREQUENCY;
101     class_default->max_total = MAXIMUM_LINKS_DEFAULT;
102     class_default->max_sendq = DEFAULT_SENDQ;
103     class_default->max_recvq = DEFAULT_RECVQ;
104    
105     client_check_cb = register_callback("check_client", check_client);
106     }
107    
108     const char *
109     get_client_class(const dlink_list *const list)
110     {
111     const dlink_node *ptr = NULL;
112    
113     if ((ptr = list->head)) {
114     const struct MaskItem *conf = ptr->data;
115    
116     assert(conf->class);
117     assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
118    
119     return conf->class->name;
120     }
121    
122     return class_default->name;
123     }
124    
125     unsigned int
126     get_client_ping(const dlink_list *const list, int *pingwarn)
127     {
128     const dlink_node *ptr = NULL;
129     int ping = 0;
130    
131     if ((ptr = list->head)) {
132     const struct MaskItem *conf = ptr->data;
133    
134     assert(aconf->class);
135     assert(aconf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
136    
137     ping = get_conf_ping(conf, pingwarn);
138     if (ping > 0)
139     return ping;
140     }
141    
142     return class_default->ping_freq;
143     }
144    
145     unsigned int
146     get_sendq(const dlink_list *const list)
147     {
148     const dlink_node *ptr = NULL;
149    
150     if ((ptr = list->head)) {
151     const struct MaskItem *conf = ptr->data;
152    
153     assert(conf->class);
154     assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
155    
156     return conf->class->max_sendq;
157     }
158    
159     return class_default->max_sendq;
160     }
161    
162     unsigned int
163     get_recvq(const dlink_list *const list)
164     {
165     const dlink_node *ptr = NULL;
166    
167     if ((ptr = list->head)) {
168     const struct MaskItem *conf = ptr->data;
169    
170     assert(conf->class);
171     assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
172    
173     return conf->class->max_recvq;
174     }
175    
176     return class_default->max_recvq;
177     }
178    
179     /*
180     * inputs - Integer (Number of class)
181     * output - Pointer to ClassItem struct. Non-NULL expected
182     * side effects - NONE
183     */
184     struct ClassItem *
185     class_find(const char *name, int active)
186     {
187     dlink_node *ptr = NULL;
188    
189     DLINK_FOREACH(ptr, class_list.head) {
190     struct ClassItem *class = ptr->data;
191    
192     if (!irccmp(class->name, name))
193     return active && !class->active ? NULL : class;
194     }
195    
196     return NULL;
197     }
198    
199     /*
200     * We don't delete the class table, rather mark all entries for deletion.
201     * The table is cleaned up by delete_marked_classes. - avalon
202     */
203     void
204     class_mark_for_deletion(void)
205     {
206     dlink_node *ptr = NULL;
207    
208     DLINK_FOREACH(ptr, class_list.head)
209     {
210     struct ClassItem *class = ptr->data;
211    
212     if (class != class_default)
213     class->active = 0;
214     }
215     }
216    
217     void
218     class_delete_marked(void)
219     {
220     dlink_node *ptr = NULL, *ptr_next = NULL;
221    
222     DLINK_FOREACH_SAFE(ptr, ptr_next, class_list.head) {
223     struct ClassItem *class = ptr->data;
224    
225     if (!class->active && !class->ref_count)
226     {
227     destroy_cidr_class(class);
228     class_free(class);
229     }
230     }
231     }
232    
233     /*
234     * cidr_limit_reached
235     *
236     * inputs - int flag allowing over_rule of limits
237     * - pointer to the ip to be added
238     * - pointer to the class
239     * output - non zero if limit reached
240     * 0 if limit not reached
241     * side effects -
242     */
243     int
244     cidr_limit_reached(int over_rule,
245     struct irc_ssaddr *ip, struct ClassItem *class)
246     {
247     dlink_node *ptr = NULL;
248     struct CidrItem *cidr = NULL;
249    
250     if (class->number_per_cidr <= 0)
251     return 0;
252    
253     if (ip->ss.ss_family == AF_INET)
254     {
255     if (class->cidr_bitlen_ipv4 <= 0)
256     return 0;
257    
258     DLINK_FOREACH(ptr, class->list_ipv4.head)
259     {
260     cidr = ptr->data;
261     if (match_ipv4(ip, &cidr->mask, class->cidr_bitlen_ipv4))
262     {
263     if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
264     return -1;
265     cidr->number_on_this_cidr++;
266     return 0;
267     }
268     }
269     cidr = MyMalloc(sizeof(struct CidrItem));
270     cidr->number_on_this_cidr = 1;
271     cidr->mask = *ip;
272     mask_addr(&cidr->mask, class->cidr_bitlen_ipv4);
273     dlinkAdd(cidr, &cidr->node, &class->list_ipv4);
274     }
275     #ifdef IPV6
276     else if (class->cidr_bitlen_ipv6 > 0)
277     {
278     DLINK_FOREACH(ptr, class->list_ipv6.head)
279     {
280     cidr = ptr->data;
281     if (match_ipv6(ip, &cidr->mask, class->cidr_bitlen_ipv6))
282     {
283     if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
284     return -1;
285     cidr->number_on_this_cidr++;
286     return 0;
287     }
288     }
289     cidr = MyMalloc(sizeof(struct CidrItem));
290     cidr->number_on_this_cidr = 1;
291     cidr->mask = *ip;
292     mask_addr(&cidr->mask, class->cidr_bitlen_ipv6);
293     dlinkAdd(cidr, &cidr->node, &class->list_ipv6);
294     }
295     #endif
296     return 0;
297     }
298    
299     /*
300     * remove_from_cidr_check
301     *
302     * inputs - pointer to the ip to be removed
303     * - pointer to the class
304     * output - NONE
305     * side effects -
306     */
307     void
308     remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
309     {
310     dlink_node *ptr = NULL;
311     dlink_node *next_ptr = NULL;
312     struct CidrItem *cidr;
313    
314     if (aclass->number_per_cidr == 0)
315     return;
316    
317     if (ip->ss.ss_family == AF_INET)
318     {
319     if (aclass->cidr_bitlen_ipv4 <= 0)
320     return;
321    
322     DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
323     {
324     cidr = ptr->data;
325     if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
326     {
327     cidr->number_on_this_cidr--;
328     if (cidr->number_on_this_cidr == 0)
329     {
330     dlinkDelete(ptr, &aclass->list_ipv4);
331     MyFree(cidr);
332     return;
333     }
334     }
335     }
336     }
337     #ifdef IPV6
338     else if (aclass->cidr_bitlen_ipv6 > 0)
339     {
340     DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
341     {
342     cidr = ptr->data;
343     if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
344     {
345     cidr->number_on_this_cidr--;
346     if (cidr->number_on_this_cidr == 0)
347     {
348     dlinkDelete(ptr, &aclass->list_ipv6);
349     MyFree(cidr);
350     return;
351     }
352     }
353     }
354     }
355     #endif
356     }
357    
358     static void
359     rebuild_cidr_list(int aftype, struct ClassItem *oldcl, struct ClassItem *newcl,
360     dlink_list *old_list, dlink_list *new_list, int changed)
361     {
362     dlink_node *ptr;
363     struct Client *client_p;
364     struct MaskItem *conf;
365    
366     if (!changed)
367     {
368     *new_list = *old_list;
369     old_list->head = old_list->tail = NULL;
370     old_list->length = 0;
371     return;
372     }
373    
374     DLINK_FOREACH(ptr, local_client_list.head)
375     {
376     client_p = ptr->data;
377     if (client_p->localClient->aftype != aftype)
378     continue;
379     if (dlink_list_length(&client_p->localClient->confs) == 0)
380     continue;
381    
382     conf = client_p->localClient->confs.tail->data;
383     if (conf->type == CONF_CLIENT)
384     if (conf->class == oldcl)
385     cidr_limit_reached(1, &client_p->localClient->ip, newcl);
386     }
387     }
388    
389     /*
390     * rebuild_cidr_class
391     *
392     * inputs - pointer to old conf
393     * - pointer to new_class
394     * output - none
395     * side effects - rebuilds the class link list of cidr blocks
396     */
397     void
398     rebuild_cidr_class(struct ClassItem *old_class, struct ClassItem *new_class)
399     {
400     if (old_class->number_per_cidr > 0 && new_class->number_per_cidr > 0)
401     {
402     if (old_class->cidr_bitlen_ipv4 > 0 && new_class->cidr_bitlen_ipv4 > 0)
403     rebuild_cidr_list(AF_INET, old_class, new_class,
404     &old_class->list_ipv4, &new_class->list_ipv4,
405     old_class->cidr_bitlen_ipv4 != new_class->cidr_bitlen_ipv4);
406    
407     #ifdef IPV6
408     if (old_class->cidr_bitlen_ipv6 > 0 && new_class->cidr_bitlen_ipv6 > 0)
409     rebuild_cidr_list(AF_INET6, old_class, new_class,
410     &old_class->list_ipv6, &new_class->list_ipv6,
411     old_class->cidr_bitlen_ipv6 != new_class->cidr_bitlen_ipv6);
412     #endif
413     }
414    
415     destroy_cidr_class(old_class);
416     }
417    
418     /*
419     * destroy_cidr_list
420     *
421     * inputs - pointer to class dlink list of cidr blocks
422     * output - none
423     * side effects - completely destroys the class link list of cidr blocks
424     */
425     static void
426     destroy_cidr_list(dlink_list *list)
427     {
428     dlink_node *ptr = NULL, *next_ptr = NULL;
429    
430     DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
431     {
432     dlinkDelete(ptr, list);
433     MyFree(ptr->data);
434     }
435     }
436    
437     /*
438     * destroy_cidr_class
439     *
440     * inputs - pointer to class
441     * output - none
442     * side effects - completely destroys the class link list of cidr blocks
443     */
444     void
445     destroy_cidr_class(struct ClassItem *class)
446     {
447     destroy_cidr_list(&class->list_ipv4);
448     destroy_cidr_list(&class->list_ipv6);
449     }

Properties

Name Value
svn:executable *