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 4298 by michael, Sun Jul 20 13:51:16 2014 UTC vs.
Revision 6409 by michael, Tue Aug 25 19:56:57 2015 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-2015 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 44 | Line 44
44                           ch = ch - 'a' + 10; \
45                         } while (0);
46  
47 + /* Hashtable stuff...now external as it's used in m_stats.c */
48 + dlink_list atable[ATABLE_SIZE];
49 +
50   /* The mask parser/type determination code... */
51  
52   /* int try_parse_v6_netmask(const char *, struct irc_ssaddr *, int *);
# Line 57 | Line 60
60     Also a bug in DigitParse above.
61     -Gozem 2002-07-19 gozem@linux.nu
62   */
60 – #ifdef IPV6
63   static int
64   try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
65   {
# Line 69 | Line 71 | try_parse_v6_netmask(const char *text, s
71    int bits = 128;
72    int deficit = 0;
73    short dc[8];
74 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
74 >  struct sockaddr_in6 *const v6 = (struct sockaddr_in6 *)addr;
75  
76    for (const char *p = text; (c = *p); ++p)
77    {
# Line 161 | Line 163 | try_parse_v6_netmask(const char *text, s
163      *b = bits;
164    return HM_IPV6;
165   }
164 – #endif
166  
167   /* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
168   * Input: A possible IPV4 address as a string.
# Line 177 | Line 178 | try_parse_v4_netmask(const char *text, s
178    unsigned char addb[4];
179    int n = 0, bits = 0;
180    char c;
181 <  struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
181 >  struct sockaddr_in *const v4 = (struct sockaddr_in *)addr;
182  
183    digits[n++] = text;
184  
# Line 194 | Line 195 | try_parse_v4_netmask(const char *text, s
195      }
196      else if (c == '*')
197      {
198 <      if (*(p + 1) || n == 0 || *(p - 1) != '.')
198 >      if (*(p + 1) || n == 1 || *(p - 1) != '.')
199          return HM_HOST;
200  
201        bits = (n - 1) * 8;
# Line 253 | Line 254 | parse_netmask(const char *text, struct i
254   {
255    if (strchr(text, '.'))
256      return try_parse_v4_netmask(text, addr, b);
256 – #ifdef IPV6
257    if (strchr(text, ':'))
258      return try_parse_v6_netmask(text, addr, b);
259 < #endif
259 >
260    return HM_HOST;
261   }
262  
# Line 266 | Line 266 | parse_netmask(const char *text, struct i
266   * Output: if match, -1 else 0
267   * Side effects: None
268   */
269 – #ifdef IPV6
269   int
270   match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
271   {
272    int i, m, n = bits / 8;
273 <  const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
274 <  const struct sockaddr_in6 *v6mask = (const struct sockaddr_in6 *)mask;
273 >  const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
274 >  const struct sockaddr_in6 *const v6mask = (const struct sockaddr_in6 *)mask;
275  
276    for (i = 0; i < n; ++i)
277      if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
# Line 285 | Line 284 | match_ipv6(const struct irc_ssaddr *addr
284      return -1;
285    return 0;
286   }
288 – #endif
287  
288   /* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int)
289   * Input: An IP address, an IP mask, the number of bits in the mask.
# Line 295 | Line 293 | match_ipv6(const struct irc_ssaddr *addr
293   int
294   match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
295   {
296 <  const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
297 <  const struct sockaddr_in *v4mask = (const struct sockaddr_in *)mask;
296 >  const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
297 >  const struct sockaddr_in *const v4mask = (const struct sockaddr_in *)mask;
298  
299    if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
300        ntohl(v4mask->sin_addr.s_addr))
# Line 316 | Line 314 | void
314   mask_addr(struct irc_ssaddr *ip, int bits)
315   {
316    int mask;
319 – #ifdef IPV6
317    struct sockaddr_in6 *v6_base_ip;
318    int i, m, n;
322 – #endif
319    struct sockaddr_in *v4_base_ip;
320  
321 < #ifdef IPV6
326 <  if (ip->ss.ss_family != AF_INET6)
327 < #endif
321 >  if (ip->ss.ss_family == AF_INET)
322    {
323      uint32_t tmp = 0;
324      v4_base_ip = (struct sockaddr_in *)ip;
# Line 333 | Line 327 | mask_addr(struct irc_ssaddr *ip, int bit
327      tmp = ntohl(v4_base_ip->sin_addr.s_addr);
328      v4_base_ip->sin_addr.s_addr = htonl(tmp & mask);
329    }
336 – #ifdef IPV6
330    else
331    {
332      n = bits / 8;
333      m = bits % 8;
334      v6_base_ip = (struct sockaddr_in6 *)ip;
335  
336 <    mask = ~((1 << (8 - m)) -1 );
336 >    mask = ~((1 << (8 - m)) - 1);
337      v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask;
338  
339      for (i = n + 1; i < 16; i++)
340        v6_base_ip->sin6_addr.s6_addr[i] = 0;
341    }
349 – #endif
350 – }
351 –
352 – /* Hashtable stuff...now external as it's used in m_stats.c */
353 – dlink_list atable[ATABLE_SIZE];
354 –
355 – void
356 – init_host_hash(void)
357 – {
358 –  memset(&atable, 0, sizeof(atable));
342   }
343  
344   /* unsigned long hash_ipv4(struct irc_ssaddr*)
# Line 368 | 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 382 | Line 365 | hash_ipv4(const struct irc_ssaddr *addr,
365   * Output: A hash value of the IP address.
366   * Side effects: None
367   */
385 – #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)
375    {
# Line 404 | 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   }
409 – #endif
392  
393   /* int hash_text(const char *start)
394   * Input: The start of the text to hash.
# Line 454 | Line 436 | get_mask_hash(const char *text)
436   * should always be true (i.e. conf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
437   */
438   struct MaskItem *
439 < find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type,
439 > find_conf_by_address(const char *name, const struct irc_ssaddr *addr, unsigned int type,
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;
# Line 467 | Line 449 | find_conf_by_address(const char *name, s
449    if (addr)
450    {
451      /* Check for IPV6 matches... */
470 – #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) &&
461                arec->precedence > hprecv &&
# Line 491 | Line 472 | find_conf_by_address(const char *name, s
472          }
473        }
474      }
475 <    else
495 < #endif
496 <    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) &&
484                arec->precedence > hprecv &&
# Line 524 | Line 503 | find_conf_by_address(const char *name, s
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;
508 >          arec = node->data;
509            if ((arec->type == type) &&
510              arec->precedence > hprecv &&
511              (arec->masktype == HM_HOST) &&
# Line 545 | Line 524 | find_conf_by_address(const char *name, s
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 &&
532            arec->precedence > hprecv &&
# Line 592 | Line 571 | find_address_conf(const char *host, cons
571  
572    /*
573     * If they are K-lined, return the K-line. Otherwise, return the
574 <   * auth{} block. -A1kmm
574 >   * auth {} block. -A1kmm
575     */
576 <  if (killcnf)
598 <    return killcnf;
599 <
600 <  if (IsConfExemptGline(authcnf))
601 <    return authcnf;
602 <
603 <  killcnf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
604 <  if (killcnf)
576 >  if (killcnf && (killcnf->until == 0 || killcnf->until > CurrentTime))
577      return killcnf;
578  
579    return authcnf;
# Line 617 | Line 589 | struct MaskItem *
589   find_dline_conf(struct irc_ssaddr *addr, int aftype)
590   {
591    struct MaskItem *eline;
592 +  struct MaskItem *dline;
593  
594    eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, aftype, NULL, NULL, 1);
595    if (eline)
596      return eline;
597  
598 <  return find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1);
598 >  dline = find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1);
599 >  if (dline && (dline->until == 0 || dline->until > CurrentTime))
600 >    return dline;
601 >
602 >  return NULL;
603   }
604  
605   /* void add_conf_by_address(int, struct MaskItem *aconf)
# Line 633 | Line 610 | find_dline_conf(struct irc_ssaddr *addr,
610   struct AddressRec *
611   add_conf_by_address(const unsigned int type, struct MaskItem *conf)
612   {
613 <  const char *hostname = conf->host;
614 <  const char *username = conf->user;
613 >  struct AddressRec *arec = NULL;
614 >  const char *const hostname = conf->host;
615 >  const char *const username = conf->user;
616    static unsigned int prec_value = 0xFFFFFFFF;
617    int bits = 0;
640 –  struct AddressRec *arec = NULL;
618  
619    assert(type && !EmptyString(hostname));
620  
# Line 656 | Line 633 | add_conf_by_address(const unsigned int t
633        bits -= bits % 8;
634        dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]);
635        break;
659 – #ifdef IPV6
636      case HM_IPV6:
637        /* We have to do this, since we do not re-hash for every bit -A1kmm. */
638        bits -= bits % 16;
639        dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]);
640        break;
665 – #endif
641      default: /* HM_HOST */
642        arec->Mask.hostname = hostname;
643        dlinkAdd(arec, &arec->node, &atable[get_mask_hash(hostname)]);
# Line 683 | Line 658 | delete_one_address_conf(const char *addr
658   {
659    int bits = 0;
660    uint32_t hv = 0;
661 <  dlink_node *ptr = NULL;
661 >  dlink_node *node = NULL;
662    struct irc_ssaddr addr;
663  
664    switch (parse_netmask(address, &addr, &bits))
# Line 693 | Line 668 | delete_one_address_conf(const char *addr
668        bits -= bits % 8;
669        hv = hash_ipv4(&addr, bits);
670        break;
696 – #ifdef IPV6
671      case HM_IPV6:
672        /* We have to do this, since we do not re-hash for every bit -A1kmm. */
673        bits -= bits % 16;
674        hv = hash_ipv6(&addr, bits);
675        break;
702 – #endif
676      default: /* HM_HOST */
677        hv = get_mask_hash(address);
678        break;
679    }
680  
681 <  DLINK_FOREACH(ptr, atable[hv].head)
681 >  DLINK_FOREACH(node, atable[hv].head)
682    {
683 <    struct AddressRec *arec = ptr->data;
683 >    struct AddressRec *arec = node->data;
684  
685      if (arec->conf == conf)
686      {
# Line 732 | Line 705 | delete_one_address_conf(const char *addr
705   void
706   clear_out_address_conf(void)
707   {
708 <  dlink_node *ptr = NULL, *ptr_next = NULL;
708 >  dlink_node *node = NULL, *node_next = NULL;
709  
710    for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
711    {
712 <    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
712 >    DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
713      {
714 <      struct AddressRec *arec = ptr->data;
714 >      struct AddressRec *arec = node->data;
715  
716        /*
717 <       * We keep the temporary K-lines and destroy the permanent ones,
745 <       * just to be confusing :) -A1kmm
717 >       * Destroy the ircd.conf items and keep those that are in the databases
718         */
719 <      if (arec->conf->until || IsConfDatabase(arec->conf))
719 >      if (IsConfDatabase(arec->conf))
720          continue;
721  
722        dlinkDelete(&arec->node, &atable[i]);
723 +      arec->conf->active = 0;
724  
725        if (!arec->conf->ref_count)
726          conf_free(arec->conf);
# Line 757 | Line 730 | clear_out_address_conf(void)
730   }
731  
732   static void
733 < hostmask_send_expiration(struct AddressRec *arec)
733 > hostmask_send_expiration(const struct AddressRec *const arec)
734   {
735    char ban_type = '\0';
736  
737 <  if (!ConfigFileEntry.tkline_expire_notices)
737 >  if (!ConfigGeneral.tkline_expire_notices)
738      return;
739  
740    switch (arec->type)
# Line 772 | Line 745 | hostmask_send_expiration(struct AddressR
745      case CONF_DLINE:
746        ban_type = 'D';
747        break;
775 –    case CONF_GLINE:
776 –      ban_type = 'G';
777 –      break;
748      default: break;
749    }
750  
751 <  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
751 >  sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
752                         "Temporary %c-line for [%s@%s] expired", ban_type,
753                         (arec->conf->user) ? arec->conf->user : "*",
754                         (arec->conf->host) ? arec->conf->host : "*");
# Line 787 | Line 757 | hostmask_send_expiration(struct AddressR
757   void
758   hostmask_expire_temporary(void)
759   {
760 <  dlink_node *ptr = NULL, *ptr_next = NULL;
760 >  dlink_node *node = NULL, *node_next = NULL;
761  
762    for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
763    {
764 <    DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
764 >    DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
765      {
766 <      struct AddressRec *arec = ptr->data;
766 >      struct AddressRec *arec = node->data;
767  
768        if (!arec->conf->until || arec->conf->until > CurrentTime)
769          continue;
# Line 802 | Line 772 | hostmask_expire_temporary(void)
772        {
773          case CONF_KLINE:
774          case CONF_DLINE:
805 –        case CONF_GLINE:
775            hostmask_send_expiration(arec);
776  
777            dlinkDelete(&arec->node, &atable[i]);

Diff Legend

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