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/trunk/src/hostmask.c (file contents):
Revision 2916 by michael, Sat Jan 25 21:09:18 2014 UTC vs.
Revision 4977 by michael, Thu Dec 4 15:12:24 2014 UTC

# 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  
# Line 57 | Line 57
57     Also a bug in DigitParse above.
58     -Gozem 2002-07-19 gozem@linux.nu
59   */
60 – #ifdef IPV6
60   static int
61   try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
62   {
64 –  const char *p;
63    char c;
64    int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
65    int dp = 0;
# Line 70 | Line 68 | try_parse_v6_netmask(const char *text, s
68    int bits = 128;
69    int deficit = 0;
70    short dc[8];
71 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
71 >  struct sockaddr_in6 *const v6 = (struct sockaddr_in6 *)addr;
72  
73 <  for (p = text; (c = *p); p++)
73 >  for (const char *p = text; (c = *p); ++p)
74    {
75      if (IsXDigit(c))
76      {
# Line 111 | Line 109 | try_parse_v6_netmask(const char *text, s
109        char *after;
110  
111        d[dp] = d[dp] >> 4 * nyble;
112 <      dp++;
112 >      ++dp;
113        bits = strtoul(p + 1, &after, 10);
114  
115        if (bits < 0 || *after)
# Line 127 | Line 125 | try_parse_v6_netmask(const char *text, s
125    d[dp] = d[dp] >> 4 * nyble;
126  
127    if (c == 0)
128 <    dp++;
128 >    ++dp;
129    if (finsert < 0 && bits == 0)
130      bits = dp * 16;
131  
# Line 135 | Line 133 | try_parse_v6_netmask(const char *text, s
133    deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp;
134  
135    /* Now fill in the gaps(from ::) in the copied table... -A1kmm */
136 <  for (dp = 0, nyble = 0; dp < 8; dp++)
136 >  for (dp = 0, nyble = 0; dp < 8; ++dp)
137    {
138      if (nyble == finsert && deficit)
139      {
# Line 149 | Line 147 | try_parse_v6_netmask(const char *text, s
147    /* Set unused bits to 0... -A1kmm */
148    if (bits < 128 && (bits % 16 != 0))
149      dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1);
150 <  for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; dp++)
150 >  for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; ++dp)
151      dc[dp] = 0;
152  
153    /* And assign... -A1kmm */
154    if (addr)
155 <    for (dp = 0; dp < 8; dp++)
155 >    for (dp = 0; dp < 8; ++dp)
156        /* The cast is a kludge to make netbsd work. */
157        ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]);
158  
159 <  if (b != NULL)
159 >  if (b)
160      *b = bits;
161    return HM_IPV6;
162   }
165 – #endif
163  
164   /* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
165   * Input: A possible IPV4 address as a string.
# Line 174 | Line 171 | try_parse_v6_netmask(const char *text, s
171   static int
172   try_parse_v4_netmask(const char *text, struct irc_ssaddr *addr, int *b)
173   {
177 –  const char *p;
174    const char *digits[4];
175    unsigned char addb[4];
176    int n = 0, bits = 0;
177    char c;
178 <  struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
178 >  struct sockaddr_in *const v4 = (struct sockaddr_in *)addr;
179  
180    digits[n++] = text;
181  
182 <  for (p = text; (c = *p); p++)
182 >  for (const char *p = text; (c = *p); ++p)
183    {
184      if (c >= '0' && c <= '9')   /* empty */
185        ;
# Line 224 | Line 220 | try_parse_v4_netmask(const char *text, s
220      while (n < 4)
221        digits[n++] = "0";
222  
223 <  for (n = 0; n < 4; n++)
223 >  for (n = 0; n < 4; ++n)
224      addb[n] = strtoul(digits[n], NULL, 10);
225  
226    if (bits == 0)
# Line 233 | Line 229 | try_parse_v4_netmask(const char *text, s
229    /* Set unused bits to 0... -A1kmm */
230    if (bits < 32 && bits % 8)
231      addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1);
232 <  for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; n++)
232 >  for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; ++n)
233      addb[n] = 0;
234    if (addr)
235      v4->sin_addr.s_addr =
236        htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]);
237 <  if (b != NULL)
237 >  if (b)
238      *b = bits;
239    return HM_IPV4;
240   }
# Line 255 | Line 251 | parse_netmask(const char *text, struct i
251   {
252    if (strchr(text, '.'))
253      return try_parse_v4_netmask(text, addr, b);
258 – #ifdef IPV6
254    if (strchr(text, ':'))
255      return try_parse_v6_netmask(text, addr, b);
256 < #endif
256 >
257    return HM_HOST;
258   }
259  
# Line 268 | Line 263 | parse_netmask(const char *text, struct i
263   * Output: if match, -1 else 0
264   * Side effects: None
265   */
271 – #ifdef IPV6
266   int
267   match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
268   {
269    int i, m, n = bits / 8;
270 <  const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
271 <  const struct sockaddr_in6 *v6mask = (const struct sockaddr_in6 *)mask;
270 >  const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
271 >  const struct sockaddr_in6 *const v6mask = (const struct sockaddr_in6 *)mask;
272  
273 <  for (i = 0; i < n; i++)
273 >  for (i = 0; i < n; ++i)
274      if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
275        return 0;
276 +
277    if ((m = bits % 8) == 0)
278      return -1;
279    if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) ==
# Line 286 | Line 281 | match_ipv6(const struct irc_ssaddr *addr
281      return -1;
282    return 0;
283   }
289 – #endif
284  
285   /* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int)
286   * Input: An IP address, an IP mask, the number of bits in the mask.
# Line 296 | Line 290 | match_ipv6(const struct irc_ssaddr *addr
290   int
291   match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
292   {
293 <  const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
294 <  const struct sockaddr_in *v4mask = (const struct sockaddr_in *)mask;
293 >  const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
294 >  const struct sockaddr_in *const v4mask = (const struct sockaddr_in *)mask;
295  
296    if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
297        ntohl(v4mask->sin_addr.s_addr))
# Line 317 | Line 311 | void
311   mask_addr(struct irc_ssaddr *ip, int bits)
312   {
313    int mask;
320 – #ifdef IPV6
314    struct sockaddr_in6 *v6_base_ip;
315    int i, m, n;
323 – #endif
316    struct sockaddr_in *v4_base_ip;
317  
318 < #ifdef IPV6
327 <  if (ip->ss.ss_family != AF_INET6)
328 < #endif
318 >  if (ip->ss.ss_family == AF_INET)
319    {
320 +    uint32_t tmp = 0;
321      v4_base_ip = (struct sockaddr_in *)ip;
322  
323      mask = ~((1 << (32 - bits)) - 1);
324 <    v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
324 >    tmp = ntohl(v4_base_ip->sin_addr.s_addr);
325 >    v4_base_ip->sin_addr.s_addr = htonl(tmp & mask);
326    }
335 – #ifdef IPV6
327    else
328    {
329      n = bits / 8;
330      m = bits % 8;
331      v6_base_ip = (struct sockaddr_in6 *)ip;
332  
333 <    mask = ~((1 << (8 - m)) -1 );
333 >    mask = ~((1 << (8 - m)) - 1);
334      v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask;
335  
336      for (i = n + 1; i < 16; i++)
337        v6_base_ip->sin6_addr.s6_addr[i] = 0;
338    }
348 – #endif
339   }
340  
341 < /* Hashtable stuff...now external as its used in m_stats.c */
341 > /* Hashtable stuff...now external as it's used in m_stats.c */
342   dlink_list atable[ATABLE_SIZE];
343  
354 – void
355 – init_host_hash(void)
356 – {
357 –  memset(&atable, 0, sizeof(atable));
358 – }
359 –
344   /* unsigned long hash_ipv4(struct irc_ssaddr*)
345   * Input: An IP address.
346   * Output: A hash value of the IP address.
# Line 367 | Line 351 | hash_ipv4(const struct irc_ssaddr *addr,
351   {
352    if (bits != 0)
353    {
354 <    const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
354 >    const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
355      uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
356  
357      return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
# Line 381 | Line 365 | hash_ipv4(const struct irc_ssaddr *addr,
365   * Output: A hash value of the IP address.
366   * Side effects: None
367   */
384 – #ifdef IPV6
368   static uint32_t
369   hash_ipv6(const struct irc_ssaddr *addr, int bits)
370   {
371    uint32_t v = 0, n;
372 <  const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
372 >  const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
373  
374 <  for (n = 0; n < 16; n++)
374 >  for (n = 0; n < 16; ++n)
375    {
376      if (bits >= 8)
377      {
# Line 403 | Line 386 | hash_ipv6(const struct irc_ssaddr *addr,
386      else
387        return v & (ATABLE_SIZE - 1);
388    }
389 +
390    return v & (ATABLE_SIZE - 1);
391   }
408 – #endif
392  
393   /* int hash_text(const char *start)
394   * Input: The start of the text to hash.
# Line 415 | Line 398 | hash_ipv6(const struct irc_ssaddr *addr,
398   static uint32_t
399   hash_text(const char *start)
400   {
418 –  const char *p = start;
401    uint32_t h = 0;
402  
403 <  for (; *p; ++p)
403 >  for (const char *p = start; *p; ++p)
404      h = (h << 4) - (h + ToLower(*p));
405  
406    return h & (ATABLE_SIZE - 1);
# Line 435 | Line 417 | get_mask_hash(const char *text)
417   {
418    const char *hp = "", *p;
419  
420 <  for (p = text + strlen(text) - 1; p >= text; p--)
420 >  for (p = text + strlen(text) - 1; p >= text; --p)
421      if (IsMWildChar(*p))
422        return hash_text(hp);
423      else if (*p == '.')
# Line 458 | Line 440 | find_conf_by_address(const char *name, s
440                       int fam, const char *username, const char *password, int do_match)
441   {
442    unsigned int hprecv = 0;
443 <  dlink_node *ptr = NULL;
443 >  dlink_node *node = NULL;
444    struct MaskItem *hprec = NULL;
445    struct AddressRec *arec = NULL;
446    int b;
447    int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp;
448  
467 –  if (username == NULL)
468 –    username = "";
469 –  if (password == NULL)
470 –    password = "";
471 –
449    if (addr)
450    {
451      /* Check for IPV6 matches... */
475 – #ifdef IPV6
452      if (fam == AF_INET6)
453      {
454        for (b = 128; b >= 0; b -= 16)
455        {
456 <        DLINK_FOREACH(ptr, atable[hash_ipv6(addr, b)].head)
456 >        DLINK_FOREACH(node, atable[hash_ipv6(addr, b)].head)
457          {
458 <          arec = ptr->data;
458 >          arec = node->data;
459  
460 <          if (arec->type == (type & ~0x1) &&
460 >          if ((arec->type == type) &&
461                arec->precedence > hprecv &&
462                arec->masktype == HM_IPV6 &&
463                match_ipv6(addr, &arec->Mask.ipa.addr,
464                           arec->Mask.ipa.bits) &&
465 <              (type & 0x1 || !cmpfunc(arec->username, username)) &&
465 >              (!username || !cmpfunc(arec->username, username)) &&
466                (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
467                 match_conf_password(password, arec->conf)))
468            {
# Line 496 | Line 472 | find_conf_by_address(const char *name, s
472          }
473        }
474      }
475 <    else
500 < #endif
501 <    if (fam == AF_INET)
475 >    else if (fam == AF_INET)
476      {
477        for (b = 32; b >= 0; b -= 8)
478        {
479 <        DLINK_FOREACH(ptr, atable[hash_ipv4(addr, b)].head)
479 >        DLINK_FOREACH(node, atable[hash_ipv4(addr, b)].head)
480          {
481 <          arec = ptr->data;
481 >          arec = node->data;
482  
483 <          if (arec->type == (type & ~0x1) &&
483 >          if ((arec->type == type) &&
484                arec->precedence > hprecv &&
485                arec->masktype == HM_IPV4 &&
486                match_ipv4(addr, &arec->Mask.ipa.addr,
487                           arec->Mask.ipa.bits) &&
488 <              (type & 0x1 || !cmpfunc(arec->username, username)) &&
488 >              (!username || !cmpfunc(arec->username, username)) &&
489                (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
490                 match_conf_password(password, arec->conf)))
491            {
# Line 523 | Line 497 | find_conf_by_address(const char *name, s
497      }
498    }
499  
500 <  if (name != NULL)
500 >  if (name)
501    {
502      const char *p = name;
503  
504      while (1)
505      {
506 <        DLINK_FOREACH(ptr, atable[hash_text(p)].head)
506 >        DLINK_FOREACH(node, atable[hash_text(p)].head)
507          {
508 <          arec = ptr->data;
509 <          if ((arec->type == (type & ~0x1)) &&
508 >          arec = node->data;
509 >          if ((arec->type == type) &&
510              arec->precedence > hprecv &&
511              (arec->masktype == HM_HOST) &&
512              !cmpfunc(arec->Mask.hostname, name) &&
513 <            (type & 0x1 || !cmpfunc(arec->username, username)) &&
513 >            (!username || !cmpfunc(arec->username, username)) &&
514              (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
515               match_conf_password(password, arec->conf)))
516          {
# Line 544 | Line 518 | find_conf_by_address(const char *name, s
518            hprec = arec->conf;
519          }
520        }
521 <      p = strchr(p, '.');
522 <      if (p == NULL)
521 >
522 >      if ((p = strchr(p, '.')) == NULL)
523          break;
524 <      p++;
524 >      ++p;
525      }
526  
527 <    DLINK_FOREACH(ptr, atable[0].head)
527 >    DLINK_FOREACH(node, atable[0].head)
528      {
529 <      arec = ptr->data;
529 >      arec = node->data;
530  
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) &&
535 <          (type & 0x1 || !cmpfunc(arec->username, username)) &&
535 >          (!username || !cmpfunc(arec->username, username)) &&
536            (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
537             match_conf_password(password, arec->conf)))
538        {
# Line 578 | Line 552 | find_conf_by_address(const char *name, s
552   * Side-effects: None
553   */
554   struct MaskItem *
555 < find_address_conf(const char *host, const char *user,
556 <                  struct irc_ssaddr *ip, int aftype, char *password)
555 > find_address_conf(const char *host, const char *user, struct irc_ssaddr *ip,
556 >                  int aftype, const char *password)
557   {
558    struct MaskItem *authcnf = NULL, *killcnf = NULL;
559  
# Line 599 | Line 573 | find_address_conf(const char *host, cons
573     * If they are K-lined, return the K-line. Otherwise, return the
574     * auth{} block. -A1kmm
575     */
576 <  if (killcnf != NULL)
576 >  if (killcnf)
577      return killcnf;
578  
579    if (IsConfExemptGline(authcnf))
580      return authcnf;
581  
582    killcnf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
583 <  if (killcnf != NULL)
583 >  if (killcnf)
584      return killcnf;
585  
586    return authcnf;
# Line 623 | Line 597 | find_dline_conf(struct irc_ssaddr *addr,
597   {
598    struct MaskItem *eline;
599  
600 <  eline = find_conf_by_address(NULL, addr, CONF_EXEMPT | 1, aftype,
601 <                               NULL, NULL, 1);
628 <  if (eline != NULL)
600 >  eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, aftype, NULL, NULL, 1);
601 >  if (eline)
602      return eline;
603  
604 <  return find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL, 1);
604 >  return find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1);
605   }
606  
607   /* void add_conf_by_address(int, struct MaskItem *aconf)
# Line 639 | Line 612 | find_dline_conf(struct irc_ssaddr *addr,
612   struct AddressRec *
613   add_conf_by_address(const unsigned int type, struct MaskItem *conf)
614   {
615 <  const char *address;
616 <  const char *username;
615 >  struct AddressRec *arec = NULL;
616 >  const char *const hostname = conf->host;
617 >  const char *const username = conf->user;
618    static unsigned int prec_value = 0xFFFFFFFF;
619    int bits = 0;
646 –  struct AddressRec *arec;
647 –
648 –  address = conf->host;
649 –  username = conf->user;
650 –
651 –  assert(type);
620  
621 <  if (EmptyString(address))
654 <    address = "/NOMATCH!/";
621 >  assert(type && !EmptyString(hostname));
622  
623 <  arec = MyMalloc(sizeof(struct AddressRec));
624 <  arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
623 >  arec = MyCalloc(sizeof(struct AddressRec));
624 >  arec->masktype = parse_netmask(hostname, &arec->Mask.ipa.addr, &bits);
625    arec->Mask.ipa.bits = bits;
626    arec->username = username;
627    arec->conf = conf;
# Line 668 | Line 635 | add_conf_by_address(const unsigned int t
635        bits -= bits % 8;
636        dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]);
637        break;
671 – #ifdef IPV6
638      case HM_IPV6:
639        /* We have to do this, since we do not re-hash for every bit -A1kmm. */
640        bits -= bits % 16;
641        dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]);
642        break;
677 – #endif
643      default: /* HM_HOST */
644 <      arec->Mask.hostname = address;
645 <      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(address)]);
644 >      arec->Mask.hostname = hostname;
645 >      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(hostname)]);
646        break;
647    }
648  
# Line 695 | Line 660 | delete_one_address_conf(const char *addr
660   {
661    int bits = 0;
662    uint32_t hv = 0;
663 <  dlink_node *ptr = NULL, *ptr_next = NULL;
663 >  dlink_node *node = NULL;
664    struct irc_ssaddr addr;
665  
666    switch (parse_netmask(address, &addr, &bits))
# Line 705 | Line 670 | delete_one_address_conf(const char *addr
670        bits -= bits % 8;
671        hv = hash_ipv4(&addr, bits);
672        break;
708 – #ifdef IPV6
673      case HM_IPV6:
674        /* We have to do this, since we do not re-hash for every bit -A1kmm. */
675        bits -= bits % 16;
676        hv = hash_ipv6(&addr, bits);
677        break;
714 – #endif
678      default: /* HM_HOST */
679        hv = get_mask_hash(address);
680        break;
681    }
682  
683 <  DLINK_FOREACH_SAFE(ptr, ptr_next, atable[hv].head)
683 >  DLINK_FOREACH(node, atable[hv].head)
684    {
685 <    struct AddressRec *arec = ptr->data;
685 >    struct AddressRec *arec = node->data;
686  
687      if (arec->conf == conf)
688      {
# Line 744 | Line 707 | delete_one_address_conf(const char *addr
707   void
708   clear_out_address_conf(void)
709   {
710 <  unsigned int i = 0;
748 <  dlink_node *ptr = NULL, *ptr_next = NULL;
710 >  dlink_node *node = NULL, *node_next = NULL;
711  
712 <  for (i = 0; i < ATABLE_SIZE; ++i)
712 >  for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
713    {
714 <    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
714 >    DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
715      {
716 <      struct AddressRec *arec = ptr->data;
716 >      struct AddressRec *arec = node->data;
717  
718        /*
719         * We keep the temporary K-lines and destroy the permanent ones,
# Line 761 | Line 723 | clear_out_address_conf(void)
723          continue;
724  
725        dlinkDelete(&arec->node, &atable[i]);
726 +      arec->conf->active = 0;
727  
728        if (!arec->conf->ref_count)
729          conf_free(arec->conf);
# Line 770 | Line 733 | clear_out_address_conf(void)
733   }
734  
735   static void
736 < hostmask_send_expiration(struct AddressRec *arec)
736 > hostmask_send_expiration(const struct AddressRec *const arec)
737   {
738    char ban_type = '\0';
739  
740 <  if (!ConfigFileEntry.tkline_expire_notices)
740 >  if (!ConfigGeneral.tkline_expire_notices)
741      return;
742  
743    switch (arec->type)
# Line 800 | Line 763 | hostmask_send_expiration(struct AddressR
763   void
764   hostmask_expire_temporary(void)
765   {
766 <  unsigned int i = 0;
804 <  dlink_node *ptr = NULL, *ptr_next = NULL;
766 >  dlink_node *node = NULL, *node_next = NULL;
767  
768 <  for (i = 0; i < ATABLE_SIZE; ++i)
768 >  for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
769    {
770 <    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
770 >    DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
771      {
772 <      struct AddressRec *arec = ptr->data;
772 >      struct AddressRec *arec = node->data;
773  
774        if (!arec->conf->until || arec->conf->until > CurrentTime)
775          continue;

Diff Legend

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