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 3469 by michael, Sat May 3 17:55:53 2014 UTC vs.
Revision 8963 by michael, Sat May 11 21:06:49 2019 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 2001-2014 ircd-hybrid development team
4 > *  Copyright (c) 2001-2019 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 15 | Line 15
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18 < *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20   */
21  
# Line 42 | Line 42
42                           ch = ch - 'A' + 10; \
43                         else if (ch >= 'a' && ch <= 'f') \
44                           ch = ch - 'a' + 10; \
45 <                       } while (0);
45 >                       } while (false);
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  
# Line 53 | Line 56
56   * Side effects: None
57   * Comments: Called from parse_netmask
58   */
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 */
60 #ifdef IPV6
59   static int
60   try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
61   {
# Line 69 | 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 (const char *p = text; (c = *p); ++p)
73    {
# Line 90 | 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 153 | Line 154 | try_parse_v6_netmask(const char *text, s
154  
155    /* And assign... -A1kmm */
156    if (addr)
157 +  {
158 +    v6->sin6_family = AF_INET6;
159 +
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  
165    if (b)
166      *b = bits;
167    return HM_IPV6;
168   }
164 #endif
169  
170   /* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
171   * Input: A possible IPV4 address as a string.
# Line 177 | Line 181 | try_parse_v4_netmask(const char *text, s
181    unsigned char addb[4];
182    int n = 0, bits = 0;
183    char c;
184 <  struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
184 >  struct sockaddr_in *const v4 = (struct sockaddr_in *)addr;
185  
186    digits[n++] = text;
187  
# Line 194 | Line 198 | try_parse_v4_netmask(const char *text, s
198      }
199      else if (c == '*')
200      {
201 <      if (*(p + 1) || n == 0 || *(p - 1) != '.')
201 >      if (*(p + 1) || n == 1 || *(p - 1) != '.')
202          return HM_HOST;
203  
204        bits = (n - 1) * 8;
# Line 234 | Line 238 | try_parse_v4_netmask(const char *text, s
238    for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; ++n)
239      addb[n] = 0;
240    if (addr)
241 +  {
242 +    v4->sin_family = AF_INET;
243      v4->sin_addr.s_addr =
244        htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]);
245 +  }
246 +
247    if (b)
248      *b = bits;
249    return HM_IPV4;
# Line 251 | Line 259 | try_parse_v4_netmask(const char *text, s
259   int
260   parse_netmask(const char *text, struct irc_ssaddr *addr, int *b)
261   {
262 +  if (addr)
263 +    memset(addr, 0, sizeof(*addr));
264 +
265    if (strchr(text, '.'))
266      return try_parse_v4_netmask(text, addr, b);
256 #ifdef IPV6
267    if (strchr(text, ':'))
268      return try_parse_v6_netmask(text, addr, b);
269 < #endif
269 >
270    return HM_HOST;
271   }
272  
# Line 266 | Line 276 | parse_netmask(const char *text, struct i
276   * Output: if match, -1 else 0
277   * Side effects: None
278   */
279 < #ifdef IPV6
270 < int
279 > bool
280   match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
281   {
282    int i, m, n = bits / 8;
283 <  const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
284 <  const struct sockaddr_in6 *v6mask = (const struct sockaddr_in6 *)mask;
283 >  const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
284 >  const struct sockaddr_in6 *const v6mask = (const struct sockaddr_in6 *)mask;
285  
286    for (i = 0; i < n; ++i)
287      if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
288 <      return 0;
288 >      return false;
289  
290    if ((m = bits % 8) == 0)
291 <    return -1;
291 >    return true;
292    if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) ==
293        v6mask->sin6_addr.s6_addr[n])
294 <    return -1;
295 <  return 0;
294 >    return true;
295 >  return false;
296   }
288 #endif
297  
298   /* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int)
299   * Input: An IP address, an IP mask, the number of bits in the mask.
300   * Output: if match, -1 else 0
301   * Side Effects: None
302   */
303 < int
303 > bool
304   match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
305   {
306 <  const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
307 <  const struct sockaddr_in *v4mask = (const struct sockaddr_in *)mask;
306 >  const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
307 >  const struct sockaddr_in *const v4mask = (const struct sockaddr_in *)mask;
308  
309 <  if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
309 >  if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) ==
310        ntohl(v4mask->sin_addr.s_addr))
311 <    return 0;
312 <  return -1;
305 < }
306 <
307 < /*
308 < * mask_addr
309 < *
310 < * inputs       - pointer to the ip to mask
311 < *              - bitlen
312 < * output       - NONE
313 < * side effects -
314 < */
315 < void
316 < mask_addr(struct irc_ssaddr *ip, int bits)
317 < {
318 <  int mask;
319 < #ifdef IPV6
320 <  struct sockaddr_in6 *v6_base_ip;
321 <  int i, m, n;
322 < #endif
323 <  struct sockaddr_in *v4_base_ip;
324 <
325 < #ifdef IPV6
326 <  if (ip->ss.ss_family != AF_INET6)
327 < #endif
328 <  {
329 <    v4_base_ip = (struct sockaddr_in *)ip;
330 <
331 <    mask = ~((1 << (32 - bits)) - 1);
332 <    v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
333 <  }
334 < #ifdef IPV6
335 <  else
336 <  {
337 <    n = bits / 8;
338 <    m = bits % 8;
339 <    v6_base_ip = (struct sockaddr_in6 *)ip;
340 <
341 <    mask = ~((1 << (8 - m)) -1 );
342 <    v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask;
343 <
344 <    for (i = n + 1; i < 16; i++)
345 <      v6_base_ip->sin6_addr.s6_addr[i] = 0;
346 <  }
347 < #endif
348 < }
349 <
350 < /* Hashtable stuff...now external as its used in m_stats.c */
351 < dlink_list atable[ATABLE_SIZE];
352 <
353 < void
354 < init_host_hash(void)
355 < {
356 <  memset(&atable, 0, sizeof(atable));
311 >    return true;
312 >  return false;
313   }
314  
315   /* unsigned long hash_ipv4(struct irc_ssaddr*)
# Line 364 | Line 320 | init_host_hash(void)
320   static uint32_t
321   hash_ipv4(const struct irc_ssaddr *addr, int bits)
322   {
323 <  if (bits != 0)
323 >  if (bits)
324    {
325 <    const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
325 >    const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
326      uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
327  
328      return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
# Line 380 | Line 336 | hash_ipv4(const struct irc_ssaddr *addr,
336   * Output: A hash value of the IP address.
337   * Side effects: None
338   */
383 #ifdef IPV6
339   static uint32_t
340   hash_ipv6(const struct irc_ssaddr *addr, int bits)
341   {
342    uint32_t v = 0, n;
343 <  const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
343 >  const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
344  
345    for (n = 0; n < 16; ++n)
346    {
# Line 402 | Line 357 | hash_ipv6(const struct irc_ssaddr *addr,
357      else
358        return v & (ATABLE_SIZE - 1);
359    }
360 +
361    return v & (ATABLE_SIZE - 1);
362   }
407 #endif
363  
364   /* int hash_text(const char *start)
365   * Input: The start of the text to hash.
# Line 452 | Line 407 | get_mask_hash(const char *text)
407   * should always be true (i.e. conf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
408   */
409   struct MaskItem *
410 < find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type,
411 <                     int fam, const char *username, const char *password, int do_match)
410 > find_conf_by_address(const char *name, const struct irc_ssaddr *addr, unsigned int type,
411 >                     const char *username, const char *password, int do_match)
412   {
413    unsigned int hprecv = 0;
414 <  dlink_node *ptr = NULL;
414 >  dlink_node *node;
415    struct MaskItem *hprec = NULL;
416    struct AddressRec *arec = NULL;
462  int b;
417    int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp;
418  
419    if (addr)
420    {
421      /* Check for IPV6 matches... */
422 < #ifdef IPV6
469 <    if (fam == AF_INET6)
422 >    if (addr->ss.ss_family == AF_INET6)
423      {
424 <      for (b = 128; b >= 0; b -= 16)
424 >      for (int b = 128; b >= 0; b -= 16)
425        {
426 <        DLINK_FOREACH(ptr, atable[hash_ipv6(addr, b)].head)
426 >        DLINK_FOREACH(node, atable[hash_ipv6(addr, b)].head)
427          {
428 <          arec = ptr->data;
428 >          arec = node->data;
429  
430            if ((arec->type == type) &&
431                arec->precedence > hprecv &&
# Line 489 | Line 442 | find_conf_by_address(const char *name, s
442          }
443        }
444      }
445 <    else
493 < #endif
494 <    if (fam == AF_INET)
445 >    else if (addr->ss.ss_family == AF_INET)
446      {
447 <      for (b = 32; b >= 0; b -= 8)
447 >      for (int b = 32; b >= 0; b -= 8)
448        {
449 <        DLINK_FOREACH(ptr, atable[hash_ipv4(addr, b)].head)
449 >        DLINK_FOREACH(node, atable[hash_ipv4(addr, b)].head)
450          {
451 <          arec = ptr->data;
451 >          arec = node->data;
452  
453            if ((arec->type == type) &&
454                arec->precedence > hprecv &&
# Line 520 | Line 471 | find_conf_by_address(const char *name, s
471    {
472      const char *p = name;
473  
474 <    while (1)
474 >    while (true)
475      {
476 <        DLINK_FOREACH(ptr, atable[hash_text(p)].head)
476 >        DLINK_FOREACH(node, atable[hash_text(p)].head)
477          {
478 <          arec = ptr->data;
478 >          arec = node->data;
479            if ((arec->type == type) &&
480              arec->precedence > hprecv &&
481              (arec->masktype == HM_HOST) &&
# Line 543 | Line 494 | find_conf_by_address(const char *name, s
494        ++p;
495      }
496  
497 <    DLINK_FOREACH(ptr, atable[0].head)
497 >    DLINK_FOREACH(node, atable[0].head)
498      {
499 <      arec = ptr->data;
499 >      arec = node->data;
500  
501        if (arec->type == type &&
502            arec->precedence > hprecv &&
# Line 571 | Line 522 | find_conf_by_address(const char *name, s
522   * Side-effects: None
523   */
524   struct MaskItem *
525 < find_address_conf(const char *host, const char *user,
575 <                  struct irc_ssaddr *ip, int aftype, char *password)
525 > find_address_conf(const char *host, const char *user, const struct irc_ssaddr *addr, const char *password)
526   {
527    struct MaskItem *authcnf = NULL, *killcnf = NULL;
528  
529    /* Find the best auth{} block... If none, return NULL -A1kmm */
530 <  if ((authcnf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
581 <                                      password, 1)) == NULL)
530 >  if ((authcnf = find_conf_by_address(host, addr, CONF_CLIENT, user, password, 1)) == NULL)
531      return NULL;
532  
533    /* If they are exempt from K-lines, return the best auth{} block. -A1kmm */
# Line 586 | Line 535 | find_address_conf(const char *host, cons
535      return authcnf;
536  
537    /* Find the best K-line... -A1kmm */
538 <  killcnf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
538 >  killcnf = find_conf_by_address(host, addr, CONF_KLINE, user, NULL, 1);
539  
540    /*
541     * If they are K-lined, return the K-line. Otherwise, return the
542 <   * auth{} block. -A1kmm
542 >   * auth {} block. -A1kmm
543     */
544    if (killcnf)
545      return killcnf;
546  
598  if (IsConfExemptGline(authcnf))
599    return authcnf;
600
601  killcnf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
602  if (killcnf)
603    return killcnf;
604
547    return authcnf;
548   }
549  
# Line 612 | Line 554 | find_address_conf(const char *host, cons
554   * Side effects: None.
555   */
556   struct MaskItem *
557 < find_dline_conf(struct irc_ssaddr *addr, int aftype)
557 > find_dline_conf(const struct irc_ssaddr *addr)
558   {
559    struct MaskItem *eline;
560  
561 <  eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, aftype, NULL, NULL, 1);
561 >  eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, NULL, NULL, 1);
562    if (eline)
563      return eline;
564  
565 <  return find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1);
565 >  return find_conf_by_address(NULL, addr, CONF_DLINE, NULL, NULL, 1);
566   }
567  
568   /* void add_conf_by_address(int, struct MaskItem *aconf)
# Line 631 | Line 573 | find_dline_conf(struct irc_ssaddr *addr,
573   struct AddressRec *
574   add_conf_by_address(const unsigned int type, struct MaskItem *conf)
575   {
576 <  const char *hostname = conf->host;
577 <  const char *username = conf->user;
578 <  static unsigned int prec_value = 0xFFFFFFFF;
576 >  const char *const hostname = conf->host;
577 >  const char *const username = conf->user;
578 >  static unsigned int prec_value = UINT_MAX;
579    int bits = 0;
638  struct AddressRec *arec = NULL;
580  
581    assert(type && !EmptyString(hostname));
582  
583 <  arec = MyMalloc(sizeof(struct AddressRec));
583 >  struct AddressRec *arec = xcalloc(sizeof(*arec));
584    arec->masktype = parse_netmask(hostname, &arec->Mask.ipa.addr, &bits);
585    arec->Mask.ipa.bits = bits;
586    arec->username = username;
# Line 654 | Line 595 | add_conf_by_address(const unsigned int t
595        bits -= bits % 8;
596        dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]);
597        break;
657 #ifdef IPV6
598      case HM_IPV6:
599        /* We have to do this, since we do not re-hash for every bit -A1kmm. */
600        bits -= bits % 16;
601        dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]);
602        break;
663 #endif
603      default: /* HM_HOST */
604        arec->Mask.hostname = hostname;
605        dlinkAdd(arec, &arec->node, &atable[get_mask_hash(hostname)]);
# Line 681 | Line 620 | delete_one_address_conf(const char *addr
620   {
621    int bits = 0;
622    uint32_t hv = 0;
623 <  dlink_node *ptr = NULL, *ptr_next = NULL;
623 >  dlink_node *node;
624    struct irc_ssaddr addr;
625  
626    switch (parse_netmask(address, &addr, &bits))
# Line 691 | Line 630 | delete_one_address_conf(const char *addr
630        bits -= bits % 8;
631        hv = hash_ipv4(&addr, bits);
632        break;
694 #ifdef IPV6
633      case HM_IPV6:
634        /* We have to do this, since we do not re-hash for every bit -A1kmm. */
635        bits -= bits % 16;
636        hv = hash_ipv6(&addr, bits);
637        break;
700 #endif
638      default: /* HM_HOST */
639        hv = get_mask_hash(address);
640        break;
641    }
642  
643 <  DLINK_FOREACH_SAFE(ptr, ptr_next, atable[hv].head)
643 >  DLINK_FOREACH(node, atable[hv].head)
644    {
645 <    struct AddressRec *arec = ptr->data;
645 >    struct AddressRec *arec = node->data;
646  
647      if (arec->conf == conf)
648      {
649        dlinkDelete(&arec->node, &atable[hv]);
650  
651 <      if (!conf->ref_count)
651 >      if (conf->ref_count == 0)
652          conf_free(conf);
653  
654 <      MyFree(arec);
654 >      xfree(arec);
655        return;
656      }
657    }
# Line 730 | Line 667 | delete_one_address_conf(const char *addr
667   void
668   clear_out_address_conf(void)
669   {
670 <  dlink_node *ptr = NULL, *ptr_next = NULL;
670 >  dlink_node *node, *node_next;
671  
672    for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
673    {
674 <    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
674 >    DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
675      {
676 <      struct AddressRec *arec = ptr->data;
676 >      struct AddressRec *arec = node->data;
677  
678        /*
679 <       * We keep the temporary K-lines and destroy the permanent ones,
743 <       * just to be confusing :) -A1kmm
679 >       * Destroy the ircd.conf items and keep those that are in the databases
680         */
681 <      if (arec->conf->until || IsConfDatabase(arec->conf))
681 >      if (IsConfDatabase(arec->conf))
682          continue;
683  
684        dlinkDelete(&arec->node, &atable[i]);
685 +      arec->conf->active = false;
686  
687 <      if (!arec->conf->ref_count)
687 >      if (arec->conf->ref_count == 0)
688          conf_free(arec->conf);
689 <      MyFree(arec);
689 >      xfree(arec);
690      }
691    }
692   }
693  
694   static void
695 < hostmask_send_expiration(struct AddressRec *arec)
695 > hostmask_send_expiration(const struct AddressRec *const arec)
696   {
697 <  char ban_type = '\0';
761 <
762 <  if (!ConfigFileEntry.tkline_expire_notices)
763 <    return;
697 >  char ban_type = '?';
698  
699    switch (arec->type)
700    {
# Line 770 | Line 704 | hostmask_send_expiration(struct AddressR
704      case CONF_DLINE:
705        ban_type = 'D';
706        break;
773    case CONF_GLINE:
774      ban_type = 'G';
775      break;
707      default: break;
708    }
709  
710 <  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
710 >  sendto_realops_flags(UMODE_EXPIRATION, L_ALL, SEND_NOTICE,
711                         "Temporary %c-line for [%s@%s] expired", ban_type,
712                         (arec->conf->user) ? arec->conf->user : "*",
713                         (arec->conf->host) ? arec->conf->host : "*");
# Line 785 | Line 716 | hostmask_send_expiration(struct AddressR
716   void
717   hostmask_expire_temporary(void)
718   {
719 <  dlink_node *ptr = NULL, *ptr_next = NULL;
719 >  dlink_node *node, *node_next;
720  
721    for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
722    {
723 <    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
723 >    DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
724      {
725 <      struct AddressRec *arec = ptr->data;
725 >      struct AddressRec *arec = node->data;
726  
727 <      if (!arec->conf->until || arec->conf->until > CurrentTime)
727 >      if (arec->conf->until == 0 || arec->conf->until > event_base->time.sec_real)
728          continue;
729  
730        switch (arec->type)
731        {
732          case CONF_KLINE:
733          case CONF_DLINE:
803        case CONF_GLINE:
734            hostmask_send_expiration(arec);
735  
736            dlinkDelete(&arec->node, &atable[i]);
737            conf_free(arec->conf);
738 <          MyFree(arec);
738 >          xfree(arec);
739            break;
740          default: break;
741        }

Comparing ircd-hybrid/trunk/src/hostmask.c (property svn:keywords):
Revision 3469 by michael, Sat May 3 17:55:53 2014 UTC vs.
Revision 8963 by michael, Sat May 11 21:06:49 2019 UTC

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

Diff Legend

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