ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 1662
Committed: Sat Nov 17 20:11:33 2012 UTC (12 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 8230 byte(s)
Log Message:
- Fixed inconsistent svn file properties

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

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision