ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/conf/class.c
Revision: 719
Committed: Sun Jul 16 16:56:58 2006 UTC (20 years ago) by adx
Content type: text/x-csrc
File size: 6453 byte(s)
Log Message:
+ reworked operator{} blocks to make them independent from oldconf
+ moved some utilities from s_conf.* to libio
+ added stub for auth{} blocks

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * class.c: Defines the class{} block of ircd.conf.
4 *
5 * Copyright (C) 2005 by the Hybrid Development Team.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "conf/conf.h"
27
28 struct CidrItem
29 {
30 struct irc_ssaddr mask;
31 int number_on_this_cidr;
32 dlink_node node;
33 };
34
35 struct Class *default_class = NULL;
36
37 static dlink_list class_list = {NULL, NULL, 0};
38 static dlink_node *enum_node = NULL;
39 static dlink_node *hreset, *hverify;
40 static struct Class tmpclass;
41
42 //
43 // Low configuration layer: object storage and reference counting.
44 //
45
46 struct Class *
47 ref_class_by_name(const char *name)
48 {
49 dlink_node *ptr;
50
51 DLINK_FOREACH(ptr, class_list.head)
52 {
53 struct Class *cl = ptr->data;
54
55 if (!strcasecmp(cl->name, name))
56 return ref_class_by_ptr(cl);
57 }
58
59 return NULL;
60 }
61
62 struct Class *
63 ref_class_by_ptr(struct Class *cl)
64 {
65 cl->refcnt++;
66 return cl;
67 }
68
69 static void
70 destroy_cidr_list(dlink_list *l)
71 {
72 while (l->head != NULL)
73 {
74 struct CidrItem *cidr = l->head->data;
75
76 dlinkDelete(&cidr->node, l);
77 MyFree(cidr);
78 }
79 }
80
81 void
82 unref_class(struct Class *cl)
83 {
84 assert(cl->refcnt > 0);
85
86 if (--cl->refcnt == 0)
87 {
88 destroy_cidr_list(&cl->list_ipv4);
89 destroy_cidr_list(&cl->list_ipv6);
90 MyFree(cl);
91 }
92 }
93
94 struct Class *
95 make_class(const char *name)
96 {
97 struct Class *cl = MyMalloc(sizeof(struct Class));
98
99 DupString(cl->name, name);
100
101 ref_class_by_ptr(cl);
102 dlinkAddTail(cl, &cl->node, &class_list);
103
104 return cl;
105 }
106
107 void
108 delete_class(struct Class *cl)
109 {
110 if (&cl->node == enum_node)
111 enum_node = cl->node.next;
112
113 dlinkDelete(&cl->node, &class_list);
114 unref_class(cl);
115 }
116
117 void
118 enum_classes(ENUMCLASSFUNC ef)
119 {
120 dlink_node *ptr;
121
122 DLINK_FOREACH_SAFE(ptr, enum_node, class_list.head)
123 ef(ptr->data);
124 }
125
126 //
127 // TODO: Class matching and assigning (limits!)
128 //
129
130 //
131 // Configuration manager interface.
132 //
133
134 static void do_reset_class(struct Class *cl)
135 {
136 if (cl != default_class)
137 cl->stale = YES;
138 }
139
140 static void do_verify_class(struct Class *cl)
141 {
142 if (cl->stale)
143 delete_class(cl);
144 }
145
146 static void *
147 reset_classes(va_list args)
148 {
149 default_class->connectfreq = DEFAULT_CONNECTFREQUENCY;
150 default_class->ping_time = DEFAULT_PINGFREQUENCY;
151 default_class->max_number = MAXIMUM_LINKS_DEFAULT;
152 default_class->sendq_size = DEFAULT_SENDQ;
153
154 enum_classes(do_reset_class);
155 return pass_callback(hreset);
156 }
157
158 static void *
159 verify_classes(va_list args)
160 {
161 enum_classes(do_verify_class);
162 return pass_callback(hverify);
163 }
164
165 static void
166 before_class(void)
167 {
168 memset(&tmpclass, 0, sizeof(tmpclass));
169 }
170
171 static void
172 after_class(void)
173 {
174 struct Class *cl;
175
176 if (tmpclass.name == NULL)
177 return;
178
179 if ((cl = ref_class_by_name(tmpclass.name)) == NULL)
180 {
181 cl = make_class(tmpclass.name);
182 MyFree(tmpclass.name);
183 }
184 else
185 {
186 cl->name = tmpclass.name;
187 unref_class(cl);
188 }
189
190 cl->connectfreq = tmpclass.connectfreq;
191 cl->ping_time = tmpclass.ping_time;
192 cl->ping_warning = tmpclass.ping_warning;
193 cl->sendq_size = tmpclass.sendq_size;
194
195 memcpy(cl->userhost_limit, tmpclass.userhost_limit,
196 sizeof(cl->userhost_limit));
197 memcpy(cl->host_limit, tmpclass.host_limit, sizeof(cl->host_limit));
198
199 // TODO: number per cidr stuff ..
200
201 cl->max_ident = tmpclass.max_ident;
202 cl->max_noident = tmpclass.max_noident;
203 cl->max_number = tmpclass.max_number;
204
205 cl->stale = NO;
206 }
207
208 static void
209 local_or_global_limit(void *value, void *where)
210 {
211 dlink_list *list = value;
212 dlink_node *ptr;
213
214 DLINK_FOREACH(ptr, list->head)
215 {
216 char *item = ptr->data, *s;
217 int type = 0; // assume local
218
219 if ((s = strchr(item, ':')) != NULL)
220 {
221 *s++ = 0;
222 if (!strcasecmp(item, "global"))
223 type = 1;
224 else if (strcasecmp(item, "local"))
225 {
226 parse_error("unknown limit type [%s]", item);
227 return;
228 }
229 }
230 else
231 s = item;
232
233 *(((int *) where) + type) = atoi(s);
234 }
235 }
236
237 void
238 init_class(void)
239 {
240 struct ConfSection *s = add_conf_section("class", 1);
241
242 hreset = install_hook(reset_conf, reset_classes);
243 hverify = install_hook(verify_conf, verify_classes);
244
245 s->before = before_class;
246
247 s->def_field = add_conf_field(s, "name", CT_STRING, NULL, &tmpclass.name);
248 add_conf_field(s, "connectfreq", CT_TIME, NULL, &tmpclass.connectfreq);
249 add_conf_field(s, "ping_time", CT_TIME, NULL, &tmpclass.ping_time);
250 add_conf_field(s, "ping_warning", CT_TIME, NULL, &tmpclass.ping_warning);
251 add_conf_field(s, "sendq", CT_SIZE, NULL, &tmpclass.sendq_size);
252
253 add_conf_field(s, "host_limit", CT_LIST, local_or_global_limit,
254 &tmpclass.host_limit);
255 add_conf_field(s, "number_per_ip", CT_NUMBER, local_or_global_limit,
256 &tmpclass.host_limit);
257 add_conf_field(s, "userhost_limit", CT_LIST, local_or_global_limit,
258 &tmpclass.userhost_limit);
259 add_conf_field(s, "number_per_userhost", CT_NUMBER, local_or_global_limit,
260 &tmpclass.userhost_limit);
261
262 add_conf_field(s, "number_per_cidr", CT_NUMBER, NULL,
263 &tmpclass.number_per_cidr);
264 add_conf_field(s, "cidr_bitlen_ipv4", CT_NUMBER, NULL,
265 &tmpclass.cidr_bitlen_ipv4);
266 add_conf_field(s, "cidr_bitlen_ipv6", CT_NUMBER, NULL,
267 &tmpclass.cidr_bitlen_ipv4);
268
269 add_conf_field(s, "max_ident", CT_NUMBER, NULL, &tmpclass.max_ident);
270 add_conf_field(s, "max_noident", CT_NUMBER, NULL, &tmpclass.max_noident);
271 add_conf_field(s, "max_number", CT_NUMBER, NULL, &tmpclass.max_number);
272
273 // for backwards compatibility only, these names really sucked
274 add_conf_field(s, "max_local", CT_NUMBER, NULL,
275 &tmpclass.userhost_limit[0]);
276 add_conf_field(s, "max_global", CT_NUMBER, NULL,
277 &tmpclass.userhost_limit[1]);
278
279 s->after = after_class;
280
281 default_class = make_class("default");
282
283 }

Properties

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