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-7.2/src/hostmask.c (file contents), Revision 1014 by michael, Sun Oct 18 15:17:32 2009 UTC vs.
ircd-hybrid-8/src/hostmask.c (file contents), Revision 1371 by michael, Wed Apr 25 19:32:21 2012 UTC

# Line 26 | Line 26
26   #include "memory.h"
27   #include "ircd_defs.h"
28   #include "list.h"
29 < #include "s_conf.h"
29 > #include "conf.h"
30   #include "hostmask.h"
31   #include "numeric.h"
32   #include "send.h"
33   #include "irc_string.h"
34 + #include "ircd.h"
35  
36   #ifdef IPV6
37   static int try_parse_v6_netmask(const char *, struct irc_ssaddr *, int *);
38 < static unsigned long hash_ipv6(struct irc_ssaddr *, int);
38 > static uint32_t hash_ipv6(struct irc_ssaddr *, int);
39   #endif
40   static int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
41 < static unsigned long hash_ipv4(struct irc_ssaddr *, int);
41 > static uint32_t hash_ipv4(struct irc_ssaddr *, int);
42  
43   #define DigitParse(ch) do { \
44                         if (ch >= '0' && ch <= '9') \
# Line 46 | Line 47 | static unsigned long hash_ipv4(struct ir
47                           ch = ch - 'A' + 10; \
48                         else if (ch >= 'a' && ch <= 'f') \
49                           ch = ch - 'a' + 10; \
50 <                       } while(0);
50 >                       } while (0);
51  
52   /* The mask parser/type determination code... */
53  
# Line 74 | Line 75 | try_parse_v6_netmask(const char *text, s
75    int bits = 128;
76    int deficit = 0;
77    short dc[8];
78 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6*) addr;
78 >  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
79  
80    for (p = text; (c = *p); p++)
81      if (IsXDigit(c))
# Line 116 | Line 117 | try_parse_v6_netmask(const char *text, s
117        d[dp] = d[dp] >> 4 * nyble;
118        dp++;
119        bits = strtoul(p + 1, &after, 10);
120 +
121        if (bits < 0 || *after)
122          return HM_HOST;
123        if (bits > dp * 4 && !(finsert >= 0 && bits <= 128))
# Line 126 | Line 128 | try_parse_v6_netmask(const char *text, s
128        return HM_HOST;
129  
130    d[dp] = d[dp] >> 4 * nyble;
131 +
132    if (c == 0)
133      dp++;
134    if (finsert < 0 && bits == 0)
135      bits = dp * 16;
136 +
137    /* How many words are missing? -A1kmm */
138    deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp;
139 +
140    /* Now fill in the gaps(from ::) in the copied table... -A1kmm */
141    for (dp = 0, nyble = 0; dp < 8; dp++)
142    {
# Line 143 | Line 148 | try_parse_v6_netmask(const char *text, s
148      else
149        dc[dp] = d[nyble++];
150    }
151 +
152    /* Set unused bits to 0... -A1kmm */
153    if (bits < 128 && (bits % 16 != 0))
154      dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1);
155    for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; dp++)
156      dc[dp] = 0;
157 +
158    /* And assign... -A1kmm */
159    if (addr)
160      for (dp = 0; dp < 8; dp++)
161        /* The cast is a kludge to make netbsd work. */
162        ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]);
163 +
164    if (b != NULL)
165      *b = bits;
166    return HM_IPV6;
# Line 174 | Line 182 | try_parse_v4_netmask(const char *text, s
182    unsigned char addb[4];
183    int n = 0, bits = 0;
184    char c;
185 <  struct sockaddr_in *v4 = (struct sockaddr_in*) addr;
185 >  struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
186  
187    digits[n++] = text;
188  
# Line 185 | Line 193 | try_parse_v4_netmask(const char *text, s
193      {
194        if (n >= 4)
195          return HM_HOST;
196 +
197        digits[n++] = p + 1;
198      }
199      else if (c == '*')
200      {
201        if (*(p + 1) || n == 0 || *(p - 1) != '.')
202          return HM_HOST;
203 +
204        bits = (n - 1) * 8;
205        break;
206      }
# Line 198 | Line 208 | try_parse_v4_netmask(const char *text, s
208      {
209        char *after;
210        bits = strtoul(p + 1, &after, 10);
211 +
212        if (!bits || *after)
213          return HM_HOST;
214        if (bits > n * 8)
215          return HM_HOST;
216 +
217        break;
218      }
219      else
# Line 212 | Line 224 | try_parse_v4_netmask(const char *text, s
224    if (bits)
225      while (n < 4)
226        digits[n++] = "0";
227 +
228    for (n = 0; n < 4; n++)
229      addb[n] = strtoul(digits[n], NULL, 10);
230 +
231    if (bits == 0)
232      bits = 32;
233 +
234    /* Set unused bits to 0... -A1kmm */
235    if (bits < 32 && bits % 8)
236      addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1);
# Line 240 | Line 255 | int
255   parse_netmask(const char *text, struct irc_ssaddr *addr, int *b)
256   {
257   #ifdef IPV6
258 <    if (strchr(text, ':'))
258 >  if (strchr(text, ':'))
259      return try_parse_v6_netmask(text, addr, b);
260   #endif
261    if (strchr(text, '.'))
# Line 259 | Line 274 | int
274   match_ipv6(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits)
275   {
276    int i, m, n = bits / 8;
277 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6*)addr;
278 <  struct sockaddr_in6 *v6mask = (struct sockaddr_in6*)mask;
277 >  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
278 >  struct sockaddr_in6 *v6mask = (struct sockaddr_in6 *)mask;
279  
280    for (i = 0; i < n; i++)
281      if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
# Line 281 | Line 296 | match_ipv6(struct irc_ssaddr *addr, stru
296   int
297   match_ipv4(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits)
298   {
299 <  struct sockaddr_in *v4 = (struct sockaddr_in*) addr;
300 <  struct sockaddr_in *v4mask = (struct sockaddr_in*) mask;
299 >  struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
300 >  struct sockaddr_in *v4mask = (struct sockaddr_in *)mask;
301 >
302    if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
303        ntohl(v4mask->sin_addr.s_addr))
304      return 0;
# Line 311 | Line 327 | mask_addr(struct irc_ssaddr *ip, int bit
327    if (ip->ss.ss_family != AF_INET6)
328   #endif
329    {
330 <    v4_base_ip = (struct sockaddr_in*)ip;
330 >    v4_base_ip = (struct sockaddr_in *)ip;
331 >
332      mask = ~((1 << (32 - bits)) - 1);
333 <    v4_base_ip->sin_addr.s_addr =
317 <      htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
333 >    v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
334    }
335   #ifdef IPV6
336    else
337    {
338      n = bits / 8;
339      m = bits % 8;
340 <    v6_base_ip = (struct sockaddr_in6*)ip;
340 >    v6_base_ip = (struct sockaddr_in6 *)ip;
341  
342      mask = ~((1 << (8 - m)) -1 );
343      v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask;
344 +
345      for (i = n + 1; i < 16; i++)
346        v6_base_ip->sin6_addr.s6_addr[i] = 0;
347    }
# Line 332 | Line 349 | mask_addr(struct irc_ssaddr *ip, int bit
349   }
350  
351   /* Hashtable stuff...now external as its used in m_stats.c */
352 < struct AddressRec *atable[ATABLE_SIZE];
352 > dlink_list atable[ATABLE_SIZE];
353  
354   void
355   init_host_hash(void)
# Line 345 | Line 362 | init_host_hash(void)
362   * Output: A hash value of the IP address.
363   * Side effects: None
364   */
365 < static unsigned long
365 > static uint32_t
366   hash_ipv4(struct irc_ssaddr *addr, int bits)
367   {
368    if (bits != 0)
369    {
370      struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
371 <    unsigned long av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
372 <    return((av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1));
371 >    uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
372 >
373 >    return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
374    }
375  
376 <  return(0);
376 >  return 0;
377   }
378  
379   /* unsigned long hash_ipv6(struct irc_ssaddr*)
# Line 364 | Line 382 | hash_ipv4(struct irc_ssaddr *addr, int b
382   * Side effects: None
383   */
384   #ifdef IPV6
385 < static unsigned long
385 > static uint32_t
386   hash_ipv6(struct irc_ssaddr *addr, int bits)
387   {
388 <  unsigned long v = 0, n;
389 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6*) addr;
390 <  
388 >  uint32_t v = 0, n;
389 >  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
390 >
391    for (n = 0; n < 16; n++)
392    {
393      if (bits >= 8)
# Line 394 | Line 412 | hash_ipv6(struct irc_ssaddr *addr, int b
412   * Output: The hash of the string between 1 and (TH_MAX-1)
413   * Side-effects: None.
414   */
415 < static int
415 > static uint32_t
416   hash_text(const char *start)
417   {
418    const char *p = start;
419 <  unsigned long h = 0;
419 >  uint32_t h = 0;
420  
421 <  while (*p)
422 <  {
423 <    h = (h << 4) - (h + (unsigned char)ToLower(*p++));
424 <  }
407 <  return (h & (ATABLE_SIZE - 1));
421 >  for (; *p; ++p)
422 >    h = (h << 4) - (h + (unsigned char)ToLower(*p));
423 >
424 >  return h & (ATABLE_SIZE - 1);
425   }
426  
427   /* unsigned long get_hash_mask(const char *)
# Line 413 | Line 430 | hash_text(const char *start)
430   *         wildcard in the string.
431   * Side-effects: None.
432   */
433 < static unsigned long
433 > static uint32_t
434   get_mask_hash(const char *text)
435   {
436    const char *hp = "", *p;
# Line 437 | Line 454 | get_mask_hash(const char *text)
454   * should always be true (i.e. aconf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
455   */
456   struct AccessItem *
457 < find_conf_by_address(const char *name, struct irc_ssaddr *addr, int type,
458 <                     int fam, const char *username, const char *password)
457 > find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type,
458 >                     int fam, const char *username, const char *password, int do_match)
459   {
460 <  unsigned long hprecv = 0;
460 >  unsigned int hprecv = 0;
461 >  dlink_node *ptr = NULL;
462    struct AccessItem *hprec = NULL;
463    struct AddressRec *arec;
464    int b;
465 +  int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp;
466  
467    if (username == NULL)
468      username = "";
# Line 458 | Line 477 | find_conf_by_address(const char *name, s
477      {
478        for (b = 128; b >= 0; b -= 16)
479        {
480 <        for (arec = atable[hash_ipv6(addr, b)]; arec; arec = arec->next)
480 >        DLINK_FOREACH(ptr, atable[hash_ipv6(addr, b)].head)
481 >        {
482 >          arec = ptr->data;
483 >
484            if (arec->type == (type & ~0x1) &&
485                arec->precedence > hprecv &&
486                arec->masktype == HM_IPV6 &&
487                match_ipv6(addr, &arec->Mask.ipa.addr,
488                           arec->Mask.ipa.bits) &&
489 <              (type & 0x1 || match(arec->username, username)) &&
489 >              (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
490                (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
491                 match_conf_password(password, arec->aconf)))
492            {
493              hprecv = arec->precedence;
494              hprec = arec->aconf;
495            }
496 +        }
497        }
498      }
499      else
# Line 479 | Line 502 | find_conf_by_address(const char *name, s
502      {
503        for (b = 32; b >= 0; b -= 8)
504        {
505 <        for (arec = atable[hash_ipv4(addr, b)]; arec; arec = arec->next)
505 >        DLINK_FOREACH(ptr, atable[hash_ipv4(addr, b)].head)
506 >        {
507 >          arec = ptr->data;
508 >
509            if (arec->type == (type & ~0x1) &&
510                arec->precedence > hprecv &&
511                arec->masktype == HM_IPV4 &&
512                match_ipv4(addr, &arec->Mask.ipa.addr,
513                           arec->Mask.ipa.bits) &&
514 <              (type & 0x1 || match(arec->username, username)) &&
514 >              (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
515                (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
516                 match_conf_password(password, arec->aconf)))
517            {
518              hprecv = arec->precedence;
519              hprec = arec->aconf;
520            }
521 +        }
522        }
523      }
524    }
# Line 502 | Line 529 | find_conf_by_address(const char *name, s
529  
530      while (1)
531      {
532 <      for (arec = atable[hash_text(p)]; arec != NULL; arec = arec->next)
533 <        if ((arec->type == (type & ~0x1)) &&
532 >        DLINK_FOREACH(ptr, atable[hash_text(p)].head)
533 >        {
534 >          arec = ptr->data;
535 >          if ((arec->type == (type & ~0x1)) &&
536              arec->precedence > hprecv &&
537              (arec->masktype == HM_HOST) &&
538 <            match(arec->Mask.hostname, name) &&
539 <            (type & 0x1 || match(arec->username, username)) &&
538 >            cmpfunc(arec->Mask.hostname, name) == do_match &&
539 >            (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
540              (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
541               match_conf_password(password, arec->aconf)))
542          {
543            hprecv = arec->precedence;
544            hprec = arec->aconf;
545          }
546 +      }
547        p = strchr(p, '.');
548        if (p == NULL)
549          break;
550        p++;
551      }
552 <    for (arec = atable[0]; arec; arec = arec->next)
552 >
553 >    DLINK_FOREACH(ptr, atable[0].head)
554 >    {
555 >      arec = ptr->data;
556 >
557        if (arec->type == (type & ~0x1) &&
558            arec->precedence > hprecv &&
559            arec->masktype == HM_HOST &&
560 <          match(arec->Mask.hostname, name) &&
561 <          (type & 0x1 || match(arec->username, username)) &&
560 >          cmpfunc(arec->Mask.hostname, name) == do_match &&
561 >          (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
562            (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
563             match_conf_password(password, arec->aconf)))
564        {
565          hprecv = arec->precedence;
566          hprec = arec->aconf;
567        }
568 +    }
569    }
570  
571    return hprec;
# Line 550 | Line 585 | find_address_conf(const char *host, cons
585  
586    /* Find the best I-line... If none, return NULL -A1kmm */
587    if ((iconf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
588 <                                    password)) == NULL)
589 <    return(NULL);
588 >                                    password, 1)) == NULL)
589 >    return NULL;
590  
591    /* If they are exempt from K-lines, return the best I-line. -A1kmm */
592    if (IsConfExemptKline(iconf))
593 <    return(iconf);
593 >    return iconf;
594  
595    /* Find the best K-line... -A1kmm */
596 <  kconf = find_conf_by_address(host, ip, CONF_KILL, aftype, user, NULL);
596 >  kconf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
597  
598    /* If they are K-lined, return the K-line. Otherwise, return the
599     * I-line. -A1kmm */
600    if (kconf != NULL)
601 <    return(kconf);
601 >    return kconf;
602  
603 <  kconf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL);
603 >  kconf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
604    if (kconf != NULL && !IsConfExemptGline(iconf))
605 <    return(kconf);
605 >    return kconf;
606  
607 <  return(iconf);
607 >  return iconf;
608   }
609  
610   struct AccessItem *
# Line 579 | Line 614 | find_gline_conf(const char *host, const
614    struct AccessItem *eline;
615  
616    eline = find_conf_by_address(host, ip, CONF_EXEMPTKLINE, aftype,
617 <                               user, NULL);
617 >                               user, NULL, 1);
618    if (eline != NULL)
619 <    return(eline);
619 >    return eline;
620  
621 <  return(find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL));
621 >  return find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
622   }
623  
624   /* find_kline_conf
# Line 596 | Line 631 | find_gline_conf(const char *host, const
631   */
632   struct AccessItem *
633   find_kline_conf(const char *host, const char *user,
634 <                struct irc_ssaddr *ip, int aftype)
634 >                struct irc_ssaddr *ip, int aftype)
635   {
636    struct AccessItem *eline;
637  
638    eline = find_conf_by_address(host, ip, CONF_EXEMPTKLINE, aftype,
639 <                               user, NULL);
639 >                               user, NULL, 1);
640    if (eline != NULL)
641 <    return(eline);
641 >    return eline;
642  
643 <  return(find_conf_by_address(host, ip, CONF_KILL, aftype, user, NULL));
643 >  return find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
644   }
645  
646   /* struct AccessItem* find_dline_conf(struct irc_ssaddr*, int)
# Line 620 | Line 655 | find_dline_conf(struct irc_ssaddr *addr,
655    struct AccessItem *eline;
656  
657    eline = find_conf_by_address(NULL, addr, CONF_EXEMPTDLINE | 1, aftype,
658 <                               NULL, NULL);
658 >                               NULL, NULL, 1);
659    if (eline != NULL)
660 <    return(eline);
661 <  return(find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL));
660 >    return eline;
661 >
662 >  return find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL, 1);
663   }
664  
665   /* void add_conf_by_address(int, struct AccessItem *aconf)
# Line 632 | Line 668 | find_dline_conf(struct irc_ssaddr *addr,
668   * Side-effects: Adds this entry to the hash table.
669   */
670   void
671 < add_conf_by_address(int type, struct AccessItem *aconf)
671 > add_conf_by_address(const unsigned int type, struct AccessItem *aconf)
672   {
673    const char *address;
674    const char *username;
675 <  static unsigned long prec_value = 0xFFFFFFFF;
676 <  int masktype, bits;
641 <  unsigned long hv;
675 >  static unsigned int prec_value = 0xFFFFFFFF;
676 >  int bits = 0;
677    struct AddressRec *arec;
678  
679    address = aconf->host;
# Line 651 | Line 686 | add_conf_by_address(int type, struct Acc
686      address = "/NOMATCH!/";
687  
688    arec = MyMalloc(sizeof(struct AddressRec));
689 <  masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
689 >  arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
690    arec->Mask.ipa.bits = bits;
656 –  arec->masktype = masktype;
657 – #ifdef IPV6
658 –  if (masktype == HM_IPV6)
659 –  {
660 –    /* We have to do this, since we do not re-hash for every bit -A1kmm. */
661 –    bits -= bits % 16;
662 –    arec->next = atable[(hv = hash_ipv6(&arec->Mask.ipa.addr, bits))];
663 –    atable[hv] = arec;
664 –  }
665 –  else
666 – #endif
667 –  if (masktype == HM_IPV4)
668 –  {
669 –    /* We have to do this, since we do not re-hash for every bit -A1kmm. */
670 –    bits -= bits % 8;
671 –    arec->next = atable[(hv = hash_ipv4(&arec->Mask.ipa.addr, bits))];
672 –    atable[hv] = arec;
673 –  }
674 –  else
675 –  {
676 –    arec->Mask.hostname = address;
677 –    arec->next = atable[(hv = get_mask_hash(address))];
678 –    atable[hv] = arec;
679 –  }
691    arec->username = username;
692    arec->aconf = aconf;
693    arec->precedence = prec_value--;
694    arec->type = type;
695 +
696 +  switch (arec->masktype)
697 +  {
698 +    case HM_IPV4:
699 +      /* We have to do this, since we do not re-hash for every bit -A1kmm. */
700 +      bits -= bits % 8;
701 +      dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]);
702 +      break;
703 + #ifdef IPV6
704 +    case HM_IPV6:
705 +      /* We have to do this, since we do not re-hash for every bit -A1kmm. */
706 +      bits -= bits % 16;
707 +      dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]);
708 +      break;
709 + #endif
710 +    default: /* HM_HOST */
711 +      arec->Mask.hostname = address;
712 +      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(address)]);
713 +      break;
714 +  }
715   }
716  
717   /* void delete_one_address(const char*, struct AccessItem*)
# Line 692 | Line 723 | add_conf_by_address(int type, struct Acc
723   void
724   delete_one_address_conf(const char *address, struct AccessItem *aconf)
725   {
726 <  int masktype, bits;
727 <  unsigned long hv;
728 <  struct AddressRec *arec, *arecl = NULL;
726 >  int bits = 0;
727 >  uint32_t hv = 0;
728 >  dlink_node *ptr = NULL, *ptr_next = NULL;
729    struct irc_ssaddr addr;
699 –  masktype = parse_netmask(address, &addr, &bits);
730  
731 < #ifdef IPV6
702 <  if (masktype == HM_IPV6)
731 >  switch (parse_netmask(address, &addr, &bits))
732    {
733 <    /* We have to do this, since we do not re-hash for every bit -A1kmm. */
734 <    bits -= bits % 16;
735 <    hv = hash_ipv6(&addr, bits);
736 <  }
737 <  else
733 >    case HM_IPV4:
734 >      /* We have to do this, since we do not re-hash for every bit -A1kmm. */
735 >      bits -= bits % 8;
736 >      hv = hash_ipv4(&addr, bits);
737 >      break;
738 > #ifdef IPV6
739 >    case HM_IPV6:
740 >      /* We have to do this, since we do not re-hash for every bit -A1kmm. */
741 >      bits -= bits % 16;
742 >      hv = hash_ipv6(&addr, bits);
743 >      break;
744   #endif
745 <  if (masktype == HM_IPV4)
746 <  {
747 <    /* We have to do this, since we do not re-hash for every bit -A1kmm. */
713 <    bits -= bits % 8;
714 <    hv = hash_ipv4(&addr, bits);
745 >    default: /* HM_HOST */
746 >      hv = get_mask_hash(address);
747 >      break;
748    }
749 <  else
750 <    hv = get_mask_hash(address);
718 <  for (arec = atable[hv]; arec; arec = arec->next)
749 >
750 >  DLINK_FOREACH_SAFE(ptr, ptr_next, atable[hv].head)
751    {
752 +    struct AddressRec *arec = ptr->data;
753 +
754      if (arec->aconf == aconf)
755      {
756 <      if (arecl)
723 <        arecl->next = arec->next;
724 <      else
725 <        atable[hv] = arec->next;
756 >      dlinkDelete(&arec->node, &atable[hv]);
757        aconf->status |= CONF_ILLEGAL;
758 <      if (aconf->clients == 0)
758 >
759 >      if (!aconf->clients)
760          free_access_item(aconf);
761 +
762        MyFree(arec);
763        return;
764      }
732 –    arecl = arec;
765    }
766   }
767  
# Line 743 | Line 775 | delete_one_address_conf(const char *addr
775   void
776   clear_out_address_conf(void)
777   {
778 <  int i;
779 <  struct AddressRec *arec;
748 <  struct AddressRec *last_arec;
749 <  struct AddressRec *next_arec;
778 >  unsigned int i = 0;
779 >  dlink_node *ptr = NULL, *ptr_next = NULL;
780  
781 <  for (i = 0; i < ATABLE_SIZE; i++)
781 >  for (i = 0; i < ATABLE_SIZE; ++i)
782    {
783 <    last_arec = NULL;
784 <    for (arec = atable[i]; arec; arec = next_arec)
783 >    ptr = ptr_next = NULL;
784 >
785 >    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
786      {
787 +      struct AddressRec *arec = ptr->data;
788 +
789        /* We keep the temporary K-lines and destroy the
790         * permanent ones, just to be confusing :) -A1kmm
791         */  
792 <      next_arec = arec->next;
760 <
761 <      if (arec->aconf->flags & CONF_FLAGS_TEMPORARY)
762 <      {
763 <        last_arec = arec;
764 <      }
765 <      else  
792 >      if (!(arec->aconf->flags & CONF_FLAGS_TEMPORARY))
793        {
794 +        dlinkDelete(&arec->node, &atable[i]);
795          /* unlink it from link list - Dianora */
768 –  
769 –        if (last_arec == NULL)
770 –        {
771 –          atable[i] = next_arec;
772 –        }
773 –        else
774 –        {
775 –          last_arec->next = next_arec;
776 –        }
777 –
796          arec->aconf->status |= CONF_ILLEGAL;
797 <        if (arec->aconf->clients == 0)
797 >
798 >        if (!arec->aconf->clients)
799            free_access_item(arec->aconf);
800          MyFree(arec);
801        }
# Line 784 | Line 803 | clear_out_address_conf(void)
803    }
804   }
805  
806 + static void
807 + hostmask_send_expiration(struct AddressRec *arec)
808 + {
809 +  char ban_type = '\0';
810 +
811 +  if (!ConfigFileEntry.tkline_expire_notices)
812 +    return;
813 +
814 +  switch (arec->type)
815 +  {
816 +    case CONF_KLINE:
817 +      ban_type = 'K';
818 +      break;
819 +    case CONF_DLINE:
820 +      ban_type = 'D';
821 +      break;
822 +    case CONF_GLINE:
823 +      ban_type = 'G';
824 +      break;
825 +  }
826 +  
827 +  sendto_realops_flags(UMODE_ALL, L_ALL,
828 +                       "Temporary %c-line for [%s@%s] expired", ban_type,
829 +                       (arec->aconf->user) ? arec->aconf->user : "*",
830 +                       (arec->aconf->host) ? arec->aconf->host : "*");
831 + }
832 +
833 + void
834 + hostmask_expire_temporary(void)
835 + {
836 +  unsigned int i = 0;
837 +  dlink_node *ptr = NULL, *ptr_next = NULL;
838 +
839 +  for (i = 0; i < ATABLE_SIZE; ++i)
840 +  {
841 +    ptr = ptr_next = NULL;
842 +
843 +    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
844 +    {
845 +      struct AddressRec *arec = ptr->data;
846 +
847 +      if (!IsConfTemporary(arec->aconf) || arec->aconf->hold > CurrentTime)
848 +        continue;
849 +
850 +      switch (arec->type)
851 +      {
852 +        case CONF_KLINE:
853 +        case CONF_DLINE:
854 +        case CONF_GLINE:
855 +          hostmask_send_expiration(arec);
856 +
857 +          dlinkDelete(&arec->node, &atable[i]);
858 +          free_access_item(arec->aconf);
859 +          MyFree(arec);
860 +          break;
861 +      }
862 +    }
863 +  }
864 + }
865 +
866   /*
867   * show_iline_prefix()
868   *
# Line 797 | Line 876 | char *
876   show_iline_prefix(struct Client *sptr, struct AccessItem *aconf, const char *name)
877   {
878    static char prefix_of_host[USERLEN + 14];
879 <  char *prefix_ptr;
879 >  char *prefix_ptr = prefix_of_host;
880  
802 –  prefix_ptr = prefix_of_host;
881    if (IsNoTilde(aconf))
882      *prefix_ptr++ = '-';
883    if (IsLimitIp(aconf))
# Line 820 | Line 898 | show_iline_prefix(struct Client *sptr, s
898      *prefix_ptr++ = '_';
899    if (MyOper(sptr) && IsConfExemptLimits(aconf))
900      *prefix_ptr++ = '>';
823 –  if (MyOper(sptr) && IsConfIdlelined(aconf))
824 –    *prefix_ptr++ = '<';
901    if (IsConfCanFlood(aconf))
902      *prefix_ptr++ = '|';
903 +
904    strlcpy(prefix_ptr, name, USERLEN+1);
905  
906 <  return(prefix_of_host);
906 >  return prefix_of_host;
907   }
908  
909   /* report_auth()
# Line 838 | Line 915 | show_iline_prefix(struct Client *sptr, s
915   void
916   report_auth(struct Client *client_p)
917   {
841 –  struct AddressRec *arec;
918    struct ConfItem *conf;
919    struct AccessItem *aconf;
920 <  int i;
920 >  dlink_node *ptr = NULL;
921 >  unsigned int i;
922  
923 <  for (i = 0; i < ATABLE_SIZE; i++)
923 >
924 >  for (i = 0; i < ATABLE_SIZE; ++i)
925    {
926 <    for (arec = atable[i]; arec; arec = arec->next)
926 >    ptr = NULL;
927 >
928 >    DLINK_FOREACH(ptr, atable[i].head)
929      {
930 +      struct AddressRec *arec = ptr->data;
931 +
932        if (arec->type == CONF_CLIENT)
933        {
934          aconf = arec->aconf;
# Line 890 | Line 972 | report_auth(struct Client *client_p)
972   void
973   report_Klines(struct Client *client_p, int tkline)
974   {
893 –  struct AddressRec *arec = NULL;
975    struct AccessItem *aconf = NULL;
976 <  int i;
976 >  unsigned int i = 0;
977    const char *p = NULL;
978 +  dlink_node *ptr = NULL;
979  
980    if (tkline)
981      p = "k";
982    else
983      p = "K";
984  
985 <  for (i = 0; i < ATABLE_SIZE; i++)
985 >  for (i = 0; i < ATABLE_SIZE; ++i)
986    {
987 <    for (arec = atable[i]; arec; arec = arec->next)
987 >    ptr = NULL;
988 >
989 >    DLINK_FOREACH(ptr, atable[i].head)
990      {
991 <      if (arec->type == CONF_KILL)
991 >      struct AddressRec *arec = ptr->data;
992 >
993 >      if (arec->type == CONF_KLINE)
994        {
995          if ((tkline && !((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY)) ||
996              (!tkline && ((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY)))
997            continue;
998  
999 <        if (IsOper(client_p))
1000 <          sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
999 >        if (HasUMode(client_p, UMODE_OPER))
1000 >          sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
1001                       client_p->name, p, aconf->host, aconf->user,
1002 <                     aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
1003 <        else
1002 >                     aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
1003 >        else
1004            sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
1005                       client_p->name, p, aconf->host, aconf->user,
1006 <                     aconf->reason, "");
1006 >                     aconf->reason, "");
1007        }
1008      }
1009    }

Diff Legend

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