/[svn]/ircd-hybrid/trunk/src/conf_class.c
ViewVC logotype

Contents of /ircd-hybrid/trunk/src/conf_class.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1647 - (show annotations)
Fri Nov 9 20:11:58 2012 UTC (8 years ago) by michael
File MIME type: text/x-chdr
File size: 8810 byte(s)
- Finish stabilizing/cleanup of conf parser

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

Properties

Name Value
svn:executable *
svn:keywords Id

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28