ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 7266
Committed: Sat Feb 6 19:02:03 2016 UTC (9 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 7710 byte(s)
Log Message:
- Minor simplifications on clearing lists

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 7006 * Copyright (c) 1997-2016 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 7032 struct ClassItem *const class = xcalloc(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 michael 7032 xfree(class->name);
73     xfree(class);
74 michael 1633 }
75    
76     void
77     class_init(void)
78     {
79 michael 1650 (class_default = class_make())->name = xstrdup("default");
80 michael 1633 }
81    
82 michael 5411 const struct ClassItem *
83 michael 1783 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 5411 return get_class_ptr(list)->name;
104 michael 1633 }
105    
106     unsigned int
107 michael 1644 get_client_ping(const dlink_list *const list)
108 michael 1633 {
109 michael 5411 return get_class_ptr(list)->ping_freq;
110 michael 1633 }
111    
112     unsigned int
113     get_sendq(const dlink_list *const list)
114     {
115 michael 5411 return get_class_ptr(list)->max_sendq;
116 michael 1633 }
117    
118     unsigned int
119     get_recvq(const dlink_list *const list)
120     {
121 michael 5411 return get_class_ptr(list)->max_recvq;
122 michael 1633 }
123    
124     /*
125     * inputs - Integer (Number of class)
126     * output - Pointer to ClassItem struct. Non-NULL expected
127     * side effects - NONE
128     */
129     struct ClassItem *
130     class_find(const char *name, int active)
131     {
132 michael 4800 dlink_node *node = NULL;
133 michael 1633
134 michael 4800 DLINK_FOREACH(node, class_list.head)
135 michael 2213 {
136 michael 4800 struct ClassItem *class = node->data;
137 michael 1633
138     if (!irccmp(class->name, name))
139     return active && !class->active ? NULL : class;
140     }
141    
142     return NULL;
143     }
144    
145     /*
146     * We don't delete the class table, rather mark all entries for deletion.
147     * The table is cleaned up by delete_marked_classes. - avalon
148     */
149     void
150     class_mark_for_deletion(void)
151     {
152 michael 4800 dlink_node *node = NULL;
153 michael 1633
154 michael 4800 DLINK_FOREACH_PREV(node, class_list.tail->prev)
155     ((struct ClassItem *)node->data)->active = 0;
156 michael 1633 }
157    
158     void
159     class_delete_marked(void)
160     {
161 michael 4800 dlink_node *node = NULL, *node_next = NULL;
162 michael 1633
163 michael 4800 DLINK_FOREACH_SAFE(node, node_next, class_list.head)
164 michael 2213 {
165 michael 4800 struct ClassItem *class = node->data;
166 michael 1633
167     if (!class->active && !class->ref_count)
168     {
169     destroy_cidr_class(class);
170     class_free(class);
171     }
172     }
173     }
174    
175     /*
176     * cidr_limit_reached
177     *
178     * inputs - int flag allowing over_rule of limits
179     * - pointer to the ip to be added
180     * - pointer to the class
181     * output - non zero if limit reached
182     * 0 if limit not reached
183     * side effects -
184     */
185     int
186 michael 2213 cidr_limit_reached(int over_rule, struct irc_ssaddr *ip, struct ClassItem *class)
187 michael 1633 {
188 michael 4800 dlink_node *node = NULL;
189 michael 1633 struct CidrItem *cidr = NULL;
190    
191 michael 1644 if (class->number_per_cidr == 0)
192 michael 1633 return 0;
193    
194     if (ip->ss.ss_family == AF_INET)
195     {
196 michael 1644 if (class->cidr_bitlen_ipv4 == 0)
197 michael 1633 return 0;
198    
199 michael 4800 DLINK_FOREACH(node, class->list_ipv4.head)
200 michael 1633 {
201 michael 4800 cidr = node->data;
202 michael 2213
203 michael 1633 if (match_ipv4(ip, &cidr->mask, class->cidr_bitlen_ipv4))
204     {
205     if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
206     return -1;
207 michael 2213
208 michael 1633 cidr->number_on_this_cidr++;
209     return 0;
210     }
211     }
212 michael 2213
213 michael 7032 cidr = xcalloc(sizeof(struct CidrItem));
214 michael 1633 cidr->number_on_this_cidr = 1;
215     cidr->mask = *ip;
216     mask_addr(&cidr->mask, class->cidr_bitlen_ipv4);
217     dlinkAdd(cidr, &cidr->node, &class->list_ipv4);
218     }
219     else if (class->cidr_bitlen_ipv6 > 0)
220     {
221 michael 4800 DLINK_FOREACH(node, class->list_ipv6.head)
222 michael 1633 {
223 michael 4800 cidr = node->data;
224 michael 2213
225 michael 1633 if (match_ipv6(ip, &cidr->mask, class->cidr_bitlen_ipv6))
226     {
227     if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
228     return -1;
229 michael 2213
230 michael 1633 cidr->number_on_this_cidr++;
231     return 0;
232     }
233     }
234 michael 2213
235 michael 7032 cidr = xcalloc(sizeof(struct CidrItem));
236 michael 1633 cidr->number_on_this_cidr = 1;
237     cidr->mask = *ip;
238     mask_addr(&cidr->mask, class->cidr_bitlen_ipv6);
239     dlinkAdd(cidr, &cidr->node, &class->list_ipv6);
240     }
241 michael 4415
242 michael 1633 return 0;
243     }
244    
245     /*
246     * remove_from_cidr_check
247     *
248     * inputs - pointer to the ip to be removed
249     * - pointer to the class
250     * output - NONE
251     * side effects -
252     */
253     void
254     remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
255     {
256 michael 4800 dlink_node *node = NULL, *node_next = NULL;
257 michael 1633
258     if (aclass->number_per_cidr == 0)
259     return;
260    
261     if (ip->ss.ss_family == AF_INET)
262     {
263 michael 1644 if (aclass->cidr_bitlen_ipv4 == 0)
264 michael 1633 return;
265    
266 michael 4800 DLINK_FOREACH_SAFE(node, node_next, aclass->list_ipv4.head)
267 michael 1633 {
268 michael 4800 struct CidrItem *cidr = node->data;
269 michael 2213
270 michael 1633 if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
271     {
272 michael 2213 cidr->number_on_this_cidr--;
273    
274     if (cidr->number_on_this_cidr == 0)
275     {
276 michael 4800 dlinkDelete(node, &aclass->list_ipv4);
277 michael 7032 xfree(cidr);
278 michael 2213 return;
279     }
280 michael 1633 }
281     }
282     }
283     else if (aclass->cidr_bitlen_ipv6 > 0)
284     {
285 michael 4800 DLINK_FOREACH_SAFE(node, node_next, aclass->list_ipv6.head)
286 michael 1633 {
287 michael 4800 struct CidrItem *cidr = node->data;
288 michael 2213
289 michael 1633 if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
290     {
291 michael 2213 cidr->number_on_this_cidr--;
292    
293     if (cidr->number_on_this_cidr == 0)
294     {
295 michael 4800 dlinkDelete(node, &aclass->list_ipv6);
296 michael 7032 xfree(cidr);
297 michael 2213 return;
298     }
299 michael 1633 }
300     }
301     }
302     }
303    
304 michael 1647 void
305     rebuild_cidr_list(struct ClassItem *class)
306 michael 1633 {
307 michael 4800 dlink_node *node = NULL;
308 michael 1633
309 michael 1647 destroy_cidr_class(class);
310 michael 1633
311 michael 4800 DLINK_FOREACH(node, local_client_list.head)
312 michael 1633 {
313 michael 4800 struct Client *client_p = node->data;
314 michael 4588 struct MaskItem *conf = client_p->connection->confs.tail->data;
315 michael 1633
316 michael 1647 if (conf && (conf->type == CONF_CLIENT))
317     if (conf->class == class)
318 michael 4588 cidr_limit_reached(1, &client_p->connection->ip, class);
319 michael 1633 }
320     }
321    
322     /*
323     * destroy_cidr_list
324     *
325     * inputs - pointer to class dlink list of cidr blocks
326     * output - none
327     * side effects - completely destroys the class link list of cidr blocks
328     */
329     static void
330     destroy_cidr_list(dlink_list *list)
331     {
332 michael 7266 while (list->head)
333 michael 1633 {
334 michael 7266 struct CidrItem *cidr = list->head->data;
335     dlinkDelete(&cidr->node, list);
336     xfree(cidr);
337 michael 1633 }
338     }
339    
340     /*
341     * destroy_cidr_class
342     *
343     * inputs - pointer to class
344     * output - none
345     * side effects - completely destroys the class link list of cidr blocks
346     */
347     void
348     destroy_cidr_class(struct ClassItem *class)
349     {
350     destroy_cidr_list(&class->list_ipv4);
351     destroy_cidr_list(&class->list_ipv6);
352     }

Properties

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