ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 5347
Committed: Sun Jan 11 12:42:20 2015 UTC (10 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 8700 byte(s)
Log Message:
- Update copyright years

File Contents

# User Rev Content
1 michael 1633 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 michael 1633 *
4 michael 5347 * Copyright (c) 1997-2015 ircd-hybrid development team
5 michael 1633 *
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 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 michael 1633 * USA
20     */
21    
22 michael 2916 /*! \file conf_class.c
23 michael 1633 * \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 michael 1658 #include "hostmask.h"
32 michael 1633 #include "irc_string.h"
33     #include "memory.h"
34    
35    
36     struct ClassItem *class_default;
37    
38 michael 3250 static dlink_list class_list;
39 michael 1633
40    
41     const dlink_list *
42     class_get_list(void)
43     {
44     return &class_list;
45     }
46    
47     struct ClassItem *
48     class_make(void)
49     {
50 michael 4833 struct ClassItem *const class = MyCalloc(sizeof(*class));
51 michael 1633
52 michael 1650 class->active = 1;
53     class->con_freq = DEFAULT_CONNECTFREQUENCY;
54     class->ping_freq = DEFAULT_PINGFREQUENCY;
55     class->max_total = MAXIMUM_LINKS_DEFAULT;
56     class->max_sendq = DEFAULT_SENDQ;
57     class->max_recvq = DEFAULT_RECVQ;
58    
59 michael 1633 dlinkAdd(class, &class->node, &class_list);
60    
61     return class;
62     }
63    
64     void
65 michael 4874 class_free(struct ClassItem *const class)
66 michael 1633 {
67 michael 3547 assert(class != class_default);
68 michael 1633 assert(class->active == 0);
69     assert(class->ref_count == 0);
70    
71     dlinkDelete(&class->node, &class_list);
72     MyFree(class->name);
73     MyFree(class);
74     }
75    
76     void
77     class_init(void)
78     {
79 michael 1650 (class_default = class_make())->name = xstrdup("default");
80 michael 1633 }
81    
82 michael 1783 struct ClassItem *
83     get_class_ptr(const dlink_list *const list)
84     {
85 michael 4848 const dlink_node *const node = list->head;
86 michael 1783
87 michael 4848 if (node)
88 michael 2213 {
89 michael 4833 const struct MaskItem *const conf = node->data;
90 michael 1783
91     assert(conf->class);
92     assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
93    
94     return conf->class;
95     }
96    
97     return class_default;
98     }
99    
100 michael 1633 const char *
101     get_client_class(const dlink_list *const list)
102     {
103 michael 4848 const dlink_node *const node = list->head;
104 michael 1633
105 michael 4848 if (node)
106 michael 2213 {
107 michael 4833 const struct MaskItem *const conf = node->data;
108 michael 1633
109     assert(conf->class);
110 michael 1654 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
111 michael 1633
112     return conf->class->name;
113     }
114    
115     return class_default->name;
116     }
117    
118     unsigned int
119 michael 1644 get_client_ping(const dlink_list *const list)
120 michael 1633 {
121 michael 4848 const dlink_node *const node = list->head;
122 michael 1633
123 michael 4848 if (node)
124 michael 2213 {
125 michael 4833 const struct MaskItem *const conf = node->data;
126 michael 1633
127 michael 1654 assert(conf->class);
128     assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
129 michael 1633
130 michael 1644 return conf->class->ping_freq;
131 michael 1633 }
132    
133     return class_default->ping_freq;
134     }
135    
136     unsigned int
137     get_sendq(const dlink_list *const list)
138     {
139 michael 4848 const dlink_node *const node = list->head;
140 michael 1633
141 michael 4848 if (node)
142 michael 2213 {
143 michael 4833 const struct MaskItem *const conf = node->data;
144 michael 1633
145     assert(conf->class);
146 michael 1654 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
147 michael 1633
148     return conf->class->max_sendq;
149     }
150    
151     return class_default->max_sendq;
152     }
153    
154     unsigned int
155     get_recvq(const dlink_list *const list)
156     {
157 michael 4848 const dlink_node *const node = list->head;
158 michael 1633
159 michael 4848 if (node)
160 michael 2213 {
161 michael 4833 const struct MaskItem *const conf = node->data;
162 michael 1633
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 michael 4800 dlink_node *node = NULL;
181 michael 1633
182 michael 4800 DLINK_FOREACH(node, class_list.head)
183 michael 2213 {
184 michael 4800 struct ClassItem *class = node->data;
185 michael 1633
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 michael 4800 dlink_node *node = NULL;
201 michael 1633
202 michael 4800 DLINK_FOREACH_PREV(node, class_list.tail->prev)
203     ((struct ClassItem *)node->data)->active = 0;
204 michael 1633 }
205    
206     void
207     class_delete_marked(void)
208     {
209 michael 4800 dlink_node *node = NULL, *node_next = NULL;
210 michael 1633
211 michael 4800 DLINK_FOREACH_SAFE(node, node_next, class_list.head)
212 michael 2213 {
213 michael 4800 struct ClassItem *class = node->data;
214 michael 1633
215     if (!class->active && !class->ref_count)
216     {
217     destroy_cidr_class(class);
218     class_free(class);
219     }
220     }
221     }
222    
223     /*
224     * cidr_limit_reached
225     *
226     * inputs - int flag allowing over_rule of limits
227     * - pointer to the ip to be added
228     * - pointer to the class
229     * output - non zero if limit reached
230     * 0 if limit not reached
231     * side effects -
232     */
233     int
234 michael 2213 cidr_limit_reached(int over_rule, struct irc_ssaddr *ip, struct ClassItem *class)
235 michael 1633 {
236 michael 4800 dlink_node *node = NULL;
237 michael 1633 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 michael 4800 DLINK_FOREACH(node, class->list_ipv4.head)
248 michael 1633 {
249 michael 4800 cidr = node->data;
250 michael 2213
251 michael 1633 if (match_ipv4(ip, &cidr->mask, class->cidr_bitlen_ipv4))
252     {
253     if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
254     return -1;
255 michael 2213
256 michael 1633 cidr->number_on_this_cidr++;
257     return 0;
258     }
259     }
260 michael 2213
261 michael 3504 cidr = MyCalloc(sizeof(struct CidrItem));
262 michael 1633 cidr->number_on_this_cidr = 1;
263     cidr->mask = *ip;
264     mask_addr(&cidr->mask, class->cidr_bitlen_ipv4);
265     dlinkAdd(cidr, &cidr->node, &class->list_ipv4);
266     }
267     else if (class->cidr_bitlen_ipv6 > 0)
268     {
269 michael 4800 DLINK_FOREACH(node, class->list_ipv6.head)
270 michael 1633 {
271 michael 4800 cidr = node->data;
272 michael 2213
273 michael 1633 if (match_ipv6(ip, &cidr->mask, class->cidr_bitlen_ipv6))
274     {
275     if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
276     return -1;
277 michael 2213
278 michael 1633 cidr->number_on_this_cidr++;
279     return 0;
280     }
281     }
282 michael 2213
283 michael 3504 cidr = MyCalloc(sizeof(struct CidrItem));
284 michael 1633 cidr->number_on_this_cidr = 1;
285     cidr->mask = *ip;
286     mask_addr(&cidr->mask, class->cidr_bitlen_ipv6);
287     dlinkAdd(cidr, &cidr->node, &class->list_ipv6);
288     }
289 michael 4415
290 michael 1633 return 0;
291     }
292    
293     /*
294     * remove_from_cidr_check
295     *
296     * inputs - pointer to the ip to be removed
297     * - pointer to the class
298     * output - NONE
299     * side effects -
300     */
301     void
302     remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
303     {
304 michael 4800 dlink_node *node = NULL, *node_next = NULL;
305 michael 1633
306     if (aclass->number_per_cidr == 0)
307     return;
308    
309     if (ip->ss.ss_family == AF_INET)
310     {
311 michael 1644 if (aclass->cidr_bitlen_ipv4 == 0)
312 michael 1633 return;
313    
314 michael 4800 DLINK_FOREACH_SAFE(node, node_next, aclass->list_ipv4.head)
315 michael 1633 {
316 michael 4800 struct CidrItem *cidr = node->data;
317 michael 2213
318 michael 1633 if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
319     {
320 michael 2213 cidr->number_on_this_cidr--;
321    
322     if (cidr->number_on_this_cidr == 0)
323     {
324 michael 4800 dlinkDelete(node, &aclass->list_ipv4);
325 michael 2213 MyFree(cidr);
326     return;
327     }
328 michael 1633 }
329     }
330     }
331     else if (aclass->cidr_bitlen_ipv6 > 0)
332     {
333 michael 4800 DLINK_FOREACH_SAFE(node, node_next, aclass->list_ipv6.head)
334 michael 1633 {
335 michael 4800 struct CidrItem *cidr = node->data;
336 michael 2213
337 michael 1633 if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
338     {
339 michael 2213 cidr->number_on_this_cidr--;
340    
341     if (cidr->number_on_this_cidr == 0)
342     {
343 michael 4800 dlinkDelete(node, &aclass->list_ipv6);
344 michael 2213 MyFree(cidr);
345     return;
346     }
347 michael 1633 }
348     }
349     }
350     }
351    
352 michael 1647 void
353     rebuild_cidr_list(struct ClassItem *class)
354 michael 1633 {
355 michael 4800 dlink_node *node = NULL;
356 michael 1633
357 michael 1647 destroy_cidr_class(class);
358 michael 1633
359 michael 4800 DLINK_FOREACH(node, local_client_list.head)
360 michael 1633 {
361 michael 4800 struct Client *client_p = node->data;
362 michael 4588 struct MaskItem *conf = client_p->connection->confs.tail->data;
363 michael 1633
364 michael 1647 if (conf && (conf->type == CONF_CLIENT))
365     if (conf->class == class)
366 michael 4588 cidr_limit_reached(1, &client_p->connection->ip, class);
367 michael 1633 }
368     }
369    
370     /*
371     * destroy_cidr_list
372     *
373     * inputs - pointer to class dlink list of cidr blocks
374     * output - none
375     * side effects - completely destroys the class link list of cidr blocks
376     */
377     static void
378     destroy_cidr_list(dlink_list *list)
379     {
380 michael 4800 dlink_node *node = NULL, *node_next = NULL;
381 michael 1633
382 michael 4800 DLINK_FOREACH_SAFE(node, node_next, list->head)
383 michael 1633 {
384 michael 4800 dlinkDelete(node, list);
385     MyFree(node->data);
386 michael 1633 }
387     }
388    
389     /*
390     * destroy_cidr_class
391     *
392     * inputs - pointer to class
393     * output - none
394     * side effects - completely destroys the class link list of cidr blocks
395     */
396     void
397     destroy_cidr_class(struct ClassItem *class)
398     {
399     destroy_cidr_list(&class->list_ipv4);
400     destroy_cidr_list(&class->list_ipv6);
401     }

Properties

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