ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_class.c
(Generate patch)

Comparing ircd-hybrid/trunk/src/conf_class.c (file contents):
Revision 1644 by michael, Tue Nov 6 22:20:16 2012 UTC vs.
Revision 8752 by michael, Tue Jan 1 11:07:01 2019 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
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
# Line 15 | Line 15
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
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20   */
21  
22 < /*! \file
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_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"
29   #include "ircd.h"
30 < #include "listener.h"
30 > #include "conf.h"
31   #include "hostmask.h"
32 < #include "modules.h"
44 < #include "numeric.h"
45 < #include "fdlist.h"
46 < #include "log.h"
47 < #include "send.h"
48 < #include "s_gline.h"
32 > #include "irc_string.h"
33   #include "memory.h"
34 < #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"
34 > #include "patricia.h"
35  
36  
37   struct ClassItem *class_default;
38  
39 < static dlink_list class_list = { NULL, NULL, 0 };
39 > static dlink_list class_list;
40  
41  
42   const dlink_list *
# Line 70 | Line 48 | class_get_list(void)
48   struct ClassItem *
49   class_make(void)
50   {
51 <  struct ClassItem *class = MyMalloc(sizeof(*class));
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  
# Line 78 | Line 65 | class_make(void)
65   }
66  
67   void
68 < class_free(struct ClassItem *class)
68 > class_free(struct ClassItem *const class)
69   {
70 <  assert(class);
71 <  assert(class->active    == 0);
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 <  MyFree(class->name);
81 <  MyFree(class);
80 >  xfree(class->name);
81 >  xfree(class);
82   }
83  
84   void
85   class_init(void)
86   {
87    class_default = class_make();
88 <
97 <  DupString(class_default->name, "default");
98 <
99 <  class_default->active    = 1;
100 <  class_default->con_freq  = DEFAULT_CONNECTFREQUENCY;
101 <  class_default->ping_freq = DEFAULT_PINGFREQUENCY;
102 <  class_default->max_total = MAXIMUM_LINKS_DEFAULT;
103 <  class_default->max_sendq = DEFAULT_SENDQ;
104 <  class_default->max_recvq = DEFAULT_RECVQ;
88 >  class_default->name = xstrdup("default");
89   }
90  
91 < const char *
92 < get_client_class(const dlink_list *const list)
91 > const struct ClassItem *
92 > class_get_ptr(const dlink_list *const list)
93   {
94 <  const dlink_node *ptr = NULL;
94 >  const dlink_node *const node = list->head;
95  
96 <  if ((ptr = list->head)) {
97 <    const struct MaskItem *conf = ptr->data;
96 >  if (node)
97 >  {
98 >    const struct MaskItem *const conf = node->data;
99  
100      assert(conf->class);
101 <    assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
101 >    assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
102  
103 <    return conf->class->name;
103 >    return conf->class;
104    }
105  
106 <  return class_default->name;
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 <  const dlink_node *ptr = NULL;
128 <
129 <  if ((ptr = list->head)) {
130 <    const struct MaskItem *conf = ptr->data;
131 <
132 <    assert(aconf->class);
133 <    assert(aconf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
134 <
135 <    return conf->class->ping_freq;
136 <  }
137 <
138 <  return class_default->ping_freq;
118 >  return class_get_ptr(list)->ping_freq;
119   }
120  
121   unsigned int
122   get_sendq(const dlink_list *const list)
123   {
124 <  const dlink_node *ptr = NULL;
145 <
146 <  if ((ptr = list->head)) {
147 <    const struct MaskItem *conf = ptr->data;
148 <
149 <    assert(conf->class);
150 <    assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
151 <
152 <    return conf->class->max_sendq;
153 <  }
154 <
155 <  return class_default->max_sendq;
124 >  return class_get_ptr(list)->max_sendq;
125   }
126  
127   unsigned int
128   get_recvq(const dlink_list *const list)
129   {
130 <  const dlink_node *ptr = NULL;
162 <
163 <  if ((ptr = list->head)) {
164 <    const struct MaskItem *conf = ptr->data;
165 <
166 <    assert(conf->class);
167 <    assert(conf->type & (CONF_OPERATOR | CONF_CLIENT | CONF_SERVER));
168 <
169 <    return conf->class->max_recvq;
170 <  }
171 <
172 <  return class_default->max_recvq;
130 >  return class_get_ptr(list)->max_recvq;
131   }
132  
133   /*
# Line 178 | Line 136 | get_recvq(const dlink_list *const list)
136   * side effects - NONE
137   */
138   struct ClassItem *
139 < class_find(const char *name, int active)
139 > class_find(const char *name, bool active)
140   {
141 <  dlink_node *ptr = NULL;
141 >  dlink_node *node;
142  
143 <  DLINK_FOREACH(ptr, class_list.head) {
144 <    struct ClassItem *class = ptr->data;
143 >  DLINK_FOREACH(node, class_list.head)
144 >  {
145 >    struct ClassItem *class = node->data;
146  
147 <    if (!irccmp(class->name, name))
148 <      return active && !class->active ? NULL : class;
147 >    if (irccmp(class->name, name) == 0)
148 >      return active == true && class->active == true ? class : NULL;
149    }
150  
151    return NULL;
# Line 199 | Line 158 | class_find(const char *name, int active)
158   void
159   class_mark_for_deletion(void)
160   {
161 <  dlink_node *ptr = NULL;
161 >  dlink_node *node;
162  
163 <  DLINK_FOREACH(ptr, class_list.head)
164 <  {
206 <    struct ClassItem *class = ptr->data;
207 <
208 <    if (class != class_default)
209 <      class->active = 0;
210 <  }
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 *ptr = NULL, *ptr_next = NULL;
170 >  dlink_node *node, *node_next;
171  
172 <  DLINK_FOREACH_SAFE(ptr, ptr_next, class_list.head) {
173 <    struct ClassItem *class = ptr->data;
172 >  DLINK_FOREACH_SAFE(node, node_next, class_list.head)
173 >  {
174 >    struct ClassItem *class = node->data;
175  
176 <    if (!class->active && !class->ref_count)
222 <    {
223 <      destroy_cidr_class(class);
176 >    if (class->active == false && class->ref_count == 0)
177        class_free(class);
225 –    }
178    }
179   }
180  
181 < /*
182 < * cidr_limit_reached
231 < *
232 < * inputs       - int flag allowing over_rule of limits
233 < *              - pointer to the ip to be added
234 < *              - pointer to the class
235 < * output       - non zero if limit reached
236 < *                0 if limit not reached
237 < * side effects -
238 < */
239 < int
240 < cidr_limit_reached(int over_rule,
241 <                   struct irc_ssaddr *ip, struct ClassItem *class)
181 > static void *
182 > class_ip_limit_trie(struct ClassItem *class, void *addr)
183   {
184 <  dlink_node *ptr = NULL;
185 <  struct CidrItem *cidr = NULL;
186 <
187 <  if (class->number_per_cidr == 0)
247 <    return 0;
248 <
249 <  if (ip->ss.ss_family == AF_INET)
250 <  {
251 <    if (class->cidr_bitlen_ipv4 == 0)
252 <      return 0;
253 <
254 <    DLINK_FOREACH(ptr, class->list_ipv4.head)
255 <    {
256 <      cidr = ptr->data;
257 <      if (match_ipv4(ip, &cidr->mask, class->cidr_bitlen_ipv4))
258 <      {
259 <        if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
260 <          return -1;
261 <        cidr->number_on_this_cidr++;
262 <        return 0;
263 <      }
264 <    }
265 <    cidr = MyMalloc(sizeof(struct CidrItem));
266 <    cidr->number_on_this_cidr = 1;
267 <    cidr->mask = *ip;
268 <    mask_addr(&cidr->mask, class->cidr_bitlen_ipv4);
269 <    dlinkAdd(cidr, &cidr->node, &class->list_ipv4);
270 <  }
271 < #ifdef IPV6
272 <  else if (class->cidr_bitlen_ipv6 > 0)
273 <  {
274 <    DLINK_FOREACH(ptr, class->list_ipv6.head)
275 <    {
276 <      cidr = ptr->data;
277 <      if (match_ipv6(ip, &cidr->mask, class->cidr_bitlen_ipv6))
278 <      {
279 <        if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
280 <          return -1;
281 <        cidr->number_on_this_cidr++;
282 <        return 0;
283 <      }
284 <    }
285 <    cidr = MyMalloc(sizeof(struct CidrItem));
286 <    cidr->number_on_this_cidr = 1;
287 <    cidr->mask = *ip;
288 <    mask_addr(&cidr->mask, class->cidr_bitlen_ipv6);
289 <    dlinkAdd(cidr, &cidr->node, &class->list_ipv6);
290 <  }
291 < #endif
292 <  return 0;
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 < /*
191 < * remove_from_cidr_check
297 < *
298 < * inputs       - pointer to the ip to be removed
299 < *              - pointer to the class
300 < * output       - NONE
301 < * side effects -
302 < */
303 < void
304 < remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
190 > bool
191 > class_ip_limit_add(struct ClassItem *class, void *addr, bool over_rule)
192   {
193 <  dlink_node *ptr = NULL;
307 <  dlink_node *next_ptr = NULL;
308 <  struct CidrItem *cidr;
193 >  int bitlen;
194  
195 <  if (aclass->number_per_cidr == 0)
196 <    return;
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 (ip->ss.ss_family == AF_INET)
201 <  {
315 <    if (aclass->cidr_bitlen_ipv4 == 0)
316 <      return;
200 >  if (class->number_per_cidr == 0 || bitlen == 0)
201 >    return false;
202  
203 <    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
204 <    {
205 <      cidr = ptr->data;
206 <      if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
207 <      {
208 <        cidr->number_on_this_cidr--;
324 <        if (cidr->number_on_this_cidr == 0)
325 <        {
326 <          dlinkDelete(ptr, &aclass->list_ipv4);
327 <          MyFree(cidr);
328 <          return;
329 <        }
330 <      }
331 <    }
332 <  }
333 < #ifdef IPV6
334 <  else if (aclass->cidr_bitlen_ipv6 > 0)
335 <  {
336 <    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
337 <    {
338 <      cidr = ptr->data;
339 <      if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
340 <      {
341 <        cidr->number_on_this_cidr--;
342 <        if (cidr->number_on_this_cidr == 0)
343 <        {
344 <          dlinkDelete(ptr, &aclass->list_ipv6);
345 <          MyFree(cidr);
346 <          return;
347 <        }
348 <      }
349 <    }
350 <  }
351 < #endif
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 < static void
212 < rebuild_cidr_list(int aftype, struct ClassItem *oldcl, struct ClassItem *newcl,
356 <                  dlink_list *old_list, dlink_list *new_list, int changed)
211 > bool
212 > class_ip_limit_remove(struct ClassItem *class, void *addr)
213   {
214 <  dlink_node *ptr;
359 <  struct Client *client_p;
360 <  struct MaskItem *conf;
214 >  int bitlen;
215  
216 <  if (!changed)
217 <  {
218 <    *new_list = *old_list;
219 <    old_list->head = old_list->tail = NULL;
366 <    old_list->length = 0;
367 <    return;
368 <  }
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 <  DLINK_FOREACH(ptr, local_client_list.head)
222 <  {
372 <    client_p = ptr->data;
373 <    if (client_p->localClient->aftype != aftype)
374 <      continue;
375 <    if (dlink_list_length(&client_p->localClient->confs) == 0)
376 <      continue;
221 >  if (class->number_per_cidr == 0 || bitlen == 0)
222 >    return false;
223  
224 <    conf = client_p->localClient->confs.tail->data;
225 <    if (conf->type == CONF_CLIENT)
226 <      if (conf->class == oldcl)
381 <        cidr_limit_reached(1, &client_p->localClient->ip, newcl);
382 <  }
383 < }
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 < /*
229 < * rebuild_cidr_class
230 < *
388 < * inputs       - pointer to old conf
389 < *              - pointer to new_class
390 < * output       - none
391 < * side effects - rebuilds the class link list of cidr blocks
392 < */
393 < void
394 < rebuild_cidr_class(struct ClassItem *old_class, struct ClassItem *new_class)
395 < {
396 <  if (old_class->number_per_cidr > 0 && new_class->number_per_cidr > 0)
228 >  PATRICIA_DATA_SET(pnode, (((uintptr_t)pnode->data) - 1));
229 >
230 >  if (((uintptr_t)pnode->data) == 0)
231    {
232 <    if (old_class->cidr_bitlen_ipv4 > 0 && new_class->cidr_bitlen_ipv4 > 0)
233 <      rebuild_cidr_list(AF_INET, old_class, new_class,
400 <                        &old_class->list_ipv4, &new_class->list_ipv4,
401 <                        old_class->cidr_bitlen_ipv4 != new_class->cidr_bitlen_ipv4);
402 <
403 < #ifdef IPV6
404 <    if (old_class->cidr_bitlen_ipv6 > 0 && new_class->cidr_bitlen_ipv6 > 0)
405 <      rebuild_cidr_list(AF_INET6, old_class, new_class,
406 <                        &old_class->list_ipv6, &new_class->list_ipv6,
407 <                        old_class->cidr_bitlen_ipv6 != new_class->cidr_bitlen_ipv6);
408 < #endif
232 >    patricia_remove(class_ip_limit_trie(class, addr), pnode);
233 >    return true;
234    }
235  
236 <  destroy_cidr_class(old_class);
236 >  return false;
237   }
238  
239 < /*
240 < * destroy_cidr_list
416 < *
417 < * inputs       - pointer to class dlink list of cidr blocks
418 < * output       - none
419 < * side effects - completely destroys the class link list of cidr blocks
420 < */
421 < static void
422 < destroy_cidr_list(dlink_list *list)
239 > void
240 > class_ip_limit_rebuild(struct ClassItem *class)
241   {
242 <  dlink_node *ptr = NULL, *next_ptr = NULL;
242 >  dlink_node *node;
243  
244 <  DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
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 <    dlinkDelete(ptr, list);
250 <    MyFree(ptr->data);
430 <  }
431 < }
249 >    struct Client *client_p = node->data;
250 >    struct MaskItem *conf = client_p->connection->confs.tail->data;
251  
252 < /*
253 < * destroy_cidr_class
254 < *
255 < * inputs       - pointer to class
437 < * output       - none
438 < * side effects - completely destroys the class link list of cidr blocks
439 < */
440 < void
441 < destroy_cidr_class(struct ClassItem *class)
442 < {
443 <  destroy_cidr_list(&class->list_ipv4);
444 <  destroy_cidr_list(&class->list_ipv6);
252 >    if (conf->type == CONF_CLIENT)
253 >      if (conf->class == class)
254 >        class_ip_limit_add(class, &client_p->ip, true);
255 >  }
256   }

Comparing ircd-hybrid/trunk/src/conf_class.c (property svn:eol-style):
Revision 1644 by michael, Tue Nov 6 22:20:16 2012 UTC vs.
Revision 8752 by michael, Tue Jan 1 11:07:01 2019 UTC

# Line 0 | Line 1
1 + native

Comparing ircd-hybrid/trunk/src/conf_class.c (property svn:executable):
Revision 1644 by michael, Tue Nov 6 22:20:16 2012 UTC vs.
Revision 8752 by michael, Tue Jan 1 11:07:01 2019 UTC

# Line 1 | Line 0
1 – *

Diff Legend

– Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)