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 1666 by michael, Sun Nov 18 17:03:18 2012 UTC vs.
Revision 8607 by michael, Mon Oct 29 21:26:54 2018 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-2018 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   */
# Line 31 | Line 31
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 = { NULL, NULL, 0 };
39 > static dlink_list class_list;
40  
41  
42   const dlink_list *
# Line 47 | 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    = 1;
54    class->con_freq  = DEFAULT_CONNECTFREQUENCY;
# Line 55 | Line 56 | class_make(void)
56    class->max_total = MAXIMUM_LINKS_DEFAULT;
57    class->max_sendq = DEFAULT_SENDQ;
58    class->max_recvq = DEFAULT_RECVQ;
59 +  class->ip_tree   = patricia_new(PATRICIA_MAXBITS);
60  
61    dlinkAdd(class, &class->node, &class_list);
62  
# Line 62 | Line 64 | class_make(void)
64   }
65  
66   void
67 < class_free(struct ClassItem *class)
67 > class_free(struct ClassItem *const class)
68   {
69 <  assert(class);
69 >  assert(class != class_default);
70    assert(class->active    == 0);
71    assert(class->ref_count == 0);
72  
73 +  if (class->ip_tree)
74 +    patricia_destroy(class->ip_tree, NULL);
75 +
76    dlinkDelete(&class->node, &class_list);
77 <  MyFree(class->name);
78 <  MyFree(class);
77 >  xfree(class->name);
78 >  xfree(class);
79   }
80  
81   void
82   class_init(void)
83   {
84 <  (class_default = class_make())->name = xstrdup("default");
84 >  class_default = class_make();
85 >  class_default->name = xstrdup("default");
86   }
87  
88 < const char *
89 < get_client_class(const dlink_list *const list)
88 > const struct ClassItem *
89 > class_get_ptr(const dlink_list *const list)
90   {
91 <  const dlink_node *ptr = NULL;
91 >  const dlink_node *const node = list->head;
92  
93 <  if ((ptr = list->head)) {
94 <    const struct MaskItem *conf = ptr->data;
93 >  if (node)
94 >  {
95 >    const struct MaskItem *const conf = node->data;
96  
97      assert(conf->class);
98      assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
99  
100 <    return conf->class->name;
100 >    return conf->class;
101    }
102  
103 <  return class_default->name;
103 >  return class_default;
104 > }
105 >
106 > const char *
107 > get_client_class(const dlink_list *const list)
108 > {
109 >  return class_get_ptr(list)->name;
110   }
111  
112   unsigned int
113   get_client_ping(const dlink_list *const list)
114   {
115 <  const dlink_node *ptr = NULL;
103 <
104 <  if ((ptr = list->head)) {
105 <    const struct MaskItem *conf = ptr->data;
106 <
107 <    assert(conf->class);
108 <    assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
109 <
110 <    return conf->class->ping_freq;
111 <  }
112 <
113 <  return class_default->ping_freq;
115 >  return class_get_ptr(list)->ping_freq;
116   }
117  
118   unsigned int
119   get_sendq(const dlink_list *const list)
120   {
121 <  const dlink_node *ptr = NULL;
120 <
121 <  if ((ptr = list->head)) {
122 <    const struct MaskItem *conf = ptr->data;
123 <
124 <    assert(conf->class);
125 <    assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
126 <
127 <    return conf->class->max_sendq;
128 <  }
129 <
130 <  return class_default->max_sendq;
121 >  return class_get_ptr(list)->max_sendq;
122   }
123  
124   unsigned int
125   get_recvq(const dlink_list *const list)
126   {
127 <  const dlink_node *ptr = NULL;
137 <
138 <  if ((ptr = list->head)) {
139 <    const struct MaskItem *conf = ptr->data;
140 <
141 <    assert(conf->class);
142 <    assert(conf->type & (CONF_OPER | CONF_CLIENT | CONF_SERVER));
143 <
144 <    return conf->class->max_recvq;
145 <  }
146 <
147 <  return class_default->max_recvq;
127 >  return class_get_ptr(list)->max_recvq;
128   }
129  
130   /*
# Line 155 | Line 135 | get_recvq(const dlink_list *const list)
135   struct ClassItem *
136   class_find(const char *name, int active)
137   {
138 <  dlink_node *ptr = NULL;
138 >  dlink_node *node;
139  
140 <  DLINK_FOREACH(ptr, class_list.head) {
141 <    struct ClassItem *class = ptr->data;
140 >  DLINK_FOREACH(node, class_list.head)
141 >  {
142 >    struct ClassItem *class = node->data;
143  
144 <    if (!irccmp(class->name, name))
145 <      return active && !class->active ? NULL : class;
144 >    if (irccmp(class->name, name) == 0)
145 >      return active && class->active == 0 ? NULL : class;
146    }
147  
148    return NULL;
# Line 174 | Line 155 | class_find(const char *name, int active)
155   void
156   class_mark_for_deletion(void)
157   {
158 <  dlink_node *ptr = NULL;
158 >  dlink_node *node;
159  
160 <  DLINK_FOREACH_PREV(ptr, class_list.tail->prev)
161 <    ((struct ClassItem *)ptr->data)->active = 0;
160 >  DLINK_FOREACH_PREV(node, class_list.tail->prev)
161 >    ((struct ClassItem *)node->data)->active = 0;
162   }
163  
164   void
165   class_delete_marked(void)
166   {
167 <  dlink_node *ptr = NULL, *ptr_next = NULL;
167 >  dlink_node *node, *node_next;
168  
169 <  DLINK_FOREACH_SAFE(ptr, ptr_next, class_list.head) {
170 <    struct ClassItem *class = ptr->data;
169 >  DLINK_FOREACH_SAFE(node, node_next, class_list.head)
170 >  {
171 >    struct ClassItem *class = node->data;
172  
173 <    if (!class->active && !class->ref_count)
192 <    {
193 <      destroy_cidr_class(class);
173 >    if (class->active == 0 && class->ref_count == 0)
174        class_free(class);
195    }
175    }
176   }
177  
199 /*
200 * cidr_limit_reached
201 *
202 * inputs       - int flag allowing over_rule of limits
203 *              - pointer to the ip to be added
204 *              - pointer to the class
205 * output       - non zero if limit reached
206 *                0 if limit not reached
207 * side effects -
208 */
178   int
179 < cidr_limit_reached(int over_rule,
211 <                   struct irc_ssaddr *ip, struct ClassItem *class)
179 > class_ip_limit_add(struct ClassItem *class, struct sockaddr *addr, int over_rule)
180   {
181 <  dlink_node *ptr = NULL;
214 <  struct CidrItem *cidr = NULL;
181 >  int bitlen;
182  
183 <  if (class->number_per_cidr == 0)
183 >  if (addr->sa_family == AF_INET6)
184 >    bitlen = class->cidr_bitlen_ipv6;
185 >  else
186 >    bitlen = class->cidr_bitlen_ipv4;
187 >
188 >  if (class->number_per_cidr == 0 || bitlen == 0)
189      return 0;
190  
191 <  if (ip->ss.ss_family == AF_INET)
192 <  {
193 <    if (class->cidr_bitlen_ipv4 == 0)
222 <      return 0;
191 >  patricia_node_t *pnode = patricia_make_and_lookup_addr(class->ip_tree, addr, bitlen);
192 >  if (((uintptr_t)pnode->data) >= class->number_per_cidr && over_rule == 0)
193 >    return 1;
194  
195 <    DLINK_FOREACH(ptr, class->list_ipv4.head)
225 <    {
226 <      cidr = ptr->data;
227 <      if (match_ipv4(ip, &cidr->mask, class->cidr_bitlen_ipv4))
228 <      {
229 <        if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
230 <          return -1;
231 <        cidr->number_on_this_cidr++;
232 <        return 0;
233 <      }
234 <    }
235 <    cidr = MyMalloc(sizeof(struct CidrItem));
236 <    cidr->number_on_this_cidr = 1;
237 <    cidr->mask = *ip;
238 <    mask_addr(&cidr->mask, class->cidr_bitlen_ipv4);
239 <    dlinkAdd(cidr, &cidr->node, &class->list_ipv4);
240 <  }
241 < #ifdef IPV6
242 <  else if (class->cidr_bitlen_ipv6 > 0)
243 <  {
244 <    DLINK_FOREACH(ptr, class->list_ipv6.head)
245 <    {
246 <      cidr = ptr->data;
247 <      if (match_ipv6(ip, &cidr->mask, class->cidr_bitlen_ipv6))
248 <      {
249 <        if (!over_rule && (cidr->number_on_this_cidr >= class->number_per_cidr))
250 <          return -1;
251 <        cidr->number_on_this_cidr++;
252 <        return 0;
253 <      }
254 <    }
255 <    cidr = MyMalloc(sizeof(struct CidrItem));
256 <    cidr->number_on_this_cidr = 1;
257 <    cidr->mask = *ip;
258 <    mask_addr(&cidr->mask, class->cidr_bitlen_ipv6);
259 <    dlinkAdd(cidr, &cidr->node, &class->list_ipv6);
260 <  }
261 < #endif
195 >  PATRICIA_DATA_SET(pnode, (((uintptr_t)pnode->data) + 1));
196    return 0;
197   }
198  
199 < /*
200 < * remove_from_cidr_check
267 < *
268 < * inputs       - pointer to the ip to be removed
269 < *              - pointer to the class
270 < * output       - NONE
271 < * side effects -
272 < */
273 < void
274 < remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
199 > int
200 > class_ip_limit_remove(struct ClassItem *class, struct sockaddr *addr)
201   {
202 <  dlink_node *ptr = NULL;
277 <  dlink_node *next_ptr = NULL;
278 <  struct CidrItem *cidr;
202 >  int bitlen;
203  
204 <  if (aclass->number_per_cidr == 0)
205 <    return;
204 >  if (addr->sa_family == AF_INET6)
205 >    bitlen = class->cidr_bitlen_ipv6;
206 >  else
207 >    bitlen = class->cidr_bitlen_ipv4;
208  
209 <  if (ip->ss.ss_family == AF_INET)
210 <  {
285 <    if (aclass->cidr_bitlen_ipv4 == 0)
286 <      return;
209 >  if (class->number_per_cidr == 0 || bitlen == 0)
210 >    return 0;
211  
212 <    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
213 <    {
214 <      cidr = ptr->data;
215 <      if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
216 <      {
217 <        cidr->number_on_this_cidr--;
218 <        if (cidr->number_on_this_cidr == 0)
295 <        {
296 <          dlinkDelete(ptr, &aclass->list_ipv4);
297 <          MyFree(cidr);
298 <          return;
299 <        }
300 <      }
301 <    }
302 <  }
303 < #ifdef IPV6
304 <  else if (aclass->cidr_bitlen_ipv6 > 0)
212 >  patricia_node_t *pnode = patricia_try_search_best_addr(class->ip_tree, addr, 0);
213 >  if (pnode == NULL)
214 >    return 0;
215 >
216 >  PATRICIA_DATA_SET(pnode, (((uintptr_t)pnode->data) - 1));
217 >
218 >  if (((uintptr_t)pnode->data) == 0)
219    {
220 <    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
221 <    {
308 <      cidr = ptr->data;
309 <      if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
310 <      {
311 <        cidr->number_on_this_cidr--;
312 <        if (cidr->number_on_this_cidr == 0)
313 <        {
314 <          dlinkDelete(ptr, &aclass->list_ipv6);
315 <          MyFree(cidr);
316 <          return;
317 <        }
318 <      }
319 <    }
220 >    patricia_remove(class->ip_tree, pnode);
221 >    return 1;
222    }
223 < #endif
223 >
224 >  return 0;
225   }
226  
227   void
228 < rebuild_cidr_list(struct ClassItem *class)
228 > class_ip_limit_rebuild(struct ClassItem *class)
229   {
230 <  dlink_node *ptr;
230 >  dlink_node *node;
231  
232 <  destroy_cidr_class(class);
232 >  patricia_clear(class->ip_tree, NULL);
233  
234 <  DLINK_FOREACH(ptr, local_client_list.head)
234 >  DLINK_FOREACH(node, local_client_list.head)
235    {
236 <    struct Client *client_p = ptr->data;
237 <    struct MaskItem *conf = client_p->localClient->confs.tail->data;
236 >    struct Client *client_p = node->data;
237 >    struct MaskItem *conf = client_p->connection->confs.tail->data;
238  
239 <    if (conf && (conf->type == CONF_CLIENT))
239 >    if (conf->type == CONF_CLIENT)
240        if (conf->class == class)
241 <        cidr_limit_reached(1, &client_p->localClient->ip, class);
241 >        class_ip_limit_add(class, (struct sockaddr *)&client_p->ip, 1);
242    }
243   }
341
342 /*
343 * destroy_cidr_list
344 *
345 * inputs       - pointer to class dlink list of cidr blocks
346 * output       - none
347 * side effects - completely destroys the class link list of cidr blocks
348 */
349 static void
350 destroy_cidr_list(dlink_list *list)
351 {
352  dlink_node *ptr = NULL, *next_ptr = NULL;
353
354  DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
355  {
356    dlinkDelete(ptr, list);
357    MyFree(ptr->data);
358  }
359 }
360
361 /*
362 * destroy_cidr_class
363 *
364 * inputs       - pointer to class
365 * output       - none
366 * side effects - completely destroys the class link list of cidr blocks
367 */
368 void
369 destroy_cidr_class(struct ClassItem *class)
370 {
371  destroy_cidr_list(&class->list_ipv4);
372  destroy_cidr_list(&class->list_ipv6);
373 }

Comparing ircd-hybrid/trunk/src/conf_class.c (property svn:keywords):
Revision 1666 by michael, Sun Nov 18 17:03:18 2012 UTC vs.
Revision 8607 by michael, Mon Oct 29 21:26:54 2018 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

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