ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 9857
Committed: Fri Jan 1 04:43:22 2021 UTC (5 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 5854 byte(s)
Log Message:
- Bump copyright years

File Contents

# User Rev Content
1 michael 1633 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 michael 1633 *
4 michael 9857 * Copyright (c) 1997-2021 ircd-hybrid development team
5 michael 1633 *
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 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 michael 1633 * USA
20     */
21    
22 michael 2916 /*! \file conf_class.c
23 michael 1633 * \brief Configuration managment for class{} blocks
24 michael 1635 * \version $Id$
25 michael 1633 */
26    
27     #include "stdinc.h"
28     #include "list.h"
29 michael 1658 #include "ircd.h"
30 michael 1633 #include "conf.h"
31 michael 1658 #include "hostmask.h"
32 michael 1633 #include "irc_string.h"
33     #include "memory.h"
34 michael 8607 #include "patricia.h"
35 michael 1633
36    
37     struct ClassItem *class_default;
38    
39 michael 3250 static dlink_list class_list;
40 michael 1633
41    
42     const dlink_list *
43     class_get_list(void)
44     {
45     return &class_list;
46     }
47    
48     struct ClassItem *
49     class_make(void)
50     {
51 michael 8431 struct ClassItem *class = xcalloc(sizeof(*class));
52 michael 1633
53 michael 8702 class->active = true;
54     class->con_freq = DEFAULT_CONNECTFREQUENCY;
55 michael 1650 class->ping_freq = DEFAULT_PINGFREQUENCY;
56     class->max_sendq = DEFAULT_SENDQ;
57     class->max_recvq = DEFAULT_RECVQ;
58 michael 8611 class->ip_tree_v6 = patricia_new(128);
59     class->ip_tree_v4 = patricia_new( 32);
60 michael 1650
61 michael 1633 dlinkAdd(class, &class->node, &class_list);
62    
63     return class;
64     }
65    
66     void
67 michael 4874 class_free(struct ClassItem *const class)
68 michael 1633 {
69 michael 3547 assert(class != class_default);
70 michael 8660 assert(class->active == false);
71 michael 1633 assert(class->ref_count == 0);
72    
73 michael 8611 if (class->ip_tree_v6)
74     patricia_destroy(class->ip_tree_v6, NULL);
75     if (class->ip_tree_v4)
76     patricia_destroy(class->ip_tree_v4, NULL);
77 michael 8607
78 michael 1633 dlinkDelete(&class->node, &class_list);
79 michael 7032 xfree(class->name);
80     xfree(class);
81 michael 1633 }
82    
83     void
84     class_init(void)
85     {
86 michael 7937 class_default = class_make();
87     class_default->name = xstrdup("default");
88 michael 1633 }
89    
90 michael 5411 const struct ClassItem *
91 michael 8437 class_get_ptr(const dlink_list *const list)
92 michael 1783 {
93 michael 4848 const dlink_node *const node = list->head;
94 michael 1783
95 michael 4848 if (node)
96 michael 2213 {
97 michael 4833 const struct MaskItem *const conf = node->data;
98 michael 1783
99     assert(conf->class);
100     assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
101    
102     return conf->class;
103     }
104    
105     return class_default;
106     }
107    
108 michael 1633 const char *
109     get_client_class(const dlink_list *const list)
110     {
111 michael 8437 return class_get_ptr(list)->name;
112 michael 1633 }
113    
114     unsigned int
115 michael 1644 get_client_ping(const dlink_list *const list)
116 michael 1633 {
117 michael 8437 return class_get_ptr(list)->ping_freq;
118 michael 1633 }
119    
120     unsigned int
121     get_sendq(const dlink_list *const list)
122     {
123 michael 8437 return class_get_ptr(list)->max_sendq;
124 michael 1633 }
125    
126     unsigned int
127     get_recvq(const dlink_list *const list)
128     {
129 michael 8437 return class_get_ptr(list)->max_recvq;
130 michael 1633 }
131    
132     /*
133     * inputs - Integer (Number of class)
134     * output - Pointer to ClassItem struct. Non-NULL expected
135     * side effects - NONE
136     */
137     struct ClassItem *
138 michael 8660 class_find(const char *name, bool active)
139 michael 1633 {
140 michael 8059 dlink_node *node;
141 michael 1633
142 michael 4800 DLINK_FOREACH(node, class_list.head)
143 michael 2213 {
144 michael 4800 struct ClassItem *class = node->data;
145 michael 1633
146 michael 8522 if (irccmp(class->name, name) == 0)
147 michael 9709 {
148     if (active == true && class->active == false)
149     return NULL;
150    
151     return class;
152     }
153 michael 1633 }
154    
155     return NULL;
156     }
157    
158     /*
159     * We don't delete the class table, rather mark all entries for deletion.
160     * The table is cleaned up by delete_marked_classes. - avalon
161     */
162     void
163     class_mark_for_deletion(void)
164     {
165 michael 8059 dlink_node *node;
166 michael 1633
167 michael 4800 DLINK_FOREACH_PREV(node, class_list.tail->prev)
168 michael 9617 {
169     struct ClassItem *class = node->data;
170     class->active = false;
171     }
172 michael 1633 }
173    
174     void
175     class_delete_marked(void)
176     {
177 michael 8059 dlink_node *node, *node_next;
178 michael 1633
179 michael 4800 DLINK_FOREACH_SAFE(node, node_next, class_list.head)
180 michael 2213 {
181 michael 4800 struct ClassItem *class = node->data;
182 michael 1633
183 michael 8660 if (class->active == false && class->ref_count == 0)
184 michael 1633 class_free(class);
185     }
186     }
187    
188 michael 8611 static void *
189     class_ip_limit_trie(struct ClassItem *class, void *addr)
190     {
191     if (((struct sockaddr *)addr)->sa_family == AF_INET6)
192     return class->ip_tree_v6;
193     else
194     return class->ip_tree_v4;
195     }
196    
197 michael 8658 bool
198 michael 8660 class_ip_limit_add(struct ClassItem *class, void *addr, bool over_rule)
199 michael 1633 {
200 michael 8607 int bitlen;
201 michael 1633
202 michael 8608 if (((struct sockaddr *)addr)->sa_family == AF_INET6)
203 michael 8607 bitlen = class->cidr_bitlen_ipv6;
204     else
205     bitlen = class->cidr_bitlen_ipv4;
206    
207     if (class->number_per_cidr == 0 || bitlen == 0)
208 michael 8658 return false;
209 michael 1633
210 michael 8611 patricia_node_t *pnode = patricia_make_and_lookup_addr(class_ip_limit_trie(class, addr), addr, bitlen);
211 michael 8660 if (((uintptr_t)pnode->data) >= class->number_per_cidr && over_rule == false)
212 michael 8658 return true;
213 michael 1633
214 michael 8607 PATRICIA_DATA_SET(pnode, (((uintptr_t)pnode->data) + 1));
215 michael 8658 return false;
216 michael 1633 }
217    
218 michael 8658 bool
219 michael 8608 class_ip_limit_remove(struct ClassItem *class, void *addr)
220 michael 1633 {
221 michael 8607 int bitlen;
222 michael 1633
223 michael 8608 if (((struct sockaddr *)addr)->sa_family == AF_INET6)
224 michael 8607 bitlen = class->cidr_bitlen_ipv6;
225     else
226     bitlen = class->cidr_bitlen_ipv4;
227 michael 1633
228 michael 8607 if (class->number_per_cidr == 0 || bitlen == 0)
229 michael 8658 return false;
230 michael 1633
231 michael 8611 patricia_node_t *pnode = patricia_try_search_best_addr(class_ip_limit_trie(class, addr), addr, 0);
232 michael 8607 if (pnode == NULL)
233 michael 8658 return false;
234 michael 2213
235 michael 8607 PATRICIA_DATA_SET(pnode, (((uintptr_t)pnode->data) - 1));
236 michael 2213
237 michael 8607 if (((uintptr_t)pnode->data) == 0)
238     {
239 michael 8611 patricia_remove(class_ip_limit_trie(class, addr), pnode);
240 michael 8658 return true;
241 michael 1633 }
242 michael 2213
243 michael 8658 return false;
244 michael 1633 }
245    
246 michael 1647 void
247 michael 8607 class_ip_limit_rebuild(struct ClassItem *class)
248 michael 1633 {
249 michael 8059 dlink_node *node;
250 michael 1633
251 michael 8611 patricia_clear(class->ip_tree_v6, NULL);
252     patricia_clear(class->ip_tree_v4, NULL);
253 michael 1633
254 michael 4800 DLINK_FOREACH(node, local_client_list.head)
255 michael 1633 {
256 michael 9250 struct Client *client = node->data;
257     struct MaskItem *conf = client->connection->confs.tail->data;
258 michael 1633
259 michael 8607 if (conf->type == CONF_CLIENT)
260 michael 1647 if (conf->class == class)
261 michael 9250 class_ip_limit_add(class, &client->ip, true);
262 michael 1633 }
263     }

Properties

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