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 3235 by michael, Sat Mar 29 19:34:16 2014 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-2014 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 18 | Line 17
17   *  along with this program; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
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 51 | Line 53
53   * Side effects: None
54   * Comments: Called from parse_netmask
55   */
56 < /* Fixed so ::/0 (any IPv6 address) is valid
56 > /* Fixed so ::/0 (any IPv6 address) is valid
57     Also a bug in DigitParse above.
58     -Gozem 2002-07-19 gozem@linux.nu
59   */
# Line 70 | Line 72 | try_parse_v6_netmask(const char *text, s
72    short dc[8];
73    struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
74  
75 <  for (p = text; (c = *p); p++)
75 >  for (p = text; (c = *p); ++p)
76 >  {
77      if (IsXDigit(c))
78      {
79        if (nyble == 0)
# 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   }
# Line 179 | Line 183 | try_parse_v4_netmask(const char *text, s
183  
184    digits[n++] = text;
185  
186 <  for (p = text; (c = *p); p++)
186 >  for (p = text; (c = *p); ++p)
187 >  {
188      if (c >= '0' && c <= '9')   /* empty */
189        ;
190      else if (c == '.')
# Line 202 | Line 207 | try_parse_v4_netmask(const char *text, s
207        char *after;
208        bits = strtoul(p + 1, &after, 10);
209  
210 <      if (!bits || *after)
210 >      if (bits < 0 || *after)
211          return HM_HOST;
212        if (bits > n * 8)
213          return HM_HOST;
# Line 211 | Line 216 | try_parse_v4_netmask(const char *text, s
216      }
217      else
218        return HM_HOST;
219 +  }
220  
221    if (n < 4 && bits == 0)
222      bits = n * 8;
# Line 218 | Line 224 | try_parse_v4_netmask(const char *text, s
224      while (n < 4)
225        digits[n++] = "0";
226  
227 <  for (n = 0; n < 4; n++)
227 >  for (n = 0; n < 4; ++n)
228      addb[n] = strtoul(digits[n], NULL, 10);
229  
230    if (bits == 0)
# Line 227 | Line 233 | try_parse_v4_netmask(const char *text, s
233    /* Set unused bits to 0... -A1kmm */
234    if (bits < 32 && bits % 8)
235      addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1);
236 <  for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; n++)
236 >  for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; ++n)
237      addb[n] = 0;
238    if (addr)
239      v4->sin_addr.s_addr =
240        htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]);
241 <  if (b != NULL)
241 >  if (b)
242      *b = bits;
243    return HM_IPV4;
244   }
# Line 247 | Line 253 | try_parse_v4_netmask(const char *text, s
253   int
254   parse_netmask(const char *text, struct irc_ssaddr *addr, int *b)
255   {
256 +  if (strchr(text, '.'))
257 +    return try_parse_v4_netmask(text, addr, b);
258   #ifdef IPV6
259    if (strchr(text, ':'))
260      return try_parse_v6_netmask(text, addr, b);
261   #endif
254 –  if (strchr(text, '.'))
255 –    return try_parse_v4_netmask(text, addr, b);
262    return HM_HOST;
263   }
264  
# Line 264 | Line 270 | parse_netmask(const char *text, struct i
270   */
271   #ifdef IPV6
272   int
273 < match_ipv6(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits)
273 > match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
274   {
275    int i, m, n = bits / 8;
276 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
277 <  struct sockaddr_in6 *v6mask = (struct sockaddr_in6 *)mask;
276 >  const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
277 >  const struct sockaddr_in6 *v6mask = (const struct sockaddr_in6 *)mask;
278  
279 <  for (i = 0; i < n; i++)
279 >  for (i = 0; i < n; ++i)
280      if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
281        return 0;
282 +
283    if ((m = bits % 8) == 0)
284      return -1;
285    if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) ==
# Line 288 | Line 295 | match_ipv6(struct irc_ssaddr *addr, stru
295   * Side Effects: None
296   */
297   int
298 < match_ipv4(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits)
298 > match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
299   {
300 <  struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
301 <  struct sockaddr_in *v4mask = (struct sockaddr_in *)mask;
300 >  const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
301 >  const struct sockaddr_in *v4mask = (const struct sockaddr_in *)mask;
302  
303    if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
304        ntohl(v4mask->sin_addr.s_addr))
# Line 357 | Line 364 | init_host_hash(void)
364   * Side effects: None
365   */
366   static uint32_t
367 < hash_ipv4(struct irc_ssaddr *addr, int bits)
367 > hash_ipv4(const struct irc_ssaddr *addr, int bits)
368   {
369    if (bits != 0)
370    {
371 <    struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
371 >    const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
372      uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
373  
374      return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
# Line 377 | Line 384 | hash_ipv4(struct irc_ssaddr *addr, int b
384   */
385   #ifdef IPV6
386   static uint32_t
387 < hash_ipv6(struct irc_ssaddr *addr, int bits)
387 > hash_ipv6(const struct irc_ssaddr *addr, int bits)
388   {
389    uint32_t v = 0, n;
390 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
390 >  const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
391  
392 <  for (n = 0; n < 16; n++)
392 >  for (n = 0; n < 16; ++n)
393    {
394      if (bits >= 8)
395      {
# Line 413 | Line 420 | hash_text(const char *start)
420    uint32_t h = 0;
421  
422    for (; *p; ++p)
423 <    h = (h << 4) - (h + (unsigned char)ToLower(*p));
423 >    h = (h << 4) - (h + ToLower(*p));
424  
425    return h & (ATABLE_SIZE - 1);
426   }
# Line 429 | Line 436 | get_mask_hash(const char *text)
436   {
437    const char *hp = "", *p;
438  
439 <  for (p = text + strlen(text) - 1; p >= text; p--)
439 >  for (p = text + strlen(text) - 1; p >= text; --p)
440      if (IsMWildChar(*p))
441        return hash_text(hp);
442      else if (*p == '.')
# Line 437 | Line 444 | get_mask_hash(const char *text)
444    return hash_text(text);
445   }
446  
447 < /* struct AccessItem *find_conf_by_address(const char *, struct irc_ssaddr *,
447 > /* struct MaskItem *find_conf_by_address(const char *, struct irc_ssaddr *,
448   *                                         int type, int fam, const char *username)
449   * Input: The hostname, the address, the type of mask to find, the address
450   *        family, the username.
# Line 445 | Line 452 | get_mask_hash(const char *text)
452   * Side-effects: None
453   * Note: Setting bit 0 of the type means that the username is ignored.
454   * Warning: IsNeedPassword for everything that is not an auth{} entry
455 < * should always be true (i.e. aconf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
455 > * should always be true (i.e. conf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
456   */
457 < struct AccessItem *
457 > struct MaskItem *
458   find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type,
459                       int fam, const char *username, const char *password, int do_match)
460   {
461    unsigned int hprecv = 0;
462    dlink_node *ptr = NULL;
463 <  struct AccessItem *hprec = NULL;
464 <  struct AddressRec *arec;
463 >  struct MaskItem *hprec = NULL;
464 >  struct AddressRec *arec = NULL;
465    int b;
466    int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp;
467  
461 –  if (username == NULL)
462 –    username = "";
463 –  if (password == NULL)
464 –    password = "";
465 –
468    if (addr)
469    {
470      /* Check for IPV6 matches... */
# Line 473 | Line 475 | find_conf_by_address(const char *name, s
475        {
476          DLINK_FOREACH(ptr, atable[hash_ipv6(addr, b)].head)
477          {
478 <          arec = ptr->data;
478 >          arec = ptr->data;
479  
480 <          if (arec->type == (type & ~0x1) &&
480 >          if ((arec->type == type) &&
481                arec->precedence > hprecv &&
482                arec->masktype == HM_IPV6 &&
483                match_ipv6(addr, &arec->Mask.ipa.addr,
484                           arec->Mask.ipa.bits) &&
485 <              (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
486 <              (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
487 <               match_conf_password(password, arec->aconf)))
485 >              (!username || !cmpfunc(arec->username, username)) &&
486 >              (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
487 >               match_conf_password(password, arec->conf)))
488            {
489              hprecv = arec->precedence;
490 <            hprec = arec->aconf;
490 >            hprec = arec->conf;
491            }
492          }
493        }
# Line 500 | Line 502 | find_conf_by_address(const char *name, s
502          {
503            arec = ptr->data;
504  
505 <          if (arec->type == (type & ~0x1) &&
505 >          if ((arec->type == type) &&
506                arec->precedence > hprecv &&
507                arec->masktype == HM_IPV4 &&
508                match_ipv4(addr, &arec->Mask.ipa.addr,
509                           arec->Mask.ipa.bits) &&
510 <              (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
511 <              (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
512 <               match_conf_password(password, arec->aconf)))
510 >              (!username || !cmpfunc(arec->username, username)) &&
511 >              (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
512 >               match_conf_password(password, arec->conf)))
513            {
514              hprecv = arec->precedence;
515 <            hprec = arec->aconf;
515 >            hprec = arec->conf;
516            }
517          }
518        }
519      }
520    }
521  
522 <  if (name != NULL)
522 >  if (name)
523    {
524      const char *p = name;
525  
# Line 526 | Line 528 | find_conf_by_address(const char *name, s
528          DLINK_FOREACH(ptr, atable[hash_text(p)].head)
529          {
530            arec = ptr->data;
531 <          if ((arec->type == (type & ~0x1)) &&
531 >          if ((arec->type == type) &&
532              arec->precedence > hprecv &&
533              (arec->masktype == HM_HOST) &&
534 <            cmpfunc(arec->Mask.hostname, name) == do_match &&
535 <            (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
536 <            (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
537 <             match_conf_password(password, arec->aconf)))
534 >            !cmpfunc(arec->Mask.hostname, name) &&
535 >            (!username || !cmpfunc(arec->username, username)) &&
536 >            (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
537 >             match_conf_password(password, arec->conf)))
538          {
539            hprecv = arec->precedence;
540 <          hprec = arec->aconf;
540 >          hprec = arec->conf;
541          }
542        }
543 <      p = strchr(p, '.');
544 <      if (p == NULL)
543 >
544 >      if ((p = strchr(p, '.')) == NULL)
545          break;
546 <      p++;
546 >      ++p;
547      }
548  
549      DLINK_FOREACH(ptr, atable[0].head)
550      {
551        arec = ptr->data;
552  
553 <      if (arec->type == (type & ~0x1) &&
553 >      if (arec->type == type &&
554            arec->precedence > hprecv &&
555            arec->masktype == HM_HOST &&
556 <          cmpfunc(arec->Mask.hostname, name) == do_match &&
557 <          (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
558 <          (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
559 <           match_conf_password(password, arec->aconf)))
556 >          !cmpfunc(arec->Mask.hostname, name) &&
557 >          (!username || !cmpfunc(arec->username, username)) &&
558 >          (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
559 >           match_conf_password(password, arec->conf)))
560        {
561          hprecv = arec->precedence;
562 <        hprec = arec->aconf;
562 >        hprec = arec->conf;
563        }
564      }
565    }
# Line 565 | Line 567 | find_conf_by_address(const char *name, s
567    return hprec;
568   }
569  
570 < /* struct AccessItem* find_address_conf(const char*, const char*,
570 > /* struct MaskItem* find_address_conf(const char*, const char*,
571   *                                     struct irc_ssaddr*, int, char *);
572   * Input: The hostname, username, address, address family.
573 < * Output: The applicable AccessItem.
573 > * Output: The applicable MaskItem.
574   * Side-effects: None
575   */
576 < struct AccessItem *
576 > struct MaskItem *
577   find_address_conf(const char *host, const char *user,
578                    struct irc_ssaddr *ip, int aftype, char *password)
579   {
580 <  struct AccessItem *iconf, *kconf;
580 >  struct MaskItem *authcnf = NULL, *killcnf = NULL;
581  
582 <  /* Find the best I-line... If none, return NULL -A1kmm */
583 <  if ((iconf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
584 <                                    password, 1)) == NULL)
582 >  /* Find the best auth{} block... If none, return NULL -A1kmm */
583 >  if ((authcnf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
584 >                                      password, 1)) == NULL)
585      return NULL;
586  
587 <  /* If they are exempt from K-lines, return the best I-line. -A1kmm */
588 <  if (IsConfExemptKline(iconf))
589 <    return iconf;
587 >  /* If they are exempt from K-lines, return the best auth{} block. -A1kmm */
588 >  if (IsConfExemptKline(authcnf))
589 >    return authcnf;
590  
591    /* Find the best K-line... -A1kmm */
592 <  kconf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
592 >  killcnf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
593  
594 <  /* If they are K-lined, return the K-line. Otherwise, return the
595 <   * I-line. -A1kmm */
596 <  if (kconf != NULL)
597 <    return kconf;
594 >  /*
595 >   * If they are K-lined, return the K-line. Otherwise, return the
596 >   * auth{} block. -A1kmm
597 >   */
598 >  if (killcnf)
599 >    return killcnf;
600  
601 <  kconf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
602 <  if (kconf != NULL && !IsConfExemptGline(iconf))
599 <    return kconf;
601 >  if (IsConfExemptGline(authcnf))
602 >    return authcnf;
603  
604 <  return iconf;
605 < }
604 >  killcnf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
605 >  if (killcnf)
606 >    return killcnf;
607  
608 < 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);
616 < }
617 <
618 < /* 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);
608 >  return authcnf;
609   }
610  
611 < /* struct AccessItem* find_dline_conf(struct irc_ssaddr*, int)
611 > /* struct MaskItem* find_dline_conf(struct irc_ssaddr*, int)
612   *
613   * Input:       An address, an address family.
614   * Output:      The best matching D-line or exempt line.
615   * Side effects: None.
616   */
617 < struct AccessItem *
617 > struct MaskItem *
618   find_dline_conf(struct irc_ssaddr *addr, int aftype)
619   {
620 <  struct AccessItem *eline;
620 >  struct MaskItem *eline;
621  
622 <  eline = find_conf_by_address(NULL, addr, CONF_EXEMPTDLINE | 1, aftype,
623 <                               NULL, NULL, 1);
653 <  if (eline != NULL)
622 >  eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, aftype, NULL, NULL, 1);
623 >  if (eline)
624      return eline;
625  
626 <  return find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL, 1);
626 >  return find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1);
627   }
628  
629 < /* void add_conf_by_address(int, struct AccessItem *aconf)
630 < * Input:
629 > /* void add_conf_by_address(int, struct MaskItem *aconf)
630 > * Input:
631   * Output: None
632   * Side-effects: Adds this entry to the hash table.
633   */
634 < void
635 < add_conf_by_address(const unsigned int type, struct AccessItem *aconf)
634 > struct AddressRec *
635 > add_conf_by_address(const unsigned int type, struct MaskItem *conf)
636   {
637 <  const char *address;
638 <  const char *username;
637 >  const char *hostname = conf->host;
638 >  const char *username = conf->user;
639    static unsigned int prec_value = 0xFFFFFFFF;
640    int bits = 0;
641 <  struct AddressRec *arec;
672 <
673 <  address = aconf->host;
674 <  username = aconf->user;
641 >  struct AddressRec *arec = NULL;
642  
643 <  assert(type != 0);
677 <  assert(aconf != NULL);
678 <
679 <  if (EmptyString(address))
680 <    address = "/NOMATCH!/";
643 >  assert(type && !EmptyString(hostname));
644  
645    arec = MyMalloc(sizeof(struct AddressRec));
646 <  arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
646 >  arec->masktype = parse_netmask(hostname, &arec->Mask.ipa.addr, &bits);
647    arec->Mask.ipa.bits = bits;
648    arec->username = username;
649 <  arec->aconf = aconf;
649 >  arec->conf = conf;
650    arec->precedence = prec_value--;
651    arec->type = type;
652  
# Line 702 | Line 665 | add_conf_by_address(const unsigned int t
665        break;
666   #endif
667      default: /* HM_HOST */
668 <      arec->Mask.hostname = address;
669 <      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(address)]);
668 >      arec->Mask.hostname = hostname;
669 >      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(hostname)]);
670        break;
671    }
672 +
673 +  return arec;
674   }
675  
676 < /* void delete_one_address(const char*, struct AccessItem*)
677 < * Input: An address string, the associated AccessItem.
676 > /* void delete_one_address(const char*, struct MaskItem*)
677 > * Input: An address string, the associated MaskItem.
678   * Output: None
679 < * Side effects: Deletes an address record. Frees the AccessItem if there
679 > * Side effects: Deletes an address record. Frees the MaskItem if there
680   *               is nothing referencing it, sets it as illegal otherwise.
681   */
682   void
683 < delete_one_address_conf(const char *address, struct AccessItem *aconf)
683 > delete_one_address_conf(const char *address, struct MaskItem *conf)
684   {
685    int bits = 0;
686    uint32_t hv = 0;
# Line 745 | Line 710 | delete_one_address_conf(const char *addr
710    {
711      struct AddressRec *arec = ptr->data;
712  
713 <    if (arec->aconf == aconf)
713 >    if (arec->conf == conf)
714      {
715        dlinkDelete(&arec->node, &atable[hv]);
751 –      aconf->status |= CONF_ILLEGAL;
716  
717 <      if (!aconf->clients)
718 <        free_access_item(aconf);
717 >      if (!conf->ref_count)
718 >        conf_free(conf);
719  
720        MyFree(arec);
721        return;
# Line 763 | Line 727 | delete_one_address_conf(const char *addr
727   * Input: None
728   * Output: None
729   * Side effects: Clears out all address records in the hash table,
730 < *               frees them, and frees the AccessItems if nothing references
731 < *               them, otherwise sets them as illegal.  
730 > *               frees them, and frees the MaskItems if nothing references
731 > *               them, otherwise sets them as illegal.
732   */
733   void
734   clear_out_address_conf(void)
735   {
772 –  unsigned int i = 0;
736    dlink_node *ptr = NULL, *ptr_next = NULL;
737 <
738 <  for (i = 0; i < ATABLE_SIZE; ++i)
737 >
738 >  for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
739    {
740      DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
741      {
742        struct AddressRec *arec = ptr->data;
743  
744 <      /* We keep the temporary K-lines and destroy the
745 <       * permanent ones, just to be confusing :) -A1kmm
746 <       */  
747 <      if (!(arec->aconf->flags & CONF_FLAGS_TEMPORARY))
748 <      {
749 <        dlinkDelete(&arec->node, &atable[i]);
750 <        /* unlink it from link list - Dianora */
751 <        arec->aconf->status |= CONF_ILLEGAL;
752 <
753 <        if (!arec->aconf->clients)
754 <          free_access_item(arec->aconf);
755 <        MyFree(arec);
793 <      }
744 >      /*
745 >       * We keep the temporary K-lines and destroy the permanent ones,
746 >       * just to be confusing :) -A1kmm
747 >       */
748 >      if (arec->conf->until || IsConfDatabase(arec->conf))
749 >        continue;
750 >
751 >      dlinkDelete(&arec->node, &atable[i]);
752 >
753 >      if (!arec->conf->ref_count)
754 >        conf_free(arec->conf);
755 >      MyFree(arec);
756      }
757    }
758   }
# Line 814 | Line 776 | hostmask_send_expiration(struct AddressR
776      case CONF_GLINE:
777        ban_type = 'G';
778        break;
779 +    default: break;
780    }
781 <  
782 <  sendto_realops_flags(UMODE_ALL, L_ALL,
781 >
782 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
783                         "Temporary %c-line for [%s@%s] expired", ban_type,
784 <                       (arec->aconf->user) ? arec->aconf->user : "*",
785 <                       (arec->aconf->host) ? arec->aconf->host : "*");
784 >                       (arec->conf->user) ? arec->conf->user : "*",
785 >                       (arec->conf->host) ? arec->conf->host : "*");
786   }
787  
788   void
789   hostmask_expire_temporary(void)
790   {
828 –  unsigned int i = 0;
791    dlink_node *ptr = NULL, *ptr_next = NULL;
792  
793 <  for (i = 0; i < ATABLE_SIZE; ++i)
793 >  for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
794    {
795      DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
796      {
797        struct AddressRec *arec = ptr->data;
798  
799 <      if (!IsConfTemporary(arec->aconf) || arec->aconf->hold > CurrentTime)
799 >      if (!arec->conf->until || arec->conf->until > CurrentTime)
800          continue;
801  
802        switch (arec->type)
# Line 845 | Line 807 | hostmask_expire_temporary(void)
807            hostmask_send_expiration(arec);
808  
809            dlinkDelete(&arec->node, &atable[i]);
810 <          free_access_item(arec->aconf);
810 >          conf_free(arec->conf);
811            MyFree(arec);
812            break;
813 +        default: break;
814        }
815      }
816    }

Diff Legend

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