ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 1650
Committed: Sat Nov 10 20:57:51 2012 UTC (12 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 8695 byte(s)
Log Message:
- Fixed few bugs that have been introduced with config rewrite
- Set some reasonable default values right after a class has been created

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

Properties

Name Value
svn:executable *
svn:keywords Id