ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 5411
Committed: Sat Jan 24 19:12:59 2015 UTC (9 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 7747 byte(s)
Log Message:
- conf_class.c: removed duplicated code

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2015 ircd-hybrid development team
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 /*! \file conf_class.c
23 * \brief Configuration managment for class{} blocks
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "ircd.h"
30 #include "conf.h"
31 #include "hostmask.h"
32 #include "irc_string.h"
33 #include "memory.h"
34
35
36 struct ClassItem *class_default;
37
38 static dlink_list class_list;
39
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 struct ClassItem *const class = MyCalloc(sizeof(*class));
51
52 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 dlinkAdd(class, &class->node, &class_list);
60
61 return class;
62 }
63
64 void
65 class_free(struct ClassItem *const class)
66 {
67 assert(class != class_default);
68 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 (class_default = class_make())->name = xstrdup("default");
80 }
81
82 const struct ClassItem *
83 get_class_ptr(const dlink_list *const list)
84 {
85 const dlink_node *const node = list->head;
86
87 if (node)
88 {
89 const struct MaskItem *const conf = node->data;
90
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 const char *
101 get_client_class(const dlink_list *const list)
102 {
103 return get_class_ptr(list)->name;
104 }
105
106 unsigned int
107 get_client_ping(const dlink_list *const list)
108 {
109 return get_class_ptr(list)->ping_freq;
110 }
111
112 unsigned int
113 get_sendq(const dlink_list *const list)
114 {
115 return get_class_ptr(list)->max_sendq;
116 }
117
118 unsigned int
119 get_recvq(const dlink_list *const list)
120 {
121 return get_class_ptr(list)->max_recvq;
122 }
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 dlink_node *node = NULL;
133
134 DLINK_FOREACH(node, class_list.head)
135 {
136 struct ClassItem *class = node->data;
137
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 dlink_node *node = NULL;
153
154 DLINK_FOREACH_PREV(node, class_list.tail->prev)
155 ((struct ClassItem *)node->data)->active = 0;
156 }
157
158 void
159 class_delete_marked(void)
160 {
161 dlink_node *node = NULL, *node_next = NULL;
162
163 DLINK_FOREACH_SAFE(node, node_next, class_list.head)
164 {
165 struct ClassItem *class = node->data;
166
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 cidr_limit_reached(int over_rule, struct irc_ssaddr *ip, struct ClassItem *class)
187 {
188 dlink_node *node = NULL;
189 struct CidrItem *cidr = NULL;
190
191 if (class->number_per_cidr == 0)
192 return 0;
193
194 if (ip->ss.ss_family == AF_INET)
195 {
196 if (class->cidr_bitlen_ipv4 == 0)
197 return 0;
198
199 DLINK_FOREACH(node, class->list_ipv4.head)
200 {
201 cidr = node->data;
202
203 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
208 cidr->number_on_this_cidr++;
209 return 0;
210 }
211 }
212
213 cidr = MyCalloc(sizeof(struct CidrItem));
214 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 DLINK_FOREACH(node, class->list_ipv6.head)
222 {
223 cidr = node->data;
224
225 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
230 cidr->number_on_this_cidr++;
231 return 0;
232 }
233 }
234
235 cidr = MyCalloc(sizeof(struct CidrItem));
236 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
242 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 dlink_node *node = NULL, *node_next = NULL;
257
258 if (aclass->number_per_cidr == 0)
259 return;
260
261 if (ip->ss.ss_family == AF_INET)
262 {
263 if (aclass->cidr_bitlen_ipv4 == 0)
264 return;
265
266 DLINK_FOREACH_SAFE(node, node_next, aclass->list_ipv4.head)
267 {
268 struct CidrItem *cidr = node->data;
269
270 if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
271 {
272 cidr->number_on_this_cidr--;
273
274 if (cidr->number_on_this_cidr == 0)
275 {
276 dlinkDelete(node, &aclass->list_ipv4);
277 MyFree(cidr);
278 return;
279 }
280 }
281 }
282 }
283 else if (aclass->cidr_bitlen_ipv6 > 0)
284 {
285 DLINK_FOREACH_SAFE(node, node_next, aclass->list_ipv6.head)
286 {
287 struct CidrItem *cidr = node->data;
288
289 if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
290 {
291 cidr->number_on_this_cidr--;
292
293 if (cidr->number_on_this_cidr == 0)
294 {
295 dlinkDelete(node, &aclass->list_ipv6);
296 MyFree(cidr);
297 return;
298 }
299 }
300 }
301 }
302 }
303
304 void
305 rebuild_cidr_list(struct ClassItem *class)
306 {
307 dlink_node *node = NULL;
308
309 destroy_cidr_class(class);
310
311 DLINK_FOREACH(node, local_client_list.head)
312 {
313 struct Client *client_p = node->data;
314 struct MaskItem *conf = client_p->connection->confs.tail->data;
315
316 if (conf && (conf->type == CONF_CLIENT))
317 if (conf->class == class)
318 cidr_limit_reached(1, &client_p->connection->ip, class);
319 }
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 dlink_node *node = NULL, *node_next = NULL;
333
334 DLINK_FOREACH_SAFE(node, node_next, list->head)
335 {
336 dlinkDelete(node, list);
337 MyFree(node->data);
338 }
339 }
340
341 /*
342 * destroy_cidr_class
343 *
344 * inputs - pointer to class
345 * output - none
346 * side effects - completely destroys the class link list of cidr blocks
347 */
348 void
349 destroy_cidr_class(struct ClassItem *class)
350 {
351 destroy_cidr_list(&class->list_ipv4);
352 destroy_cidr_list(&class->list_ipv6);
353 }

Properties

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