ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 3250
Committed: Sun Mar 30 20:47:30 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 8645 byte(s)
Log Message:
- Fixed inconsistent style in several places

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2014 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
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 *class = MyMalloc(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 *class)
66 {
67 assert(class);
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 struct ClassItem *
83 get_class_ptr(const dlink_list *const list)
84 {
85 const dlink_node *ptr = NULL;
86
87 if ((ptr = list->head))
88 {
89 const struct MaskItem *conf = ptr->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 const dlink_node *ptr = NULL;
104
105 if ((ptr = list->head))
106 {
107 const struct MaskItem *conf = ptr->data;
108
109 assert(conf->class);
110 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
111
112 return conf->class->name;
113 }
114
115 return class_default->name;
116 }
117
118 unsigned int
119 get_client_ping(const dlink_list *const list)
120 {
121 const dlink_node *ptr = NULL;
122
123 if ((ptr = list->head))
124 {
125 const struct MaskItem *conf = ptr->data;
126
127 assert(conf->class);
128 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
129
130 return conf->class->ping_freq;
131 }
132
133 return class_default->ping_freq;
134 }
135
136 unsigned int
137 get_sendq(const dlink_list *const list)
138 {
139 const dlink_node *ptr = NULL;
140
141 if ((ptr = list->head))
142 {
143 const struct MaskItem *conf = ptr->data;
144
145 assert(conf->class);
146 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
147
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 const dlink_node *ptr = NULL;
158
159 if ((ptr = list->head))
160 {
161 const struct MaskItem *conf = ptr->data;
162
163 assert(conf->class);
164 assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
165
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 {
184 struct ClassItem *class = ptr->data;
185
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 dlink_node *ptr = NULL;
201
202 DLINK_FOREACH_PREV(ptr, class_list.tail->prev)
203 ((struct ClassItem *)ptr->data)->active = 0;
204 }
205
206 void
207 class_delete_marked(void)
208 {
209 dlink_node *ptr = NULL, *ptr_next = NULL;
210
211 DLINK_FOREACH_SAFE(ptr, ptr_next, class_list.head)
212 {
213 struct ClassItem *class = ptr->data;
214
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 cidr_limit_reached(int over_rule, struct irc_ssaddr *ip, struct ClassItem *class)
235 {
236 dlink_node *ptr = NULL;
237 struct CidrItem *cidr = NULL;
238
239 if (class->number_per_cidr == 0)
240 return 0;
241
242 if (ip->ss.ss_family == AF_INET)
243 {
244 if (class->cidr_bitlen_ipv4 == 0)
245 return 0;
246
247 DLINK_FOREACH(ptr, class->list_ipv4.head)
248 {
249 cidr = ptr->data;
250
251 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
256 cidr->number_on_this_cidr++;
257 return 0;
258 }
259 }
260
261 cidr = MyMalloc(sizeof(struct CidrItem));
262 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 #ifdef IPV6
268 else if (class->cidr_bitlen_ipv6 > 0)
269 {
270 DLINK_FOREACH(ptr, class->list_ipv6.head)
271 {
272 cidr = ptr->data;
273
274 if (match_ipv6(ip, &cidr->mask, class->cidr_bitlen_ipv6))
275 {
276 if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
277 return -1;
278
279 cidr->number_on_this_cidr++;
280 return 0;
281 }
282 }
283
284 cidr = MyMalloc(sizeof(struct CidrItem));
285 cidr->number_on_this_cidr = 1;
286 cidr->mask = *ip;
287 mask_addr(&cidr->mask, class->cidr_bitlen_ipv6);
288 dlinkAdd(cidr, &cidr->node, &class->list_ipv6);
289 }
290 #endif
291 return 0;
292 }
293
294 /*
295 * remove_from_cidr_check
296 *
297 * inputs - pointer to the ip to be removed
298 * - pointer to the class
299 * output - NONE
300 * side effects -
301 */
302 void
303 remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
304 {
305 dlink_node *ptr = NULL;
306 dlink_node *next_ptr = NULL;
307 struct CidrItem *cidr;
308
309 if (aclass->number_per_cidr == 0)
310 return;
311
312 if (ip->ss.ss_family == AF_INET)
313 {
314 if (aclass->cidr_bitlen_ipv4 == 0)
315 return;
316
317 DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
318 {
319 cidr = ptr->data;
320
321 if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
322 {
323 cidr->number_on_this_cidr--;
324
325 if (cidr->number_on_this_cidr == 0)
326 {
327 dlinkDelete(ptr, &aclass->list_ipv4);
328 MyFree(cidr);
329 return;
330 }
331 }
332 }
333 }
334 #ifdef IPV6
335 else if (aclass->cidr_bitlen_ipv6 > 0)
336 {
337 DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
338 {
339 cidr = ptr->data;
340
341 if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
342 {
343 cidr->number_on_this_cidr--;
344
345 if (cidr->number_on_this_cidr == 0)
346 {
347 dlinkDelete(ptr, &aclass->list_ipv6);
348 MyFree(cidr);
349 return;
350 }
351 }
352 }
353 }
354 #endif
355 }
356
357 void
358 rebuild_cidr_list(struct ClassItem *class)
359 {
360 dlink_node *ptr = NULL;
361
362 destroy_cidr_class(class);
363
364 DLINK_FOREACH(ptr, local_client_list.head)
365 {
366 struct Client *client_p = ptr->data;
367 struct MaskItem *conf = client_p->localClient->confs.tail->data;
368
369 if (conf && (conf->type == CONF_CLIENT))
370 if (conf->class == class)
371 cidr_limit_reached(1, &client_p->localClient->ip, class);
372 }
373 }
374
375 /*
376 * destroy_cidr_list
377 *
378 * inputs - pointer to class dlink list of cidr blocks
379 * output - none
380 * side effects - completely destroys the class link list of cidr blocks
381 */
382 static void
383 destroy_cidr_list(dlink_list *list)
384 {
385 dlink_node *ptr = NULL, *ptr_next = NULL;
386
387 DLINK_FOREACH_SAFE(ptr, ptr_next, list->head)
388 {
389 dlinkDelete(ptr, list);
390 MyFree(ptr->data);
391 }
392 }
393
394 /*
395 * destroy_cidr_class
396 *
397 * inputs - pointer to class
398 * output - none
399 * side effects - completely destroys the class link list of cidr blocks
400 */
401 void
402 destroy_cidr_class(struct ClassItem *class)
403 {
404 destroy_cidr_list(&class->list_ipv4);
405 destroy_cidr_list(&class->list_ipv6);
406 }

Properties

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