/[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 1650 - (show annotations)
Sat Nov 10 20:57:51 2012 UTC (7 years, 8 months ago) by michael
File MIME type: text/x-chdr
File size: 8695 byte(s)
- Fixed few bugs that have been introduced with config rewrite
- Set some reasonable default values right after a class has been created

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 class->active = 1;
76 class->con_freq = DEFAULT_CONNECTFREQUENCY;
77 class->ping_freq = DEFAULT_PINGFREQUENCY;
78 class->max_total = MAXIMUM_LINKS_DEFAULT;
79 class->max_sendq = DEFAULT_SENDQ;
80 class->max_recvq = DEFAULT_RECVQ;
81
82 dlinkAdd(class, &class->node, &class_list);
83
84 return class;
85 }
86
87 void
88 class_free(struct ClassItem *class)
89 {
90 assert(class);
91 assert(class->active == 0);
92 assert(class->ref_count == 0);
93
94 dlinkDelete(&class->node, &class_list);
95 MyFree(class->name);
96 MyFree(class);
97 }
98
99 void
100 class_init(void)
101 {
102 (class_default = class_make())->name = xstrdup("default");
103 }
104
105 const char *
106 get_client_class(const dlink_list *const list)
107 {
108 const dlink_node *ptr = NULL;
109
110 if ((ptr = list->head)) {
111 const struct MaskItem *conf = ptr->data;
112
113 assert(conf->class);
114 assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
115
116 return conf->class->name;
117 }
118
119 return class_default->name;
120 }
121
122 unsigned int
123 get_client_ping(const dlink_list *const list)
124 {
125 const dlink_node *ptr = NULL;
126
127 if ((ptr = list->head)) {
128 const struct MaskItem *conf = ptr->data;
129
130 assert(aconf->class);
131 assert(aconf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
132
133 return conf->class->ping_freq;
134 }
135
136 return class_default->ping_freq;
137 }
138
139 unsigned int
140 get_sendq(const dlink_list *const list)
141 {
142 const dlink_node *ptr = NULL;
143
144 if ((ptr = list->head)) {
145 const struct MaskItem *conf = ptr->data;
146
147 assert(conf->class);
148 assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
149
150 return conf->class->max_sendq;
151 }
152
153 return class_default->max_sendq;
154 }
155
156 unsigned int
157 get_recvq(const dlink_list *const list)
158 {
159 const dlink_node *ptr = NULL;
160
161 if ((ptr = list->head)) {
162 const struct MaskItem *conf = ptr->data;
163
164 assert(conf->class);
165 assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
166
167 return conf->class->max_recvq;
168 }
169
170 return class_default->max_recvq;
171 }
172
173 /*
174 * inputs - Integer (Number of class)
175 * output - Pointer to ClassItem struct. Non-NULL expected
176 * side effects - NONE
177 */
178 struct ClassItem *
179 class_find(const char *name, int active)
180 {
181 dlink_node *ptr = NULL;
182
183 DLINK_FOREACH(ptr, class_list.head) {
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 struct ClassItem *class = ptr->data;
213
214 if (!class->active && !class->ref_count)
215 {
216 destroy_cidr_class(class);
217 class_free(class);
218 }
219 }
220 }
221
222 /*
223 * cidr_limit_reached
224 *
225 * inputs - int flag allowing over_rule of limits
226 * - pointer to the ip to be added
227 * - pointer to the class
228 * output - non zero if limit reached
229 * 0 if limit not reached
230 * side effects -
231 */
232 int
233 cidr_limit_reached(int over_rule,
234 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 if (match_ipv4(ip, &cidr->mask, class->cidr_bitlen_ipv4))
251 {
252 if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
253 return -1;
254 cidr->number_on_this_cidr++;
255 return 0;
256 }
257 }
258 cidr = MyMalloc(sizeof(struct CidrItem));
259 cidr->number_on_this_cidr = 1;
260 cidr->mask = *ip;
261 mask_addr(&cidr->mask, class->cidr_bitlen_ipv4);
262 dlinkAdd(cidr, &cidr->node, &class->list_ipv4);
263 }
264 #ifdef IPV6
265 else if (class->cidr_bitlen_ipv6 > 0)
266 {
267 DLINK_FOREACH(ptr, class->list_ipv6.head)
268 {
269 cidr = ptr->data;
270 if (match_ipv6(ip, &cidr->mask, class->cidr_bitlen_ipv6))
271 {
272 if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
273 return -1;
274 cidr->number_on_this_cidr++;
275 return 0;
276 }
277 }
278 cidr = MyMalloc(sizeof(struct CidrItem));
279 cidr->number_on_this_cidr = 1;
280 cidr->mask = *ip;
281 mask_addr(&cidr->mask, class->cidr_bitlen_ipv6);
282 dlinkAdd(cidr, &cidr->node, &class->list_ipv6);
283 }
284 #endif
285 return 0;
286 }
287
288 /*
289 * remove_from_cidr_check
290 *
291 * inputs - pointer to the ip to be removed
292 * - pointer to the class
293 * output - NONE
294 * side effects -
295 */
296 void
297 remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
298 {
299 dlink_node *ptr = NULL;
300 dlink_node *next_ptr = NULL;
301 struct CidrItem *cidr;
302
303 if (aclass->number_per_cidr == 0)
304 return;
305
306 if (ip->ss.ss_family == AF_INET)
307 {
308 if (aclass->cidr_bitlen_ipv4 == 0)
309 return;
310
311 DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
312 {
313 cidr = ptr->data;
314 if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
315 {
316 cidr->number_on_this_cidr--;
317 if (cidr->number_on_this_cidr == 0)
318 {
319 dlinkDelete(ptr, &aclass->list_ipv4);
320 MyFree(cidr);
321 return;
322 }
323 }
324 }
325 }
326 #ifdef IPV6
327 else if (aclass->cidr_bitlen_ipv6 > 0)
328 {
329 DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
330 {
331 cidr = ptr->data;
332 if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
333 {
334 cidr->number_on_this_cidr--;
335 if (cidr->number_on_this_cidr == 0)
336 {
337 dlinkDelete(ptr, &aclass->list_ipv6);
338 MyFree(cidr);
339 return;
340 }
341 }
342 }
343 }
344 #endif
345 }
346
347 void
348 rebuild_cidr_list(struct ClassItem *class)
349 {
350 dlink_node *ptr;
351
352 destroy_cidr_class(class);
353
354 DLINK_FOREACH(ptr, local_client_list.head)
355 {
356 struct Client *client_p = ptr->data;
357 struct MaskItem *conf = client_p->localClient->confs.tail->data;
358
359 if (conf && (conf->type == CONF_CLIENT))
360 if (conf->class == class)
361 cidr_limit_reached(1, &client_p->localClient->ip, class);
362 }
363 }
364
365 /*
366 * destroy_cidr_list
367 *
368 * inputs - pointer to class dlink list of cidr blocks
369 * output - none
370 * side effects - completely destroys the class link list of cidr blocks
371 */
372 static void
373 destroy_cidr_list(dlink_list *list)
374 {
375 dlink_node *ptr = NULL, *next_ptr = NULL;
376
377 DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
378 {
379 dlinkDelete(ptr, list);
380 MyFree(ptr->data);
381 }
382 }
383
384 /*
385 * destroy_cidr_class
386 *
387 * inputs - pointer to class
388 * output - none
389 * side effects - completely destroys the class link list of cidr blocks
390 */
391 void
392 destroy_cidr_class(struct ClassItem *class)
393 {
394 destroy_cidr_list(&class->list_ipv4);
395 destroy_cidr_list(&class->list_ipv6);
396 }

Properties

Name Value
svn:executable *
svn:keywords Id

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