]>
Commit | Line | Data |
---|---|---|
3c5a494d VY |
1 | /*\r |
2 | * ircd-ratbox: A slightly useful ircd\r | |
3 | * reject.c: reject users with prejudice\r | |
4 | *\r | |
5 | * Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>\r | |
6 | * Copyright (C) 2003-2005 ircd-ratbox development team\r | |
7 | *\r | |
8 | * This program is free software; you can redistribute it and/or modify\r | |
9 | * it under the terms of the GNU General Public License as published by\r | |
10 | * the Free Software Foundation; either version 2 of the License, or\r | |
11 | * (at your option) any later version.\r | |
12 | *\r | |
13 | * This program is distributed in the hope that it will be useful,\r | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of\r | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r | |
16 | * GNU General Public License for more details.\r | |
17 | *\r | |
18 | * You should have received a copy of the GNU General Public License\r | |
19 | * along with this program; if not, write to the Free Software\r | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301\r | |
21 | * USA\r | |
22 | *\r | |
23 | * $Id: reject.c 25119 2008-03-13 16:57:05Z androsyn $\r | |
24 | */\r | |
25 | \r | |
26 | #include "stdinc.h"\r | |
27 | #include "client.h"\r | |
28 | #include "s_conf.h"\r | |
29 | #include "reject.h"\r | |
30 | #include "s_stats.h"\r | |
31 | #include "ircd.h"\r | |
32 | #include "send.h"\r | |
33 | #include "numeric.h"\r | |
34 | #include "parse.h"\r | |
35 | #include "hostmask.h"\r | |
36 | \r | |
37 | static rb_patricia_tree_t *global_tree;\r | |
38 | static rb_patricia_tree_t *reject_tree;\r | |
39 | static rb_patricia_tree_t *dline_tree;\r | |
40 | static rb_patricia_tree_t *eline_tree;\r | |
41 | static rb_dlink_list delay_exit;\r | |
42 | static rb_dlink_list reject_list;\r | |
43 | static rb_dlink_list throttle_list;\r | |
44 | static rb_patricia_tree_t *throttle_tree;\r | |
45 | static void throttle_expires(void *unused);\r | |
46 | \r | |
47 | \r | |
48 | typedef struct _reject_data\r | |
49 | {\r | |
50 | rb_dlink_node rnode;\r | |
51 | time_t time;\r | |
52 | unsigned int count;\r | |
53 | } reject_t;\r | |
54 | \r | |
55 | typedef struct _delay_data\r | |
56 | {\r | |
57 | rb_dlink_node node;\r | |
58 | rb_fde_t *F;\r | |
59 | } delay_t;\r | |
60 | \r | |
61 | typedef struct _throttle\r | |
62 | {\r | |
63 | rb_dlink_node node;\r | |
64 | time_t last;\r | |
65 | int count;\r | |
66 | } throttle_t;\r | |
67 | \r | |
68 | typedef struct _global_data\r | |
69 | {\r | |
70 | int count;\r | |
71 | } global_t;\r | |
72 | \r | |
73 | \r | |
74 | static rb_patricia_node_t *\r | |
75 | add_ipline(struct ConfItem *aconf, rb_patricia_tree_t *tree, struct sockaddr *addr, int cidr)\r | |
76 | {\r | |
77 | rb_patricia_node_t *pnode;\r | |
78 | pnode = make_and_lookup_ip(tree, addr, cidr);\r | |
79 | if(pnode == NULL)\r | |
80 | return NULL;\r | |
81 | aconf->pnode = pnode;\r | |
82 | pnode->data = aconf;\r | |
83 | return (pnode);\r | |
84 | }\r | |
85 | \r | |
86 | int \r | |
87 | add_dline(struct ConfItem *aconf)\r | |
88 | {\r | |
89 | struct rb_sockaddr_storage st;\r | |
90 | int bitlen;\r | |
91 | if(parse_netmask(aconf->host, (struct sockaddr *)&st, &bitlen) == HM_HOST)\r | |
92 | return 0;\r | |
93 | \r | |
94 | if(add_ipline(aconf, dline_tree, (struct sockaddr *)&st, bitlen) != NULL)\r | |
95 | return 1;\r | |
96 | return 0;\r | |
97 | }\r | |
98 | \r | |
99 | int\r | |
100 | add_eline(struct ConfItem *aconf)\r | |
101 | {\r | |
102 | struct rb_sockaddr_storage st;\r | |
103 | int bitlen;\r | |
104 | if(parse_netmask(aconf->host, (struct sockaddr *)&st, &bitlen) == HM_HOST)\r | |
105 | return 0;\r | |
106 | \r | |
107 | if(add_ipline(aconf, eline_tree, (struct sockaddr *)&st, bitlen) != NULL)\r | |
108 | return 1;\r | |
109 | return 0;\r | |
110 | }\r | |
111 | \r | |
112 | unsigned long\r | |
113 | delay_exit_length(void)\r | |
114 | {\r | |
115 | return rb_dlink_list_length(&delay_exit);\r | |
116 | }\r | |
117 | \r | |
118 | static void\r | |
119 | reject_exit(void *unused)\r | |
120 | {\r | |
121 | rb_dlink_node *ptr, *ptr_next;\r | |
122 | delay_t *ddata;\r | |
123 | static const char *errbuf = "ERROR :Closing Link: (*** Banned (cache))\r\n";\r | |
124 | \r | |
125 | RB_DLINK_FOREACH_SAFE(ptr, ptr_next, delay_exit.head)\r | |
126 | {\r | |
127 | ddata = ptr->data;\r | |
128 | \r | |
129 | rb_write(ddata->F, errbuf, strlen(errbuf)); \r | |
130 | rb_close(ddata->F);\r | |
131 | rb_free(ddata);\r | |
132 | }\r | |
133 | \r | |
134 | delay_exit.head = delay_exit.tail = NULL;\r | |
135 | delay_exit.length = 0;\r | |
136 | }\r | |
137 | \r | |
138 | static void\r | |
139 | reject_expires(void *unused)\r | |
140 | {\r | |
141 | rb_dlink_node *ptr, *next;\r | |
142 | rb_patricia_node_t *pnode;\r | |
143 | reject_t *rdata;\r | |
144 | \r | |
145 | RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head)\r | |
146 | {\r | |
147 | pnode = ptr->data;\r | |
148 | rdata = pnode->data; \r | |
149 | \r | |
150 | if(rdata->time + ConfigFileEntry.reject_duration > rb_current_time())\r | |
151 | continue;\r | |
152 | \r | |
153 | rb_dlinkDelete(ptr, &reject_list);\r | |
154 | rb_free(rdata);\r | |
155 | rb_patricia_remove(reject_tree, pnode);\r | |
156 | }\r | |
157 | }\r | |
158 | \r | |
159 | void\r | |
160 | init_reject(void)\r | |
161 | {\r | |
162 | reject_tree = rb_new_patricia(PATRICIA_BITS);\r | |
163 | dline_tree = rb_new_patricia(PATRICIA_BITS);\r | |
164 | eline_tree = rb_new_patricia(PATRICIA_BITS);\r | |
165 | throttle_tree = rb_new_patricia(PATRICIA_BITS);\r | |
166 | global_tree = rb_new_patricia(PATRICIA_BITS);\r | |
167 | rb_event_add("reject_exit", reject_exit, NULL, DELAYED_EXIT_TIME);\r | |
168 | rb_event_add("reject_expires", reject_expires, NULL, 60);\r | |
169 | rb_event_add("throttle_expires", throttle_expires, NULL, 10);\r | |
170 | }\r | |
171 | \r | |
172 | \r | |
173 | void\r | |
174 | add_reject(struct Client *client_p)\r | |
175 | {\r | |
176 | rb_patricia_node_t *pnode;\r | |
177 | reject_t *rdata;\r | |
178 | \r | |
179 | /* Reject is disabled */\r | |
180 | if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0)\r | |
181 | return;\r | |
182 | \r | |
183 | if((pnode = rb_match_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip)) != NULL)\r | |
184 | {\r | |
185 | rdata = pnode->data;\r | |
186 | rdata->time = rb_current_time();\r | |
187 | rdata->count++;\r | |
188 | }\r | |
189 | else\r | |
190 | {\r | |
191 | int bitlen = 32;\r | |
192 | #ifdef RB_IPV6\r | |
193 | if(GET_SS_FAMILY(&client_p->localClient->ip) == AF_INET6)\r | |
194 | bitlen = 128;\r | |
195 | #endif\r | |
196 | pnode = make_and_lookup_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip, bitlen);\r | |
197 | pnode->data = rdata = rb_malloc(sizeof(reject_t));\r | |
198 | rb_dlinkAddTail(pnode, &rdata->rnode, &reject_list);\r | |
199 | rdata->time = rb_current_time();\r | |
200 | rdata->count = 1;\r | |
201 | }\r | |
202 | }\r | |
203 | \r | |
204 | int\r | |
205 | check_reject(rb_fde_t *F, struct sockaddr *addr)\r | |
206 | {\r | |
207 | rb_patricia_node_t *pnode;\r | |
208 | reject_t *rdata;\r | |
209 | delay_t *ddata;\r | |
210 | /* Reject is disabled */\r | |
211 | if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0)\r | |
212 | return 0;\r | |
213 | \r | |
214 | pnode = rb_match_ip(reject_tree, addr);\r | |
215 | if(pnode != NULL)\r | |
216 | {\r | |
217 | rdata = pnode->data;\r | |
218 | \r | |
219 | rdata->time = rb_current_time();\r | |
220 | if(rdata->count > (unsigned long)ConfigFileEntry.reject_after_count)\r | |
221 | {\r | |
222 | ddata = rb_malloc(sizeof(delay_t));\r | |
223 | ServerStats.is_rej++;\r | |
224 | rb_setselect(F, RB_SELECT_WRITE | RB_SELECT_READ, NULL, NULL);\r | |
225 | ddata->F = F;\r | |
226 | rb_dlinkAdd(ddata, &ddata->node, &delay_exit);\r | |
227 | return 1;\r | |
228 | }\r | |
229 | } \r | |
230 | /* Caller does what it wants */ \r | |
231 | return 0;\r | |
232 | }\r | |
233 | \r | |
234 | void \r | |
235 | flush_reject(void)\r | |
236 | {\r | |
237 | rb_dlink_node *ptr, *next;\r | |
238 | rb_patricia_node_t *pnode;\r | |
239 | reject_t *rdata;\r | |
240 | \r | |
241 | RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head)\r | |
242 | {\r | |
243 | pnode = ptr->data;\r | |
244 | rdata = pnode->data;\r | |
245 | rb_dlinkDelete(ptr, &reject_list);\r | |
246 | rb_free(rdata);\r | |
247 | rb_patricia_remove(reject_tree, pnode);\r | |
248 | }\r | |
249 | }\r | |
250 | \r | |
251 | int \r | |
252 | remove_reject(const char *ip)\r | |
253 | {\r | |
254 | rb_patricia_node_t *pnode;\r | |
255 | \r | |
256 | /* Reject is disabled */\r | |
257 | if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0)\r | |
258 | return -1;\r | |
259 | \r | |
260 | if((pnode = rb_match_string(reject_tree, ip)) != NULL)\r | |
261 | {\r | |
262 | reject_t *rdata = pnode->data;\r | |
263 | rb_dlinkDelete(&rdata->rnode, &reject_list);\r | |
264 | rb_free(rdata);\r | |
265 | rb_patricia_remove(reject_tree, pnode);\r | |
266 | return 1;\r | |
267 | }\r | |
268 | return 0;\r | |
269 | }\r | |
270 | \r | |
271 | static void\r | |
272 | delete_ipline(struct ConfItem *aconf, rb_patricia_tree_t *t)\r | |
273 | {\r | |
274 | rb_patricia_remove(t, aconf->pnode);\r | |
275 | if(!aconf->clients)\r | |
276 | {\r | |
277 | free_conf(aconf);\r | |
278 | }\r | |
279 | }\r | |
280 | \r | |
281 | static struct ConfItem *\r | |
282 | find_ipline(rb_patricia_tree_t *t, struct sockaddr *addr)\r | |
283 | {\r | |
284 | rb_patricia_node_t *pnode;\r | |
285 | pnode = rb_match_ip(t, addr);\r | |
286 | if(pnode != NULL)\r | |
287 | return (struct ConfItem *) pnode->data;\r | |
288 | return NULL;\r | |
289 | }\r | |
290 | \r | |
291 | static struct ConfItem *\r | |
292 | find_ipline_exact(rb_patricia_tree_t *t, struct sockaddr *addr, unsigned int bitlen)\r | |
293 | {\r | |
294 | rb_patricia_node_t *pnode;\r | |
295 | pnode = rb_match_ip_exact(t, addr, bitlen);\r | |
296 | if(pnode != NULL)\r | |
297 | return (struct ConfItem *) pnode->data;\r | |
298 | return NULL;\r | |
299 | }\r | |
300 | \r | |
301 | \r | |
302 | struct ConfItem *\r | |
303 | find_dline(struct sockaddr *addr)\r | |
304 | {\r | |
305 | struct ConfItem *aconf;\r | |
306 | aconf = find_ipline(eline_tree, addr);\r | |
307 | if(aconf != NULL)\r | |
308 | {\r | |
309 | return aconf;\r | |
310 | }\r | |
311 | return (find_ipline(dline_tree, addr));\r | |
312 | }\r | |
313 | \r | |
314 | struct ConfItem *\r | |
315 | find_dline_exact(struct sockaddr *addr, unsigned int bitlen)\r | |
316 | {\r | |
317 | return find_ipline_exact(dline_tree, addr, bitlen);\r | |
318 | }\r | |
319 | \r | |
320 | void\r | |
321 | remove_dline(struct ConfItem *aconf)\r | |
322 | {\r | |
323 | delete_ipline(aconf, dline_tree);\r | |
324 | }\r | |
325 | \r | |
326 | void\r | |
327 | report_dlines(struct Client *source_p)\r | |
328 | {\r | |
329 | rb_patricia_node_t *pnode;\r | |
330 | struct ConfItem *aconf;\r | |
331 | const char *host, *pass, *user, *oper_reason;\r | |
332 | RB_PATRICIA_WALK(dline_tree->head, pnode)\r | |
333 | {\r | |
334 | aconf = pnode->data;\r | |
335 | if(aconf->flags & CONF_FLAGS_TEMPORARY)\r | |
336 | RB_PATRICIA_WALK_BREAK;\r | |
337 | get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);\r | |
338 | sendto_one_numeric(source_p, RPL_STATSDLINE,\r | |
339 | form_str (RPL_STATSDLINE),\r | |
340 | 'D', host, pass,\r | |
341 | oper_reason ? "|" : "",\r | |
342 | oper_reason ? oper_reason : "");\r | |
343 | }\r | |
344 | RB_PATRICIA_WALK_END;\r | |
345 | }\r | |
346 | \r | |
347 | void\r | |
348 | report_tdlines(struct Client *source_p)\r | |
349 | {\r | |
350 | rb_patricia_node_t *pnode;\r | |
351 | struct ConfItem *aconf;\r | |
352 | const char *host, *pass, *user, *oper_reason;\r | |
353 | RB_PATRICIA_WALK(dline_tree->head, pnode)\r | |
354 | {\r | |
355 | aconf = pnode->data;\r | |
356 | if(!(aconf->flags & CONF_FLAGS_TEMPORARY))\r | |
357 | RB_PATRICIA_WALK_BREAK;\r | |
358 | get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);\r | |
359 | sendto_one_numeric(source_p, RPL_STATSDLINE,\r | |
360 | form_str (RPL_STATSDLINE),\r | |
361 | 'd', host, pass,\r | |
362 | oper_reason ? "|" : "",\r | |
363 | oper_reason ? oper_reason : "");\r | |
364 | }\r | |
365 | RB_PATRICIA_WALK_END;\r | |
366 | }\r | |
367 | \r | |
368 | void\r | |
369 | report_elines(struct Client *source_p)\r | |
370 | {\r | |
371 | rb_patricia_node_t *pnode;\r | |
372 | struct ConfItem *aconf;\r | |
373 | int port;\r | |
374 | const char *name, *host, *pass, *user, *classname;\r | |
375 | RB_PATRICIA_WALK(eline_tree->head, pnode)\r | |
376 | {\r | |
377 | aconf = pnode->data;\r | |
378 | get_printable_conf(aconf, &name, &host, &pass, &user, &port, &classname);\r | |
379 | sendto_one_numeric(source_p, RPL_STATSDLINE,\r | |
380 | form_str (RPL_STATSDLINE),\r | |
381 | 'e', host, pass,\r | |
382 | "", "");\r | |
383 | }\r | |
384 | RB_PATRICIA_WALK_END;\r | |
385 | }\r | |
386 | \r | |
387 | \r | |
388 | \r | |
389 | int\r | |
390 | throttle_add(struct sockaddr *addr)\r | |
391 | {\r | |
392 | throttle_t *t;\r | |
393 | rb_patricia_node_t *pnode;\r | |
394 | \r | |
395 | if((pnode = rb_match_ip(throttle_tree, addr)) != NULL)\r | |
396 | {\r | |
397 | t = pnode->data;\r | |
398 | \r | |
399 | if(t->count > ConfigFileEntry.throttle_count)\r | |
400 | return 1; \r | |
401 | \r | |
402 | /* Stop penalizing them after they've been throttled */\r | |
403 | t->last = rb_current_time();\r | |
404 | t->count++;\r | |
405 | \r | |
406 | } else {\r | |
407 | int bitlen = 32;\r | |
408 | #ifdef RB_IPV6\r | |
409 | if(GET_SS_FAMILY(addr) == AF_INET6)\r | |
410 | bitlen = 128;\r | |
411 | #endif\r | |
412 | t = rb_malloc(sizeof(throttle_t)); \r | |
413 | t->last = rb_current_time();\r | |
414 | t->count = 1;\r | |
415 | pnode = make_and_lookup_ip(throttle_tree, addr, bitlen);\r | |
416 | pnode->data = t;\r | |
417 | rb_dlinkAdd(pnode, &t->node, &throttle_list); \r | |
418 | } \r | |
419 | return 0;\r | |
420 | }\r | |
421 | \r | |
422 | static void\r | |
423 | throttle_expires(void *unused)\r | |
424 | {\r | |
425 | rb_dlink_node *ptr, *next;\r | |
426 | rb_patricia_node_t *pnode;\r | |
427 | throttle_t *t;\r | |
428 | \r | |
429 | RB_DLINK_FOREACH_SAFE(ptr, next, throttle_list.head)\r | |
430 | {\r | |
431 | pnode = ptr->data;\r | |
432 | t = pnode->data; \r | |
433 | \r | |
434 | if(t->last + ConfigFileEntry.throttle_duration > rb_current_time())\r | |
435 | continue;\r | |
436 | \r | |
437 | rb_dlinkDelete(ptr, &throttle_list);\r | |
438 | rb_free(t);\r | |
439 | rb_patricia_remove(throttle_tree, pnode);\r | |
440 | }\r | |
441 | }\r | |
442 | \r | |
443 | static int \r | |
444 | get_global_count(struct sockaddr *addr)\r | |
445 | {\r | |
446 | rb_patricia_node_t *pnode;\r | |
447 | global_t *glb;\r | |
448 | \r | |
449 | if((pnode = rb_match_ip(global_tree, addr)))\r | |
450 | {\r | |
451 | glb = pnode->data;\r | |
452 | return glb->count;\r | |
453 | }\r | |
454 | return 0; \r | |
455 | }\r | |
456 | \r | |
457 | static int\r | |
458 | inc_global_ip(struct sockaddr *addr, int bitlen)\r | |
459 | {\r | |
460 | rb_patricia_node_t *pnode;\r | |
461 | global_t *glb;\r | |
462 | \r | |
463 | \r | |
464 | if((pnode = rb_match_ip(global_tree, addr)))\r | |
465 | {\r | |
466 | glb = pnode->data;\r | |
467 | } \r | |
468 | else\r | |
469 | {\r | |
470 | pnode = make_and_lookup_ip(global_tree, addr, bitlen);\r | |
471 | glb = rb_malloc(sizeof(global_t));\r | |
472 | pnode->data = glb;\r | |
473 | }\r | |
474 | glb->count++;\r | |
475 | return glb->count;\r | |
476 | }\r | |
477 | \r | |
478 | static void\r | |
479 | dec_global_ip(struct sockaddr *addr)\r | |
480 | {\r | |
481 | rb_patricia_node_t *pnode;\r | |
482 | global_t *glb;\r | |
483 | \r | |
484 | if((pnode = rb_match_ip(global_tree, addr)))\r | |
485 | {\r | |
486 | glb = pnode->data;\r | |
487 | glb->count--;\r | |
488 | if(glb->count == 0)\r | |
489 | {\r | |
490 | rb_free(glb);\r | |
491 | rb_patricia_remove(global_tree, pnode);\r | |
492 | return;\r | |
493 | }\r | |
494 | }\r | |
495 | }\r | |
496 | \r | |
497 | int\r | |
498 | inc_global_cidr_count(struct Client *client_p)\r | |
499 | {\r | |
500 | struct rb_sockaddr_storage ip;\r | |
501 | struct sockaddr *addr;\r | |
502 | int bitlen;\r | |
503 | \r | |
504 | if(!MyClient(client_p))\r | |
505 | {\r | |
506 | if(EmptyString(client_p->sockhost) || !strcmp(client_p->sockhost, "0"))\r | |
507 | return -1; \r | |
508 | if(!rb_inet_pton_sock(client_p->sockhost, (struct sockaddr *)&ip))\r | |
509 | return -1;\r | |
510 | addr = (struct sockaddr *)&ip;\r | |
511 | } else\r | |
512 | addr = (struct sockaddr *)&client_p->localClient->ip;\r | |
513 | #ifdef RB_IPV6 \r | |
514 | if(GET_SS_FAMILY(addr) == AF_INET6)\r | |
515 | {\r | |
516 | bitlen = ConfigFileEntry.global_cidr_ipv6_bitlen;\r | |
517 | } else\r | |
518 | #endif\r | |
519 | bitlen = ConfigFileEntry.global_cidr_ipv4_bitlen;\r | |
520 | \r | |
521 | return inc_global_ip(addr, bitlen);\r | |
522 | }\r | |
523 | \r | |
524 | void\r | |
525 | dec_global_cidr_count(struct Client *client_p)\r | |
526 | {\r | |
527 | struct rb_sockaddr_storage ip;\r | |
528 | struct sockaddr *addr;\r | |
529 | if(!MyClient(client_p))\r | |
530 | {\r | |
531 | if(EmptyString(client_p->sockhost) || !strcmp(client_p->sockhost, "0"))\r | |
532 | return;\r | |
533 | if(!rb_inet_pton_sock(client_p->sockhost, (struct sockaddr *)&ip))\r | |
534 | return;\r | |
535 | addr = (struct sockaddr *)&ip;\r | |
536 | } else\r | |
537 | addr = (struct sockaddr *)&client_p->localClient->ip;\r | |
538 | \r | |
539 | dec_global_ip(addr);\r | |
540 | }\r | |
541 | \r | |
542 | int\r | |
543 | check_global_cidr_count(struct Client *client_p)\r | |
544 | {\r | |
545 | struct rb_sockaddr_storage ip;\r | |
546 | struct sockaddr *addr;\r | |
547 | int count, max;\r | |
548 | if(!MyClient(client_p))\r | |
549 | {\r | |
550 | if(EmptyString(client_p->sockhost) || !strcmp(client_p->sockhost, "0"))\r | |
551 | return -1;\r | |
552 | if(!rb_inet_pton_sock(client_p->sockhost, (struct sockaddr *)&ip))\r | |
553 | return -1;\r | |
554 | addr = (struct sockaddr *)&ip;\r | |
555 | } else \r | |
556 | addr = (struct sockaddr *)&client_p->localClient->ip;\r | |
557 | count = get_global_count(addr);\r | |
558 | #ifdef RB_IPV6\r | |
559 | if(GET_SS_FAMILY(addr) == AF_INET6)\r | |
560 | max = ConfigFileEntry.global_cidr_ipv6_count;\r | |
561 | else\r | |
562 | #endif\r | |
563 | max = ConfigFileEntry.global_cidr_ipv4_count;\r | |
564 | if(count >= max)\r | |
565 | return 1;\r | |
566 | return 0;\r | |
567 | }\r | |
568 | \r | |
569 | static void\r | |
570 | clear_cidr_tree(void *data)\r | |
571 | {\r | |
572 | rb_free(data); \r | |
573 | }\r | |
574 | \r | |
575 | void\r | |
576 | rehash_global_cidr_tree(void)\r | |
577 | {\r | |
578 | struct Client *client_p;\r | |
579 | rb_dlink_node *ptr;\r | |
580 | rb_clear_patricia(global_tree, clear_cidr_tree);\r | |
581 | RB_DLINK_FOREACH(ptr, global_client_list.head)\r | |
582 | {\r | |
583 | client_p = ptr->data;\r | |
584 | if(IsMe(client_p) && IsServer(client_p))\r | |
585 | continue;\r | |
586 | inc_global_cidr_count(client_p); \r | |
587 | }\r | |
588 | return;\r | |
589 | }\r | |
590 | \r |