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 1628 by michael, Thu Nov 1 21:08:56 2012 UTC vs.
Revision 6409 by michael, Tue Aug 25 19:56:57 2015 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-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 16 | 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 < *  $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 42 | 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 51 | Line 56
56   * Side effects: None
57   * Comments: Called from parse_netmask
58   */
59 < /* Fixed so ::/0 (any IPv6 address) is valid
59 > /* Fixed so ::/0 (any IPv6 address) is valid
60     Also a bug in DigitParse above.
61     -Gozem 2002-07-19 gozem@linux.nu
62   */
58 – #ifdef IPV6
63   static int
64   try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
65   {
62 –  const char *p;
66    char c;
67    int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
68    int dp = 0;
# Line 68 | 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 (p = text; (c = *p); p++)
76 >  for (const char *p = text; (c = *p); ++p)
77 >  {
78      if (IsXDigit(c))
79      {
80        if (nyble == 0)
# Line 108 | Line 112 | try_parse_v6_netmask(const char *text, s
112        char *after;
113  
114        d[dp] = d[dp] >> 4 * nyble;
115 <      dp++;
115 >      ++dp;
116        bits = strtoul(p + 1, &after, 10);
117  
118        if (bits < 0 || *after)
# Line 119 | Line 123 | try_parse_v6_netmask(const char *text, s
123      }
124      else
125        return HM_HOST;
126 +  }
127  
128    d[dp] = d[dp] >> 4 * nyble;
129  
130    if (c == 0)
131 <    dp++;
131 >    ++dp;
132    if (finsert < 0 && bits == 0)
133      bits = dp * 16;
134  
# Line 131 | Line 136 | try_parse_v6_netmask(const char *text, s
136    deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp;
137  
138    /* Now fill in the gaps(from ::) in the copied table... -A1kmm */
139 <  for (dp = 0, nyble = 0; dp < 8; dp++)
139 >  for (dp = 0, nyble = 0; dp < 8; ++dp)
140    {
141      if (nyble == finsert && deficit)
142      {
# Line 145 | Line 150 | try_parse_v6_netmask(const char *text, s
150    /* Set unused bits to 0... -A1kmm */
151    if (bits < 128 && (bits % 16 != 0))
152      dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1);
153 <  for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; dp++)
153 >  for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; ++dp)
154      dc[dp] = 0;
155  
156    /* And assign... -A1kmm */
157    if (addr)
158 <    for (dp = 0; dp < 8; dp++)
158 >    for (dp = 0; dp < 8; ++dp)
159        /* The cast is a kludge to make netbsd work. */
160        ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]);
161  
162 <  if (b != NULL)
162 >  if (b)
163      *b = bits;
164    return HM_IPV6;
165   }
161 – #endif
166  
167   /* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
168   * Input: A possible IPV4 address as a string.
# Line 170 | Line 174 | try_parse_v6_netmask(const char *text, s
174   static int
175   try_parse_v4_netmask(const char *text, struct irc_ssaddr *addr, int *b)
176   {
173 –  const char *p;
177    const char *digits[4];
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  
185 <  for (p = text; (c = *p); p++)
185 >  for (const char *p = text; (c = *p); ++p)
186 >  {
187      if (c >= '0' && c <= '9')   /* empty */
188        ;
189      else if (c == '.')
# Line 191 | 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 202 | Line 206 | try_parse_v4_netmask(const char *text, s
206        char *after;
207        bits = strtoul(p + 1, &after, 10);
208  
209 <      if (!bits || *after)
209 >      if (bits < 0 || *after)
210          return HM_HOST;
211        if (bits > n * 8)
212          return HM_HOST;
# Line 211 | Line 215 | try_parse_v4_netmask(const char *text, s
215      }
216      else
217        return HM_HOST;
218 +  }
219  
220    if (n < 4 && bits == 0)
221      bits = n * 8;
# Line 218 | Line 223 | try_parse_v4_netmask(const char *text, s
223      while (n < 4)
224        digits[n++] = "0";
225  
226 <  for (n = 0; n < 4; n++)
226 >  for (n = 0; n < 4; ++n)
227      addb[n] = strtoul(digits[n], NULL, 10);
228  
229    if (bits == 0)
# Line 227 | Line 232 | try_parse_v4_netmask(const char *text, s
232    /* Set unused bits to 0... -A1kmm */
233    if (bits < 32 && bits % 8)
234      addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1);
235 <  for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; n++)
235 >  for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; ++n)
236      addb[n] = 0;
237    if (addr)
238      v4->sin_addr.s_addr =
239        htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]);
240 <  if (b != NULL)
240 >  if (b)
241      *b = bits;
242    return HM_IPV4;
243   }
# Line 247 | Line 252 | try_parse_v4_netmask(const char *text, s
252   int
253   parse_netmask(const char *text, struct irc_ssaddr *addr, int *b)
254   {
250 – #ifdef IPV6
251 –  if (strchr(text, ':'))
252 –    return try_parse_v6_netmask(text, addr, b);
253 – #endif
255    if (strchr(text, '.'))
256      return try_parse_v4_netmask(text, addr, b);
257 +  if (strchr(text, ':'))
258 +    return try_parse_v6_netmask(text, addr, b);
259 +
260    return HM_HOST;
261   }
262  
# Line 262 | Line 266 | parse_netmask(const char *text, struct i
266   * Output: if match, -1 else 0
267   * Side effects: None
268   */
265 – #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++)
276 >  for (i = 0; i < n; ++i)
277      if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
278        return 0;
279 +
280    if ((m = bits % 8) == 0)
281      return -1;
282    if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) ==
# Line 280 | Line 284 | match_ipv6(const struct irc_ssaddr *addr
284      return -1;
285    return 0;
286   }
283 – #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 290 | 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 311 | Line 314 | void
314   mask_addr(struct irc_ssaddr *ip, int bits)
315   {
316    int mask;
314 – #ifdef IPV6
317    struct sockaddr_in6 *v6_base_ip;
318    int i, m, n;
317 – #endif
319    struct sockaddr_in *v4_base_ip;
320  
321 < #ifdef IPV6
321 <  if (ip->ss.ss_family != AF_INET6)
322 < #endif
321 >  if (ip->ss.ss_family == AF_INET)
322    {
323 +    uint32_t tmp = 0;
324      v4_base_ip = (struct sockaddr_in *)ip;
325  
326      mask = ~((1 << (32 - bits)) - 1);
327 <    v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
327 >    tmp = ntohl(v4_base_ip->sin_addr.s_addr);
328 >    v4_base_ip->sin_addr.s_addr = htonl(tmp & mask);
329    }
329 – #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    }
342 – #endif
343 – }
344 –
345 – /* Hashtable stuff...now external as its used in m_stats.c */
346 – dlink_list atable[ATABLE_SIZE];
347 –
348 – void
349 – init_host_hash(void)
350 – {
351 –  memset(&atable, 0, sizeof(atable));
342   }
343  
344   /* unsigned long hash_ipv4(struct irc_ssaddr*)
# Line 357 | Line 347 | init_host_hash(void)
347   * Side effects: None
348   */
349   static uint32_t
350 < hash_ipv4(struct irc_ssaddr *addr, int bits)
350 > hash_ipv4(const struct irc_ssaddr *addr, int bits)
351   {
352    if (bits != 0)
353    {
354 <    struct sockaddr_in *v4 = (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 375 | Line 365 | hash_ipv4(struct irc_ssaddr *addr, int b
365   * Output: A hash value of the IP address.
366   * Side effects: None
367   */
378 – #ifdef IPV6
368   static uint32_t
369 < hash_ipv6(struct irc_ssaddr *addr, int bits)
369 > hash_ipv6(const struct irc_ssaddr *addr, int bits)
370   {
371    uint32_t v = 0, n;
372 <  struct sockaddr_in6 *v6 = (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 397 | Line 386 | hash_ipv6(struct irc_ssaddr *addr, int b
386      else
387        return v & (ATABLE_SIZE - 1);
388    }
389 +
390    return v & (ATABLE_SIZE - 1);
391   }
402 – #endif
392  
393   /* int hash_text(const char *start)
394   * Input: The start of the text to hash.
# Line 409 | Line 398 | hash_ipv6(struct irc_ssaddr *addr, int b
398   static uint32_t
399   hash_text(const char *start)
400   {
412 –  const char *p = start;
401    uint32_t h = 0;
402  
403 <  for (; *p; ++p)
404 <    h = (h << 4) - (h + (unsigned char)ToLower(*p));
403 >  for (const char *p = start; *p; ++p)
404 >    h = (h << 4) - (h + ToLower(*p));
405  
406    return h & (ATABLE_SIZE - 1);
407   }
# Line 429 | 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 437 | Line 425 | get_mask_hash(const char *text)
425    return hash_text(text);
426   }
427  
428 < /* struct AccessItem *find_conf_by_address(const char *, struct irc_ssaddr *,
428 > /* struct MaskItem *find_conf_by_address(const char *, struct irc_ssaddr *,
429   *                                         int type, int fam, const char *username)
430   * Input: The hostname, the address, the type of mask to find, the address
431   *        family, the username.
# Line 445 | Line 433 | get_mask_hash(const char *text)
433   * Side-effects: None
434   * Note: Setting bit 0 of the type means that the username is ignored.
435   * Warning: IsNeedPassword for everything that is not an auth{} entry
436 < * should always be true (i.e. aconf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
436 > * should always be true (i.e. conf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
437   */
438 < struct AccessItem *
439 < find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type,
438 > struct MaskItem *
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;
444 <  struct AccessItem *hprec = NULL;
445 <  struct AddressRec *arec;
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  
461 –  if (username == NULL)
462 –    username = "";
463 –  if (password == NULL)
464 –    password = "";
465 –
449    if (addr)
450    {
451      /* Check for IPV6 matches... */
469 – #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) == do_match) &&
466 <              (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
467 <               match_conf_password(password, arec->aconf)))
465 >              (!username || !cmpfunc(arec->username, username)) &&
466 >              (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
467 >               match_conf_password(password, arec->conf)))
468            {
469              hprecv = arec->precedence;
470 <            hprec = arec->aconf;
470 >            hprec = arec->conf;
471            }
472          }
473        }
474      }
475 <    else
494 < #endif
495 <    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) == do_match) &&
489 <              (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
490 <               match_conf_password(password, arec->aconf)))
488 >              (!username || !cmpfunc(arec->username, username)) &&
489 >              (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
490 >               match_conf_password(password, arec->conf)))
491            {
492              hprecv = arec->precedence;
493 <            hprec = arec->aconf;
493 >            hprec = arec->conf;
494            }
495          }
496        }
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) == do_match &&
513 <            (type & 0x1 || cmpfunc(arec->username, username) == do_match) &&
514 <            (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
515 <             match_conf_password(password, arec->aconf)))
512 >            !cmpfunc(arec->Mask.hostname, name) &&
513 >            (!username || !cmpfunc(arec->username, username)) &&
514 >            (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
515 >             match_conf_password(password, arec->conf)))
516          {
517            hprecv = arec->precedence;
518 <          hprec = arec->aconf;
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) == 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    }
# Line 565 | Line 545 | find_conf_by_address(const char *name, s
545    return hprec;
546   }
547  
548 < /* struct AccessItem* find_address_conf(const char*, const char*,
548 > /* struct MaskItem* find_address_conf(const char*, const char*,
549   *                                     struct irc_ssaddr*, int, char *);
550   * Input: The hostname, username, address, address family.
551 < * Output: The applicable AccessItem.
551 > * Output: The applicable MaskItem.
552   * Side-effects: None
553   */
554 < struct AccessItem *
555 < find_address_conf(const char *host, const char *user,
556 <                  struct irc_ssaddr *ip, int aftype, char *password)
554 > struct MaskItem *
555 > find_address_conf(const char *host, const char *user, struct irc_ssaddr *ip,
556 >                  int aftype, const char *password)
557   {
558 <  struct AccessItem *iconf, *kconf;
558 >  struct MaskItem *authcnf = NULL, *killcnf = NULL;
559  
560    /* Find the best auth{} block... If none, return NULL -A1kmm */
561 <  if ((iconf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
562 <                                    password, 1)) == NULL)
561 >  if ((authcnf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
562 >                                      password, 1)) == NULL)
563      return NULL;
564  
565    /* If they are exempt from K-lines, return the best auth{} block. -A1kmm */
566 <  if (IsConfExemptKline(iconf))
567 <    return iconf;
566 >  if (IsConfExemptKline(authcnf))
567 >    return authcnf;
568  
569    /* Find the best K-line... -A1kmm */
570 <  kconf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
570 >  killcnf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
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 (kconf != NULL)
577 <    return kconf;
598 <
599 <  kconf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
600 <  if (kconf != NULL && !IsConfExemptGline(iconf))
601 <    return kconf;
576 >  if (killcnf && (killcnf->until == 0 || killcnf->until > CurrentTime))
577 >    return killcnf;
578  
579 <  return iconf;
579 >  return authcnf;
580   }
581  
582 < /* struct AccessItem* find_dline_conf(struct irc_ssaddr*, int)
582 > /* struct MaskItem* find_dline_conf(struct irc_ssaddr*, int)
583   *
584   * Input:       An address, an address family.
585   * Output:      The best matching D-line or exempt line.
586   * Side effects: None.
587   */
588 < struct AccessItem *
588 > struct MaskItem *
589   find_dline_conf(struct irc_ssaddr *addr, int aftype)
590   {
591 <  struct AccessItem *eline;
591 >  struct MaskItem *eline;
592 >  struct MaskItem *dline;
593  
594 <  eline = find_conf_by_address(NULL, addr, CONF_EXEMPTDLINE | 1, aftype,
595 <                               NULL, NULL, 1);
619 <  if (eline != NULL)
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 | 1, 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 AccessItem *aconf)
606 < * Input:
605 > /* void add_conf_by_address(int, struct MaskItem *aconf)
606 > * Input:
607   * Output: None
608   * Side-effects: Adds this entry to the hash table.
609   */
610 < void
611 < add_conf_by_address(const unsigned int type, struct AccessItem *aconf)
610 > struct AddressRec *
611 > add_conf_by_address(const unsigned int type, struct MaskItem *conf)
612   {
613 <  const char *address;
614 <  const char *username;
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;
637 –  struct AddressRec *arec;
638 –
639 –  address = aconf->host;
640 –  username = aconf->user;
641 –
642 –  assert(type != 0);
643 –  assert(aconf != NULL);
618  
619 <  if (EmptyString(address))
646 <    address = "/NOMATCH!/";
619 >  assert(type && !EmptyString(hostname));
620  
621 <  arec = MyMalloc(sizeof(struct AddressRec));
622 <  arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
621 >  arec = MyCalloc(sizeof(struct AddressRec));
622 >  arec->masktype = parse_netmask(hostname, &arec->Mask.ipa.addr, &bits);
623    arec->Mask.ipa.bits = bits;
624    arec->username = username;
625 <  arec->aconf = aconf;
625 >  arec->conf = conf;
626    arec->precedence = prec_value--;
627    arec->type = type;
628  
# Line 660 | 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;
663 – #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;
669 – #endif
641      default: /* HM_HOST */
642 <      arec->Mask.hostname = address;
643 <      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(address)]);
642 >      arec->Mask.hostname = hostname;
643 >      dlinkAdd(arec, &arec->node, &atable[get_mask_hash(hostname)]);
644        break;
645    }
646 +
647 +  return arec;
648   }
649  
650 < /* void delete_one_address(const char*, struct AccessItem*)
651 < * Input: An address string, the associated AccessItem.
650 > /* void delete_one_address(const char*, struct MaskItem*)
651 > * Input: An address string, the associated MaskItem.
652   * Output: None
653 < * Side effects: Deletes an address record. Frees the AccessItem if there
653 > * Side effects: Deletes an address record. Frees the MaskItem if there
654   *               is nothing referencing it, sets it as illegal otherwise.
655   */
656   void
657 < delete_one_address_conf(const char *address, struct AccessItem *aconf)
657 > delete_one_address_conf(const char *address, struct MaskItem *conf)
658   {
659    int bits = 0;
660    uint32_t hv = 0;
661 <  dlink_node *ptr = NULL, *ptr_next = NULL;
661 >  dlink_node *node = NULL;
662    struct irc_ssaddr addr;
663  
664    switch (parse_netmask(address, &addr, &bits))
# Line 695 | Line 668 | delete_one_address_conf(const char *addr
668        bits -= bits % 8;
669        hv = hash_ipv4(&addr, bits);
670        break;
698 – #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;
704 – #endif
676      default: /* HM_HOST */
677        hv = get_mask_hash(address);
678        break;
679    }
680  
681 <  DLINK_FOREACH_SAFE(ptr, ptr_next, 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->aconf == aconf)
685 >    if (arec->conf == conf)
686      {
687        dlinkDelete(&arec->node, &atable[hv]);
717 –      aconf->status |= CONF_ILLEGAL;
688  
689 <      if (!aconf->clients)
690 <        free_access_item(aconf);
689 >      if (!conf->ref_count)
690 >        conf_free(conf);
691  
692        MyFree(arec);
693        return;
# Line 729 | Line 699 | delete_one_address_conf(const char *addr
699   * Input: None
700   * Output: None
701   * Side effects: Clears out all address records in the hash table,
702 < *               frees them, and frees the AccessItems if nothing references
703 < *               them, otherwise sets them as illegal.  
702 > *               frees them, and frees the MaskItems if nothing references
703 > *               them, otherwise sets them as illegal.
704   */
705   void
706   clear_out_address_conf(void)
707   {
708 <  unsigned int i = 0;
709 <  dlink_node *ptr = NULL, *ptr_next = NULL;
710 <
741 <  for (i = 0; i < ATABLE_SIZE; ++i)
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,
749 <       * just to be confusing :) -A1kmm
717 >       * Destroy the ircd.conf items and keep those that are in the databases
718         */
719 <      if (arec->aconf->hold || IsConfDatabase(arec->aconf))
719 >      if (IsConfDatabase(arec->conf))
720          continue;
721  
722        dlinkDelete(&arec->node, &atable[i]);
723 <      arec->aconf->status |= CONF_ILLEGAL;
723 >      arec->conf->active = 0;
724  
725 <      if (!arec->aconf->clients)
726 <        free_access_item(arec->aconf);
725 >      if (!arec->conf->ref_count)
726 >        conf_free(arec->conf);
727        MyFree(arec);
728      }
729    }
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 777 | Line 745 | hostmask_send_expiration(struct AddressR
745      case CONF_DLINE:
746        ban_type = 'D';
747        break;
748 <    case CONF_GLINE:
781 <      ban_type = 'G';
782 <      break;
748 >    default: break;
749    }
750 <  
751 <  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
750 >
751 >  sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
752                         "Temporary %c-line for [%s@%s] expired", ban_type,
753 <                       (arec->aconf->user) ? arec->aconf->user : "*",
754 <                       (arec->aconf->host) ? arec->aconf->host : "*");
753 >                       (arec->conf->user) ? arec->conf->user : "*",
754 >                       (arec->conf->host) ? arec->conf->host : "*");
755   }
756  
757   void
758   hostmask_expire_temporary(void)
759   {
760 <  unsigned int i = 0;
795 <  dlink_node *ptr = NULL, *ptr_next = NULL;
760 >  dlink_node *node = NULL, *node_next = NULL;
761  
762 <  for (i = 0; i < ATABLE_SIZE; ++i)
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->aconf->hold || arec->aconf->hold > CurrentTime)
768 >      if (!arec->conf->until || arec->conf->until > CurrentTime)
769          continue;
770  
771        switch (arec->type)
772        {
773          case CONF_KLINE:
774          case CONF_DLINE:
810 –        case CONF_GLINE:
775            hostmask_send_expiration(arec);
776  
777            dlinkDelete(&arec->node, &atable[i]);
778 <          free_access_item(arec->aconf);
778 >          conf_free(arec->conf);
779            MyFree(arec);
780            break;
781 +        default: break;
782        }
783      }
784    }

Diff Legend

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