ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 1654
Committed: Fri Nov 16 19:39:37 2012 UTC (12 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 8657 byte(s)
Log Message:
- 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

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 "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 michael 1650 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 michael 1633 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 michael 1650 (class_default = class_make())->name = xstrdup("default");
102 michael 1633 }
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 michael 1654 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
114 michael 1633
115     return conf->class->name;
116     }
117    
118     return class_default->name;
119     }
120    
121     unsigned int
122 michael 1644 get_client_ping(const dlink_list *const list)
123 michael 1633 {
124     const dlink_node *ptr = NULL;
125    
126     if ((ptr = list->head)) {
127     const struct MaskItem *conf = ptr->data;
128    
129 michael 1654 assert(conf->class);
130     assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
131 michael 1633
132 michael 1644 return conf->class->ping_freq;
133 michael 1633 }
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 michael 1654 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
148 michael 1633
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 michael 1654 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
165 michael 1633
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 michael 1650 DLINK_FOREACH_PREV(ptr, class_list.tail->prev)
202     ((struct ClassItem *)ptr->data)->active = 0;
203 michael 1633 }
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 michael 1644 if (class->number_per_cidr == 0)
239 michael 1633 return 0;
240    
241     if (ip->ss.ss_family == AF_INET)
242     {
243 michael 1644 if (class->cidr_bitlen_ipv4 == 0)
244 michael 1633 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 michael 1644 if (aclass->cidr_bitlen_ipv4 == 0)
308 michael 1633 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 michael 1647 void
347     rebuild_cidr_list(struct ClassItem *class)
348 michael 1633 {
349     dlink_node *ptr;
350    
351 michael 1647 destroy_cidr_class(class);
352 michael 1633
353     DLINK_FOREACH(ptr, local_client_list.head)
354     {
355 michael 1647 struct Client *client_p = ptr->data;
356     struct MaskItem *conf = client_p->localClient->confs.tail->data;
357 michael 1633
358 michael 1647 if (conf && (conf->type == CONF_CLIENT))
359     if (conf->class == class)
360     cidr_limit_reached(1, &client_p->localClient->ip, class);
361 michael 1633 }
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