ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 1636
Committed: Sun Nov 4 17:09:47 2012 UTC (11 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 10293 byte(s)
Log Message:
- Cleanup configuration subsystem
- Fixed broken CIDR support for /challenge

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

Properties

Name Value
svn:executable *
svn:keywords Id