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

Comparing:
ircd-hybrid-8/src/hostmask.c (file contents), Revision 1376 by michael, Sun Apr 29 17:08:42 2012 UTC vs.
ircd-hybrid/trunk/src/hostmask.c (file contents), Revision 7672 by michael, Wed Jul 20 18:47:20 2016 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  hostmask.c: Code to efficiently find IP & hostmask based configs.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2005 by the past and present ircd coders, and others.
4 > *  Copyright (c) 2001-2016 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 16 | 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 < *  $Id$
20 > */
21 >
22 > /*! \file hostmask.c
23 > * \brief Code to efficiently find IP & hostmask based configs.
24 > * \version $Id$
25   */
26  
27   #include "stdinc.h"
# Line 42 | Line 44
44                           ch = ch - 'a' + 10; \
45                         } while (0);
46  
47 + /* Hashtable stuff...now external as it's used in m_stats.c */
48 + dlink_list atable[ATABLE_SIZE];
49 +
50   /* The mask parser/type determination code... */
51  
52   /* int try_parse_v6_netmask(const char *, struct irc_ssaddr *, int *);
# Line 51 | Line 56
56   * Side effects: None
57   * Comments: Called from parse_netmask
58   */
54 – /* Fixed so ::/0 (any IPv6 address) is valid
55 –   Also a bug in DigitParse above.
56 –   -Gozem 2002-07-19 gozem@linux.nu
57 – */
58 – #ifdef IPV6
59   static int
60   try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
61   {
62 –  const char *p;
62    char c;
63    int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
64    int dp = 0;
# Line 68 | Line 67 | try_parse_v6_netmask(const char *text, s
67    int bits = 128;
68    int deficit = 0;
69    short dc[8];
70 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
70 >  struct sockaddr_in6 *const v6 = (struct sockaddr_in6 *)addr;
71  
72 <  for (p = text; (c = *p); p++)
72 >  for (const char *p = text; (c = *p); ++p)
73 >  {
74      if (IsXDigit(c))
75      {
76        if (nyble == 0)
# Line 88 | Line 88 | try_parse_v6_netmask(const char *text, s
88        }
89        else
90        {
91 <        /* If there were less than 4 hex digits, e.g. :ABC: shift right
92 <         * so we don't interpret it as ABC0 -A1kmm */
91 >        /*
92 >         * If there were less than 4 hex digits, e.g. :ABC: shift right
93 >         * so we don't interpret it as ABC0 -A1kmm
94 >         */
95          d[dp] = d[dp] >> 4 * nyble;
96          nyble = 4;
97 +
98          if (++dp >= 8)
99            return HM_HOST;
100        }
# Line 108 | Line 111 | try_parse_v6_netmask(const char *text, s
111        char *after;
112  
113        d[dp] = d[dp] >> 4 * nyble;
114 <      dp++;
114 >      ++dp;
115        bits = strtoul(p + 1, &after, 10);
116  
117        if (bits < 0 || *after)
# Line 119 | Line 122 | try_parse_v6_netmask(const char *text, s
122      }
123      else
124        return HM_HOST;
125 +  }
126  
127    d[dp] = d[dp] >> 4 * nyble;
128  
129    if (c == 0)
130 <    dp++;
130 >    ++dp;
131    if (finsert < 0 && bits == 0)
132      bits = dp * 16;
133  
# Line 131 | Line 135 | try_parse_v6_netmask(const char *text, s
135    deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp;
136  
137    /* Now fill in the gaps(from ::) in the copied table... -A1kmm */
138 <  for (dp = 0, nyble = 0; dp < 8; dp++)
138 >  for (dp = 0, nyble = 0; dp < 8; ++dp)
139    {
140      if (nyble == finsert && deficit)
141      {
# Line 145 | Line 149 | try_parse_v6_netmask(const char *text, s
149    /* Set unused bits to 0... -A1kmm */
150    if (bits < 128 && (bits % 16 != 0))
151      dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1);
152 <  for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; dp++)
152 >  for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; ++dp)
153      dc[dp] = 0;
154  
155    /* And assign... -A1kmm */
156    if (addr)
157 <    for (dp = 0; dp < 8; dp++)
157 >    for (dp = 0; dp < 8; ++dp)
158        /* The cast is a kludge to make netbsd work. */
159        ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]);
160  
161 <  if (b != NULL)
161 >  if (b)
162      *b = bits;
163    return HM_IPV6;
164   }
161 – #endif
165  
166   /* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
167   * Input: A possible IPV4 address as a string.
# Line 170 | Line 173 | try_parse_v6_netmask(const char *text, s
173   static int
174   try_parse_v4_netmask(const char *text, struct irc_ssaddr *addr, int *b)
175   {
173 –  const char *p;
176    const char *digits[4];
177    unsigned char addb[4];
178    int n = 0, bits = 0;
179    char c;
180 <  struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
180 >  struct sockaddr_in *const v4 = (struct sockaddr_in *)addr;
181  
182    digits[n++] = text;
183  
184 <  for (p = text; (c = *p); p++)
184 >  for (const char *p = text; (c = *p); ++p)
185 >  {
186      if (c >= '0' && c <= '9')   /* empty */
187        ;
188      else if (c == '.')
# Line 191 | Line 194 | try_parse_v4_netmask(const char *text, s
194      }
195      else if (c == '*')
196      {
197 <      if (*(p + 1) || n == 0 || *(p - 1) != '.')
197 >      if (*(p + 1) || n == 1 || *(p - 1) != '.')
198          return HM_HOST;
199  
200        bits = (n - 1) * 8;
# Line 202 | Line 205 | try_parse_v4_netmask(const char *text, s
205        char *after;
206        bits = strtoul(p + 1, &after, 10);
207  
208 <      if (!bits || *after)
208 >      if (bits < 0 || *after)
209          return HM_HOST;
210        if (bits > n * 8)
211          return HM_HOST;
# Line 211 | Line 214 | try_parse_v4_netmask(const char *text, s
214      }
215      else
216        return HM_HOST;
217 +  }
218  
219    if (n < 4 && bits == 0)
220      bits = n * 8;
# Line 218 | Line 222 | try_parse_v4_netmask(const char *text, s
222      while (n < 4)
223        digits[n++] = "0";
224  
225 <  for (n = 0; n < 4; n++)
225 >  for (n = 0; n < 4; ++n)
226      addb[n] = strtoul(digits[n], NULL, 10);
227  
228    if (bits == 0)
# Line 227 | Line 231 | try_parse_v4_netmask(const char *text, s
231    /* Set unused bits to 0... -A1kmm */
232    if (bits < 32 && bits % 8)
233      addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1);
234 <  for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; n++)
234 >  for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; ++n)
235      addb[n] = 0;
236    if (addr)
237      v4->sin_addr.s_addr =
238        htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]);
239 <  if (b != NULL)
239 >  if (b)
240      *b = bits;
241    return HM_IPV4;
242   }
# Line 247 | Line 251 | try_parse_v4_netmask(const char *text, s
251   int
252   parse_netmask(const char *text, struct irc_ssaddr *addr, int *b)
253   {
250 – #ifdef IPV6
251 –  if (strchr(text, ':'))
252 –    return try_parse_v6_netmask(text, addr, b);
253 – #endif
254    if (strchr(text, '.'))
255      return try_parse_v4_netmask(text, addr, b);
256 +  if (strchr(text, ':'))
257 +    return try_parse_v6_netmask(text, addr, b);
258 +
259    return HM_HOST;
260   }
261  
# Line 262 | Line 265 | parse_netmask(const char *text, struct i
265   * Output: if match, -1 else 0
266   * Side effects: None
267   */
265 – #ifdef IPV6
268   int
269 < match_ipv6(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits)
269 > match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
270   {
271    int i, m, n = bits / 8;
272 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
273 <  struct sockaddr_in6 *v6mask = (struct sockaddr_in6 *)mask;
272 >  const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
273 >  const struct sockaddr_in6 *const v6mask = (const struct sockaddr_in6 *)mask;
274  
275 <  for (i = 0; i < n; i++)
275 >  for (i = 0; i < n; ++i)
276      if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
277        return 0;
278 +
279    if ((m = bits % 8) == 0)
280      return -1;
281    if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) ==
# Line 280 | Line 283 | match_ipv6(struct irc_ssaddr *addr, stru
283      return -1;
284    return 0;
285   }
283 – #endif
286  
287   /* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int)
288   * Input: An IP address, an IP mask, the number of bits in the mask.
# Line 288 | Line 290 | match_ipv6(struct irc_ssaddr *addr, stru
290   * Side Effects: None
291   */
292   int
293 < match_ipv4(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits)
293 > match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
294   {
295 <  struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
296 <  struct sockaddr_in *v4mask = (struct sockaddr_in *)mask;
295 >  const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
296 >  const struct sockaddr_in *const v4mask = (const struct sockaddr_in *)mask;
297  
298    if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
299        ntohl(v4mask->sin_addr.s_addr))
# Line 311 | Line 313 | void
313   mask_addr(struct irc_ssaddr *ip, int bits)
314   {
315    int mask;
314 – #ifdef IPV6
316    struct sockaddr_in6 *v6_base_ip;
317    int i, m, n;
317 – #endif
318    struct sockaddr_in *v4_base_ip;
319  
320 < #ifdef IPV6
321 <  if (ip->ss.ss_family != AF_INET6)
322 < #endif
320 >  if (ip->ss.ss_family == AF_INET)
321    {
322 +    uint32_t tmp = 0;
323      v4_base_ip = (struct sockaddr_in *)ip;
324  
325      mask = ~((1 << (32 - bits)) - 1);
326 <    v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
326 >    tmp = ntohl(v4_base_ip->sin_addr.s_addr);
327 >    v4_base_ip->sin_addr.s_addr = htonl(tmp & mask);
328    }
329 – #ifdef IPV6
329    else
330    {
331      n = bits / 8;
332      m = bits % 8;
333      v6_base_ip = (struct sockaddr_in6 *)ip;
334  
335 <    mask = ~((1 << (8 - m)) -1 );
335 >    mask = ~((1 << (8 - m)) - 1);
336      v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask;
337  
338      for (i = n + 1; i < 16; i++)
339        v6_base_ip->sin6_addr.s6_addr[i] = 0;
340    }
342 – #endif
343 – }
344 –
345 – /* Hashtable stuff...now external as its used in m_stats.c */
346 – dlink_list atable[ATABLE_SIZE];
347 –
348 – void
349 – init_host_hash(void)
350 – {
351 –  memset(&atable, 0, sizeof(atable));
341   }
342  
343   /* unsigned long hash_ipv4(struct irc_ssaddr*)
# Line 357 | Line 346 | init_host_hash(void)
346   * Side effects: None
347   */
348   static uint32_t
349 < hash_ipv4(struct irc_ssaddr *addr, int bits)
349 > hash_ipv4(const struct irc_ssaddr *addr, int bits)
350   {
351    if (bits != 0)
352    {
353 <    struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
353 >    const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
354      uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
355  
356      return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
# Line 375 | Line 364 | hash_ipv4(struct irc_ssaddr *addr, int b
364   * Output: A hash value of the IP address.
365   * Side effects: None
366   */
378 – #ifdef IPV6
367   static uint32_t
368 < hash_ipv6(struct irc_ssaddr *addr, int bits)
368 > hash_ipv6(const struct irc_ssaddr *addr, int bits)
369   {
370    uint32_t v = 0, n;
371 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
371 >  const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
372  
373 <  for (n = 0; n < 16; n++)
373 >  for (n = 0; n < 16; ++n)
374    {
375      if (bits >= 8)
376      {
# Line 397 | Line 385 | hash_ipv6(struct irc_ssaddr *addr, int b
385      else
386        return v & (ATABLE_SIZE - 1);
387    }
388 +
389    return v & (ATABLE_SIZE - 1);
390   }
402 – #endif
391  
392   /* int hash_text(const char *start)
393   * Input: The start of the text to hash.
# Line 409 | Line 397 | hash_ipv6(struct irc_ssaddr *addr, int b
397   static uint32_t
398   hash_text(const char *start)
399   {
412 –  const char *p = start;
400    uint32_t h = 0;
401  
402 <  for (; *p; ++p)
403 <    h = (h << 4) - (h + (unsigned char)ToLower(*p));
402 >  for (const char *p = start; *p; ++p)
403 >    h = (h << 4) - (h + ToLower(*p));
404  
405    return h & (ATABLE_SIZE - 1);
406   }
# Line 429 | Line 416 | get_mask_hash(const char *text)
416   {
417    const char *hp = "", *p;
418  
419 <  for (p = text + strlen(text) - 1; p >= text; p--)
419 >  for (p = text + strlen(text) - 1; p >= text; --p)
420      if (IsMWildChar(*p))
421        return hash_text(hp);
422      else if (*p == '.')
# Line 437 | Line 424 | get_mask_hash(const char *text)
424    return hash_text(text);
425   }
426  
427 < /* struct AccessItem *find_conf_by_address(const char *, struct irc_ssaddr *,
427 > /* struct MaskItem *find_conf_by_address(const char *, struct irc_ssaddr *,
428   *                                         int type, int fam, const char *username)
429   * Input: The hostname, the address, the type of mask to find, the address
430   *        family, the username.
# Line 445 | Line 432 | get_mask_hash(const char *text)
432   * Side-effects: None
433   * Note: Setting bit 0 of the type means that the username is ignored.
434   * Warning: IsNeedPassword for everything that is not an auth{} entry
435 < * should always be true (i.e. aconf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
435 > * should always be true (i.e. conf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
436   */
437 < struct AccessItem *
438 < find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type,
437 > struct MaskItem *
438 > find_conf_by_address(const char *name, const struct irc_ssaddr *addr, unsigned int type,
439                       int fam, const char *username, const char *password, int do_match)
440   {
441    unsigned int hprecv = 0;
442 <  dlink_node *ptr = NULL;
443 <  struct AccessItem *hprec = NULL;
444 <  struct AddressRec *arec;
442 >  dlink_node *node = NULL;
443 >  struct MaskItem *hprec = NULL;
444 >  struct AddressRec *arec = NULL;
445    int b;
446    int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp;
447  
461 –  if (username == NULL)
462 –    username = "";
463 –  if (password == NULL)
464 –    password = "";
465 –
448    if (addr)
449    {
450      /* Check for IPV6 matches... */
469 – #ifdef IPV6
451      if (fam == AF_INET6)
452      {
453        for (b = 128; b >= 0; b -= 16)
454        {
455 <        DLINK_FOREACH(ptr, atable[hash_ipv6(addr, b)].head)
455 >        DLINK_FOREACH(node, atable[hash_ipv6(addr, b)].head)
456          {
457 <          arec = ptr->data;
457 >          arec = node->data;
458  
459 <          if (arec->type == (type & ~0x1) &&
459 >          if ((arec->type == type) &&
460                arec->precedence > hprecv &&
461                arec->masktype == HM_IPV6 &&
462                match_ipv6(addr, &arec->Mask.ipa.addr,
463                           arec->Mask.ipa.bits) &&
464 <              (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
465 <              (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
466 <               match_conf_password(password, arec->aconf)))
464 >              (!username || !cmpfunc(arec->username, username)) &&
465 >              (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
466 >               match_conf_password(password, arec->conf)))
467            {
468              hprecv = arec->precedence;
469 <            hprec = arec->aconf;
469 >            hprec = arec->conf;
470            }
471          }
472        }
473      }
474 <    else
494 < #endif
495 <    if (fam == AF_INET)
474 >    else if (fam == AF_INET)
475      {
476        for (b = 32; b >= 0; b -= 8)
477        {
478 <        DLINK_FOREACH(ptr, atable[hash_ipv4(addr, b)].head)
478 >        DLINK_FOREACH(node, atable[hash_ipv4(addr, b)].head)
479          {
480 <          arec = ptr->data;
480 >          arec = node->data;
481  
482 <          if (arec->type == (type & ~0x1) &&
482 >          if ((arec->type == type) &&
483                arec->precedence > hprecv &&
484                arec->masktype == HM_IPV4 &&
485                match_ipv4(addr, &arec->Mask.ipa.addr,
486                           arec->Mask.ipa.bits) &&
487 <              (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
488 <              (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
489 <               match_conf_password(password, arec->aconf)))
487 >              (!username || !cmpfunc(arec->username, username)) &&
488 >              (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
489 >               match_conf_password(password, arec->conf)))
490            {
491              hprecv = arec->precedence;
492 <            hprec = arec->aconf;
492 >            hprec = arec->conf;
493            }
494          }
495        }
496      }
497    }
498  
499 <  if (name != NULL)
499 >  if (name)
500    {
501      const char *p = name;
502  
503      while (1)
504      {
505 <        DLINK_FOREACH(ptr, atable[hash_text(p)].head)
505 >        DLINK_FOREACH(node, atable[hash_text(p)].head)
506          {
507 <          arec = ptr->data;
508 <          if ((arec->type == (type & ~0x1)) &&
507 >          arec = node->data;
508 >          if ((arec->type == type) &&
509              arec->precedence > hprecv &&
510              (arec->masktype == HM_HOST) &&
511 <            cmpfunc(arec->Mask.hostname, name) == do_match &&
512 <            (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
513 <            (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
514 <             match_conf_password(password, arec->aconf)))
511 >            !cmpfunc(arec->Mask.hostname, name) &&
512 >            (!username || !cmpfunc(arec->username, username)) &&
513 >            (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
514 >             match_conf_password(password, arec->conf)))
515          {
516            hprecv = arec->precedence;
517 <          hprec = arec->aconf;
517 >          hprec = arec->conf;
518          }
519        }
520 <      p = strchr(p, '.');
521 <      if (p == NULL)
520 >
521 >      if ((p = strchr(p, '.')) == NULL)
522          break;
523 <      p++;
523 >      ++p;
524      }
525  
526 <    DLINK_FOREACH(ptr, atable[0].head)
526 >    DLINK_FOREACH(node, atable[0].head)
527      {
528 <      arec = ptr->data;
528 >      arec = node->data;
529  
530 <      if (arec->type == (type & ~0x1) &&
530 >      if (arec->type == type &&
531            arec->precedence > hprecv &&
532            arec->masktype == HM_HOST &&
533 <          cmpfunc(arec->Mask.hostname, name) == do_match &&
534 <          (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
535 <          (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
536 <           match_conf_password(password, arec->aconf)))
533 >          !cmpfunc(arec->Mask.hostname, name) &&
534 >          (!username || !cmpfunc(arec->username, username)) &&
535 >          (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
536 >           match_conf_password(password, arec->conf)))
537        {
538          hprecv = arec->precedence;
539 <        hprec = arec->aconf;
539 >        hprec = arec->conf;
540        }
541      }
542    }
# Line 565 | Line 544 | find_conf_by_address(const char *name, s
544    return hprec;
545   }
546  
547 < /* struct AccessItem* find_address_conf(const char*, const char*,
547 > /* struct MaskItem* find_address_conf(const char*, const char*,
548   *                                     struct irc_ssaddr*, int, char *);
549   * Input: The hostname, username, address, address family.
550 < * Output: The applicable AccessItem.
550 > * Output: The applicable MaskItem.
551   * Side-effects: None
552   */
553 < struct AccessItem *
554 < find_address_conf(const char *host, const char *user,
555 <                  struct irc_ssaddr *ip, int aftype, char *password)
556 < {
557 <  struct AccessItem *iconf, *kconf;
558 <
559 <  /* Find the best I-line... If none, return NULL -A1kmm */
560 <  if ((iconf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
561 <                                    password, 1)) == NULL)
553 > struct MaskItem *
554 > find_address_conf(const char *host, const char *user, const struct irc_ssaddr *ip,
555 >                  int aftype, const char *password)
556 > {
557 >  struct MaskItem *authcnf = NULL, *killcnf = NULL;
558 >
559 >  /* Find the best auth{} block... If none, return NULL -A1kmm */
560 >  if ((authcnf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
561 >                                      password, 1)) == NULL)
562      return NULL;
563  
564 <  /* If they are exempt from K-lines, return the best I-line. -A1kmm */
565 <  if (IsConfExemptKline(iconf))
566 <    return iconf;
564 >  /* If they are exempt from K-lines, return the best auth{} block. -A1kmm */
565 >  if (IsConfExemptKline(authcnf))
566 >    return authcnf;
567  
568    /* Find the best K-line... -A1kmm */
569 <  kconf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
569 >  killcnf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
570  
571 <  /* If they are K-lined, return the K-line. Otherwise, return the
572 <   * I-line. -A1kmm */
573 <  if (kconf != NULL)
574 <    return kconf;
571 >  /*
572 >   * If they are K-lined, return the K-line. Otherwise, return the
573 >   * auth {} block. -A1kmm
574 >   */
575 >  if (killcnf)
576 >    return killcnf;
577  
578 <  kconf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
598 <  if (kconf != NULL && !IsConfExemptGline(iconf))
599 <    return kconf;
600 <
601 <  return iconf;
602 < }
603 <
604 < struct AccessItem *
605 < find_gline_conf(const char *host, const char *user,
606 <                struct irc_ssaddr *ip, int aftype)
607 < {
608 <  struct AccessItem *eline;
609 <
610 <  eline = find_conf_by_address(host, ip, CONF_EXEMPTKLINE, aftype,
611 <                               user, NULL, 1);
612 <  if (eline != NULL)
613 <    return eline;
614 <
615 <  return find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
578 >  return authcnf;
579   }
580  
581 < /* find_kline_conf
619 < *
620 < * inputs       - pointer to hostname
621 < *              - pointer to username
622 < *              - incoming IP and type (IPv4 vs. IPv6)
623 < * outut        - pointer to kline conf if found NULL if not
624 < * side effects -
625 < */
626 < struct AccessItem *
627 < find_kline_conf(const char *host, const char *user,
628 <                struct irc_ssaddr *ip, int aftype)
629 < {
630 <  struct AccessItem *eline;
631 <
632 <  eline = find_conf_by_address(host, ip, CONF_EXEMPTKLINE, aftype,
633 <                               user, NULL, 1);
634 <  if (eline != NULL)
635 <    return eline;
636 <
637 <  return find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
638 < }
639 <
640 < /* struct AccessItem* find_dline_conf(struct irc_ssaddr*, int)
581 > /* struct MaskItem* find_dline_conf(struct irc_ssaddr*, int)
582   *
583   * Input:       An address, an address family.
584   * Output:      The best matching D-line or exempt line.
585   * Side effects: None.
586   */
587 < struct AccessItem *
588 < find_dline_conf(struct irc_ssaddr *addr, int aftype)
587 > struct MaskItem *
588 > find_dline_conf(const struct irc_ssaddr *addr, int aftype)
589   {
590 <  struct AccessItem *eline;
590 >  struct MaskItem *eline;
591  
592 <  eline = find_conf_by_address(NULL, addr, CONF_EXEMPTDLINE | 1, aftype,
593 <                               NULL, NULL, 1);
653 <  if (eline != NULL)
592 >  eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, aftype, NULL, NULL, 1);
593 >  if (eline)
594      return eline;
595  
596 <  return find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL, 1);
596 >  return find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1);
597   }
598  
599 < /* void add_conf_by_address(int, struct AccessItem *aconf)
600 < * Input:
599 > /* void add_conf_by_address(int, struct MaskItem *aconf)
600 > * Input:
601   * Output: None
602   * Side-effects: Adds this entry to the hash table.
603   */
604 < void
605 < add_conf_by_address(const unsigned int type, struct AccessItem *aconf)
604 > struct AddressRec *
605 > add_conf_by_address(const unsigned int type, struct MaskItem *conf)
606   {
607 <  const char *address;
608 <  const char *username;
609 <  static unsigned int prec_value = 0xFFFFFFFF;
607 >  const char *const hostname = conf->host;
608 >  const char *const username = conf->user;
609 >  static unsigned int prec_value = UINT_MAX;
610    int bits = 0;
671 –  struct AddressRec *arec;
672 –
673 –  address = aconf->host;
674 –  username = aconf->user;
611  
612 <  assert(type != 0);
677 <  assert(aconf != NULL);
612 >  assert(type && !EmptyString(hostname));
613  
614 <  if (EmptyString(address))
615 <    address = "/NOMATCH!/";
681 <
682 <  arec = MyMalloc(sizeof(struct AddressRec));
683 <  arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
614 >  struct AddressRec *arec = xcalloc(sizeof(struct AddressRec));
615 >  arec->masktype = parse_netmask(hostname, &arec->Mask.ipa.addr, &bits);
616    arec->Mask.ipa.bits = bits;
617    arec->username = username;
618 <  arec->aconf = aconf;
618 >  arec->conf = conf;
619    arec->precedence = prec_value--;
620    arec->type = type;
621  
# Line 694 | Line 626 | add_conf_by_address(const unsigned int t
626        bits -= bits % 8;
627        dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]);
628        break;
697 – #ifdef IPV6
629      case HM_IPV6:
630        /* We have to do this, since we do not re-hash for every bit -A1kmm. */
631        bits -= bits % 16;
632        dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]);
633        break;
703 – #endif
634      default: /* HM_HOST */
635 <      arec->Mask.hostname = address;
636 <      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(address)]);
635 >      arec->Mask.hostname = hostname;
636 >      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(hostname)]);
637        break;
638    }
639 +
640 +  return arec;
641   }
642  
643 < /* void delete_one_address(const char*, struct AccessItem*)
644 < * Input: An address string, the associated AccessItem.
643 > /* void delete_one_address(const char*, struct MaskItem*)
644 > * Input: An address string, the associated MaskItem.
645   * Output: None
646 < * Side effects: Deletes an address record. Frees the AccessItem if there
646 > * Side effects: Deletes an address record. Frees the MaskItem if there
647   *               is nothing referencing it, sets it as illegal otherwise.
648   */
649   void
650 < delete_one_address_conf(const char *address, struct AccessItem *aconf)
650 > delete_one_address_conf(const char *address, struct MaskItem *conf)
651   {
652    int bits = 0;
653    uint32_t hv = 0;
654 <  dlink_node *ptr = NULL, *ptr_next = NULL;
654 >  dlink_node *node = NULL;
655    struct irc_ssaddr addr;
656  
657    switch (parse_netmask(address, &addr, &bits))
# Line 729 | Line 661 | delete_one_address_conf(const char *addr
661        bits -= bits % 8;
662        hv = hash_ipv4(&addr, bits);
663        break;
732 – #ifdef IPV6
664      case HM_IPV6:
665        /* We have to do this, since we do not re-hash for every bit -A1kmm. */
666        bits -= bits % 16;
667        hv = hash_ipv6(&addr, bits);
668        break;
738 – #endif
669      default: /* HM_HOST */
670        hv = get_mask_hash(address);
671        break;
672    }
673  
674 <  DLINK_FOREACH_SAFE(ptr, ptr_next, atable[hv].head)
674 >  DLINK_FOREACH(node, atable[hv].head)
675    {
676 <    struct AddressRec *arec = ptr->data;
676 >    struct AddressRec *arec = node->data;
677  
678 <    if (arec->aconf == aconf)
678 >    if (arec->conf == conf)
679      {
680        dlinkDelete(&arec->node, &atable[hv]);
751 –      aconf->status |= CONF_ILLEGAL;
681  
682 <      if (!aconf->clients)
683 <        free_access_item(aconf);
682 >      if (!conf->ref_count)
683 >        conf_free(conf);
684  
685 <      MyFree(arec);
685 >      xfree(arec);
686        return;
687      }
688    }
# Line 763 | Line 692 | delete_one_address_conf(const char *addr
692   * Input: None
693   * Output: None
694   * Side effects: Clears out all address records in the hash table,
695 < *               frees them, and frees the AccessItems if nothing references
696 < *               them, otherwise sets them as illegal.  
695 > *               frees them, and frees the MaskItems if nothing references
696 > *               them, otherwise sets them as illegal.
697   */
698   void
699   clear_out_address_conf(void)
700   {
701 <  unsigned int i = 0;
702 <  dlink_node *ptr = NULL, *ptr_next = NULL;
703 <
704 <  for (i = 0; i < ATABLE_SIZE; ++i)
705 <  {
706 <    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
707 <    {
708 <      struct AddressRec *arec = ptr->data;
709 <
710 <      /* We keep the temporary K-lines and destroy the
711 <       * permanent ones, just to be confusing :) -A1kmm
712 <       */  
713 <      if (!(arec->aconf->flags & CONF_FLAGS_TEMPORARY))
714 <      {
715 <        dlinkDelete(&arec->node, &atable[i]);
716 <        /* unlink it from link list - Dianora */
717 <        arec->aconf->status |= CONF_ILLEGAL;
718 <
719 <        if (!arec->aconf->clients)
720 <          free_access_item(arec->aconf);
792 <        MyFree(arec);
793 <      }
701 >  dlink_node *node = NULL, *node_next = NULL;
702 >
703 >  for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
704 >  {
705 >    DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
706 >    {
707 >      struct AddressRec *arec = node->data;
708 >
709 >      /*
710 >       * Destroy the ircd.conf items and keep those that are in the databases
711 >       */
712 >      if (IsConfDatabase(arec->conf))
713 >        continue;
714 >
715 >      dlinkDelete(&arec->node, &atable[i]);
716 >      arec->conf->active = 0;
717 >
718 >      if (!arec->conf->ref_count)
719 >        conf_free(arec->conf);
720 >      xfree(arec);
721      }
722    }
723   }
724  
725   static void
726 < hostmask_send_expiration(struct AddressRec *arec)
726 > hostmask_send_expiration(const struct AddressRec *const arec)
727   {
728 <  char ban_type = '\0';
728 >  char ban_type = '?';
729  
730 <  if (!ConfigFileEntry.tkline_expire_notices)
730 >  if (!ConfigGeneral.tkline_expire_notices)
731      return;
732  
733    switch (arec->type)
# Line 811 | Line 738 | hostmask_send_expiration(struct AddressR
738      case CONF_DLINE:
739        ban_type = 'D';
740        break;
741 <    case CONF_GLINE:
815 <      ban_type = 'G';
816 <      break;
741 >    default: break;
742    }
743 <  
744 <  sendto_realops_flags(UMODE_ALL, L_ALL,
743 >
744 >  sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
745                         "Temporary %c-line for [%s@%s] expired", ban_type,
746 <                       (arec->aconf->user) ? arec->aconf->user : "*",
747 <                       (arec->aconf->host) ? arec->aconf->host : "*");
746 >                       (arec->conf->user) ? arec->conf->user : "*",
747 >                       (arec->conf->host) ? arec->conf->host : "*");
748   }
749  
750   void
751   hostmask_expire_temporary(void)
752   {
753 <  unsigned int i = 0;
829 <  dlink_node *ptr = NULL, *ptr_next = NULL;
753 >  dlink_node *node = NULL, *node_next = NULL;
754  
755 <  for (i = 0; i < ATABLE_SIZE; ++i)
755 >  for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
756    {
757 <    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
757 >    DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
758      {
759 <      struct AddressRec *arec = ptr->data;
759 >      struct AddressRec *arec = node->data;
760  
761 <      if (!IsConfTemporary(arec->aconf) || arec->aconf->hold > CurrentTime)
761 >      if (!arec->conf->until || arec->conf->until > CurrentTime)
762          continue;
763  
764        switch (arec->type)
765        {
766          case CONF_KLINE:
767          case CONF_DLINE:
844 –        case CONF_GLINE:
768            hostmask_send_expiration(arec);
769  
770            dlinkDelete(&arec->node, &atable[i]);
771 <          free_access_item(arec->aconf);
772 <          MyFree(arec);
771 >          conf_free(arec->conf);
772 >          xfree(arec);
773            break;
774 +        default: break;
775        }
776      }
777    }

Comparing:
ircd-hybrid-8/src/hostmask.c (property svn:keywords), Revision 1376 by michael, Sun Apr 29 17:08:42 2012 UTC vs.
ircd-hybrid/trunk/src/hostmask.c (property svn:keywords), Revision 7672 by michael, Wed Jul 20 18:47:20 2016 UTC

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

Diff Legend

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