ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
Revision: 8752
Committed: Tue Jan 1 11:07:01 2019 UTC (6 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 5844 byte(s)
Log Message:
- Update copyright years

File Contents

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

Properties

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