ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/hostmask.c
Revision: 6579
Committed: Mon Oct 19 19:10:05 2015 UTC (9 years, 10 months ago) by michael
Content type: text/x-csrc
File size: 20522 byte(s)
Log Message:
- hostmask.c: removed irrelevant comment

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 5347 * Copyright (c) 2001-2015 ircd-hybrid development team
5 adx 30 *
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
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
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 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 adx 30 * USA
20     */
21    
22 michael 2916 /*! \file hostmask.c
23     * \brief Code to efficiently find IP & hostmask based configs.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28     #include "memory.h"
29     #include "ircd_defs.h"
30 michael 1011 #include "list.h"
31 michael 1309 #include "conf.h"
32 adx 30 #include "hostmask.h"
33     #include "send.h"
34     #include "irc_string.h"
35 michael 1369 #include "ircd.h"
36 adx 30
37    
38     #define DigitParse(ch) do { \
39     if (ch >= '0' && ch <= '9') \
40     ch = ch - '0'; \
41     else if (ch >= 'A' && ch <= 'F') \
42     ch = ch - 'A' + 10; \
43     else if (ch >= 'a' && ch <= 'f') \
44     ch = ch - 'a' + 10; \
45 michael 1298 } while (0);
46 adx 30
47 michael 5460 /* Hashtable stuff...now external as it's used in m_stats.c */
48     dlink_list atable[ATABLE_SIZE];
49    
50 adx 30 /* The mask parser/type determination code... */
51    
52     /* int try_parse_v6_netmask(const char *, struct irc_ssaddr *, int *);
53     * Input: A possible IPV6 address as a string.
54     * Output: An integer describing whether it is an IPV6 or hostmask,
55     * an address(if it is IPV6), a bitlength(if it is IPV6).
56     * Side effects: None
57     * Comments: Called from parse_netmask
58     */
59     static int
60     try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
61     {
62     char c;
63     int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
64     int dp = 0;
65     int nyble = 4;
66     int finsert = -1;
67     int bits = 128;
68     int deficit = 0;
69     short dc[8];
70 michael 4874 struct sockaddr_in6 *const v6 = (struct sockaddr_in6 *)addr;
71 adx 30
72 michael 3469 for (const char *p = text; (c = *p); ++p)
73 michael 2894 {
74 adx 30 if (IsXDigit(c))
75     {
76     if (nyble == 0)
77     return HM_HOST;
78     DigitParse(c);
79     d[dp] |= c << (4 * --nyble);
80     }
81     else if (c == ':')
82     {
83     if (p > text && *(p - 1) == ':')
84     {
85     if (finsert >= 0)
86     return HM_HOST;
87     finsert = dp;
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 */
93     d[dp] = d[dp] >> 4 * nyble;
94     nyble = 4;
95     if (++dp >= 8)
96     return HM_HOST;
97     }
98     }
99     else if (c == '*')
100     {
101     /* * must be last, and * is ambiguous if there is a ::... -A1kmm */
102     if (finsert >= 0 || *(p + 1) || dp == 0 || *(p - 1) != ':')
103     return HM_HOST;
104     bits = dp * 16;
105     }
106     else if (c == '/')
107     {
108     char *after;
109    
110     d[dp] = d[dp] >> 4 * nyble;
111 michael 3215 ++dp;
112 adx 30 bits = strtoul(p + 1, &after, 10);
113 michael 1298
114 adx 30 if (bits < 0 || *after)
115     return HM_HOST;
116     if (bits > dp * 4 && !(finsert >= 0 && bits <= 128))
117     return HM_HOST;
118     break;
119     }
120     else
121     return HM_HOST;
122 michael 2894 }
123 adx 30
124     d[dp] = d[dp] >> 4 * nyble;
125 michael 1298
126 adx 30 if (c == 0)
127 michael 3215 ++dp;
128 adx 30 if (finsert < 0 && bits == 0)
129     bits = dp * 16;
130 michael 1298
131 adx 30 /* How many words are missing? -A1kmm */
132     deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp;
133 michael 1298
134 adx 30 /* Now fill in the gaps(from ::) in the copied table... -A1kmm */
135 michael 3215 for (dp = 0, nyble = 0; dp < 8; ++dp)
136 adx 30 {
137     if (nyble == finsert && deficit)
138     {
139     dc[dp] = 0;
140     deficit--;
141     }
142     else
143     dc[dp] = d[nyble++];
144     }
145 michael 1298
146 adx 30 /* Set unused bits to 0... -A1kmm */
147     if (bits < 128 && (bits % 16 != 0))
148     dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1);
149 michael 3215 for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; ++dp)
150 adx 30 dc[dp] = 0;
151 michael 1298
152 adx 30 /* And assign... -A1kmm */
153     if (addr)
154 michael 3215 for (dp = 0; dp < 8; ++dp)
155 adx 30 /* The cast is a kludge to make netbsd work. */
156     ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]);
157 michael 1298
158 michael 3215 if (b)
159 adx 30 *b = bits;
160     return HM_IPV6;
161     }
162    
163     /* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
164     * Input: A possible IPV4 address as a string.
165     * Output: An integer describing whether it is an IPV4 or hostmask,
166     * an address(if it is IPV4), a bitlength(if it is IPV4).
167     * Side effects: None
168     * Comments: Called from parse_netmask
169     */
170     static int
171     try_parse_v4_netmask(const char *text, struct irc_ssaddr *addr, int *b)
172     {
173     const char *digits[4];
174     unsigned char addb[4];
175     int n = 0, bits = 0;
176     char c;
177 michael 4874 struct sockaddr_in *const v4 = (struct sockaddr_in *)addr;
178 adx 30
179     digits[n++] = text;
180    
181 michael 3469 for (const char *p = text; (c = *p); ++p)
182 michael 2894 {
183 adx 30 if (c >= '0' && c <= '9') /* empty */
184     ;
185     else if (c == '.')
186     {
187     if (n >= 4)
188     return HM_HOST;
189 michael 1298
190 adx 30 digits[n++] = p + 1;
191     }
192     else if (c == '*')
193     {
194 michael 5976 if (*(p + 1) || n == 1 || *(p - 1) != '.')
195 adx 30 return HM_HOST;
196 michael 1298
197 adx 30 bits = (n - 1) * 8;
198     break;
199     }
200     else if (c == '/')
201     {
202     char *after;
203     bits = strtoul(p + 1, &after, 10);
204 michael 1298
205 michael 1786 if (bits < 0 || *after)
206 adx 30 return HM_HOST;
207     if (bits > n * 8)
208     return HM_HOST;
209 michael 1298
210 adx 30 break;
211     }
212     else
213     return HM_HOST;
214 michael 2894 }
215 adx 30
216     if (n < 4 && bits == 0)
217     bits = n * 8;
218     if (bits)
219     while (n < 4)
220     digits[n++] = "0";
221 michael 1298
222 michael 3215 for (n = 0; n < 4; ++n)
223 adx 30 addb[n] = strtoul(digits[n], NULL, 10);
224 michael 1298
225 adx 30 if (bits == 0)
226     bits = 32;
227 michael 1298
228 adx 30 /* Set unused bits to 0... -A1kmm */
229     if (bits < 32 && bits % 8)
230     addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1);
231 michael 3215 for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; ++n)
232 adx 30 addb[n] = 0;
233     if (addr)
234     v4->sin_addr.s_addr =
235     htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]);
236 michael 3215 if (b)
237 adx 30 *b = bits;
238     return HM_IPV4;
239     }
240    
241     /* int parse_netmask(const char *, struct irc_ssaddr *, int *);
242     * Input: A hostmask, or an IPV4/6 address.
243     * Output: An integer describing whether it is an IPV4, IPV6 address or a
244     * hostmask, an address(if it is an IP mask),
245     * a bitlength(if it is IP mask).
246     * Side effects: None
247     */
248     int
249     parse_netmask(const char *text, struct irc_ssaddr *addr, int *b)
250     {
251 michael 2814 if (strchr(text, '.'))
252     return try_parse_v4_netmask(text, addr, b);
253 michael 1298 if (strchr(text, ':'))
254 adx 30 return try_parse_v6_netmask(text, addr, b);
255 michael 4415
256 adx 30 return HM_HOST;
257     }
258    
259     /* The address matching stuff... */
260     /* int match_ipv6(struct irc_ssaddr *, struct irc_ssaddr *, int)
261     * Input: An IP address, an IP mask, the number of bits in the mask.
262     * Output: if match, -1 else 0
263     * Side effects: None
264     */
265     int
266 michael 1455 match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
267 adx 30 {
268     int i, m, n = bits / 8;
269 michael 4977 const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
270     const struct sockaddr_in6 *const v6mask = (const struct sockaddr_in6 *)mask;
271 adx 30
272 michael 3215 for (i = 0; i < n; ++i)
273 adx 30 if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
274     return 0;
275 michael 3215
276 adx 30 if ((m = bits % 8) == 0)
277     return -1;
278     if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) ==
279     v6mask->sin6_addr.s6_addr[n])
280     return -1;
281     return 0;
282     }
283 michael 1372
284 adx 30 /* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int)
285     * Input: An IP address, an IP mask, the number of bits in the mask.
286     * Output: if match, -1 else 0
287     * Side Effects: None
288     */
289     int
290 michael 1455 match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
291 adx 30 {
292 michael 4977 const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
293     const struct sockaddr_in *const v4mask = (const struct sockaddr_in *)mask;
294 michael 1298
295 adx 30 if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
296     ntohl(v4mask->sin_addr.s_addr))
297     return 0;
298     return -1;
299     }
300    
301     /*
302     * mask_addr
303     *
304     * inputs - pointer to the ip to mask
305     * - bitlen
306     * output - NONE
307     * side effects -
308     */
309     void
310     mask_addr(struct irc_ssaddr *ip, int bits)
311     {
312     int mask;
313     struct sockaddr_in6 *v6_base_ip;
314     int i, m, n;
315     struct sockaddr_in *v4_base_ip;
316    
317 michael 4415 if (ip->ss.ss_family == AF_INET)
318 adx 30 {
319 michael 3770 uint32_t tmp = 0;
320 michael 1298 v4_base_ip = (struct sockaddr_in *)ip;
321    
322 adx 30 mask = ~((1 << (32 - bits)) - 1);
323 michael 3770 tmp = ntohl(v4_base_ip->sin_addr.s_addr);
324     v4_base_ip->sin_addr.s_addr = htonl(tmp & mask);
325 adx 30 }
326     else
327     {
328     n = bits / 8;
329     m = bits % 8;
330 michael 1298 v6_base_ip = (struct sockaddr_in6 *)ip;
331 adx 30
332 michael 4915 mask = ~((1 << (8 - m)) - 1);
333 adx 30 v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask;
334 michael 1298
335 db 300 for (i = n + 1; i < 16; i++)
336     v6_base_ip->sin6_addr.s6_addr[i] = 0;
337 adx 30 }
338     }
339    
340     /* unsigned long hash_ipv4(struct irc_ssaddr*)
341     * Input: An IP address.
342     * Output: A hash value of the IP address.
343     * Side effects: None
344     */
345 michael 1343 static uint32_t
346 michael 2898 hash_ipv4(const struct irc_ssaddr *addr, int bits)
347 adx 30 {
348     if (bits != 0)
349     {
350 michael 4874 const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr;
351 michael 1343 uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
352 michael 1298
353     return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
354 adx 30 }
355    
356 michael 1298 return 0;
357 adx 30 }
358    
359     /* unsigned long hash_ipv6(struct irc_ssaddr*)
360     * Input: An IP address.
361     * Output: A hash value of the IP address.
362     * Side effects: None
363     */
364 michael 1343 static uint32_t
365 michael 2898 hash_ipv6(const struct irc_ssaddr *addr, int bits)
366 adx 30 {
367 michael 1343 uint32_t v = 0, n;
368 michael 4874 const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr;
369 michael 1298
370 michael 3215 for (n = 0; n < 16; ++n)
371 adx 30 {
372     if (bits >= 8)
373     {
374     v ^= v6->sin6_addr.s6_addr[n];
375     bits -= 8;
376     }
377     else if (bits)
378     {
379     v ^= v6->sin6_addr.s6_addr[n] & ~((1 << (8 - bits)) - 1);
380     return v & (ATABLE_SIZE - 1);
381     }
382     else
383     return v & (ATABLE_SIZE - 1);
384     }
385 michael 4415
386 adx 30 return v & (ATABLE_SIZE - 1);
387     }
388    
389     /* int hash_text(const char *start)
390     * Input: The start of the text to hash.
391     * Output: The hash of the string between 1 and (TH_MAX-1)
392     * Side-effects: None.
393     */
394 michael 1343 static uint32_t
395 adx 30 hash_text(const char *start)
396     {
397 michael 1343 uint32_t h = 0;
398 adx 30
399 michael 3469 for (const char *p = start; *p; ++p)
400 michael 2331 h = (h << 4) - (h + ToLower(*p));
401 michael 1298
402     return h & (ATABLE_SIZE - 1);
403 adx 30 }
404    
405     /* unsigned long get_hash_mask(const char *)
406     * Input: The text to hash.
407     * Output: The hash of the string right of the first '.' past the last
408     * wildcard in the string.
409     * Side-effects: None.
410     */
411 michael 1343 static uint32_t
412 adx 30 get_mask_hash(const char *text)
413     {
414     const char *hp = "", *p;
415    
416 michael 3215 for (p = text + strlen(text) - 1; p >= text; --p)
417 adx 723 if (IsMWildChar(*p))
418 adx 30 return hash_text(hp);
419     else if (*p == '.')
420     hp = p + 1;
421     return hash_text(text);
422     }
423    
424 michael 1632 /* struct MaskItem *find_conf_by_address(const char *, struct irc_ssaddr *,
425 adx 30 * int type, int fam, const char *username)
426     * Input: The hostname, the address, the type of mask to find, the address
427     * family, the username.
428     * Output: The matching value with the highest precedence.
429     * Side-effects: None
430     * Note: Setting bit 0 of the type means that the username is ignored.
431     * Warning: IsNeedPassword for everything that is not an auth{} entry
432 michael 1632 * should always be true (i.e. conf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
433 adx 30 */
434 michael 1632 struct MaskItem *
435 michael 5850 find_conf_by_address(const char *name, const struct irc_ssaddr *addr, unsigned int type,
436 michael 1371 int fam, const char *username, const char *password, int do_match)
437 adx 30 {
438 michael 1343 unsigned int hprecv = 0;
439 michael 4815 dlink_node *node = NULL;
440 michael 1632 struct MaskItem *hprec = NULL;
441     struct AddressRec *arec = NULL;
442 adx 30 int b;
443 michael 1371 int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp;
444 adx 30
445     if (addr)
446     {
447     /* Check for IPV6 matches... */
448     if (fam == AF_INET6)
449     {
450     for (b = 128; b >= 0; b -= 16)
451     {
452 michael 4815 DLINK_FOREACH(node, atable[hash_ipv6(addr, b)].head)
453 michael 1367 {
454 michael 4815 arec = node->data;
455 michael 1367
456 michael 2995 if ((arec->type == type) &&
457 adx 30 arec->precedence > hprecv &&
458     arec->masktype == HM_IPV6 &&
459     match_ipv6(addr, &arec->Mask.ipa.addr,
460     arec->Mask.ipa.bits) &&
461 michael 2995 (!username || !cmpfunc(arec->username, username)) &&
462 michael 2916 (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
463     match_conf_password(password, arec->conf)))
464 adx 30 {
465     hprecv = arec->precedence;
466 michael 1632 hprec = arec->conf;
467 adx 30 }
468 michael 1367 }
469 adx 30 }
470     }
471 michael 4415 else if (fam == AF_INET)
472 adx 30 {
473     for (b = 32; b >= 0; b -= 8)
474     {
475 michael 4815 DLINK_FOREACH(node, atable[hash_ipv4(addr, b)].head)
476 michael 1367 {
477 michael 4815 arec = node->data;
478 michael 1367
479 michael 2995 if ((arec->type == type) &&
480 adx 30 arec->precedence > hprecv &&
481     arec->masktype == HM_IPV4 &&
482     match_ipv4(addr, &arec->Mask.ipa.addr,
483     arec->Mask.ipa.bits) &&
484 michael 2995 (!username || !cmpfunc(arec->username, username)) &&
485 michael 2916 (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
486     match_conf_password(password, arec->conf)))
487 adx 30 {
488     hprecv = arec->precedence;
489 michael 1632 hprec = arec->conf;
490 adx 30 }
491 michael 1367 }
492 adx 30 }
493     }
494     }
495    
496 michael 3215 if (name)
497 adx 30 {
498     const char *p = name;
499    
500     while (1)
501     {
502 michael 4815 DLINK_FOREACH(node, atable[hash_text(p)].head)
503 michael 1367 {
504 michael 4815 arec = node->data;
505 michael 2995 if ((arec->type == type) &&
506 adx 30 arec->precedence > hprecv &&
507     (arec->masktype == HM_HOST) &&
508 michael 1652 !cmpfunc(arec->Mask.hostname, name) &&
509 michael 2995 (!username || !cmpfunc(arec->username, username)) &&
510 michael 1632 (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
511     match_conf_password(password, arec->conf)))
512 adx 30 {
513     hprecv = arec->precedence;
514 michael 1632 hprec = arec->conf;
515 adx 30 }
516 michael 1367 }
517 michael 3215
518     if ((p = strchr(p, '.')) == NULL)
519 adx 30 break;
520 michael 3215 ++p;
521 adx 30 }
522 michael 1367
523 michael 4815 DLINK_FOREACH(node, atable[0].head)
524 michael 1367 {
525 michael 4815 arec = node->data;
526 michael 1367
527 michael 2995 if (arec->type == type &&
528 adx 30 arec->precedence > hprecv &&
529     arec->masktype == HM_HOST &&
530 michael 1652 !cmpfunc(arec->Mask.hostname, name) &&
531 michael 2995 (!username || !cmpfunc(arec->username, username)) &&
532 michael 1632 (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
533     match_conf_password(password, arec->conf)))
534 adx 30 {
535     hprecv = arec->precedence;
536 michael 1632 hprec = arec->conf;
537 adx 30 }
538 michael 1367 }
539 adx 30 }
540    
541     return hprec;
542     }
543    
544 michael 1632 /* struct MaskItem* find_address_conf(const char*, const char*,
545 adx 30 * struct irc_ssaddr*, int, char *);
546     * Input: The hostname, username, address, address family.
547 michael 1632 * Output: The applicable MaskItem.
548 adx 30 * Side-effects: None
549     */
550 michael 1632 struct MaskItem *
551 michael 6429 find_address_conf(const char *host, const char *user, const struct irc_ssaddr *ip,
552 michael 3553 int aftype, const char *password)
553 adx 30 {
554 michael 1632 struct MaskItem *authcnf = NULL, *killcnf = NULL;
555 adx 30
556 michael 1426 /* Find the best auth{} block... If none, return NULL -A1kmm */
557 michael 1632 if ((authcnf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
558     password, 1)) == NULL)
559 michael 1298 return NULL;
560 adx 30
561 michael 1426 /* If they are exempt from K-lines, return the best auth{} block. -A1kmm */
562 michael 1632 if (IsConfExemptKline(authcnf))
563     return authcnf;
564 adx 30
565     /* Find the best K-line... -A1kmm */
566 michael 1632 killcnf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
567 adx 30
568 michael 1426 /*
569     * If they are K-lined, return the K-line. Otherwise, return the
570 michael 5805 * auth {} block. -A1kmm
571 michael 1426 */
572 michael 6411 if (killcnf)
573 michael 1632 return killcnf;
574 adx 30
575 michael 1632 return authcnf;
576 adx 30 }
577    
578 michael 1632 /* struct MaskItem* find_dline_conf(struct irc_ssaddr*, int)
579 adx 30 *
580     * Input: An address, an address family.
581     * Output: The best matching D-line or exempt line.
582     * Side effects: None.
583     */
584 michael 1632 struct MaskItem *
585 michael 6429 find_dline_conf(const struct irc_ssaddr *addr, int aftype)
586 adx 30 {
587 michael 1632 struct MaskItem *eline;
588 adx 30
589 michael 2995 eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, aftype, NULL, NULL, 1);
590 michael 3215 if (eline)
591 michael 1298 return eline;
592    
593 michael 6411 return find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1);
594 adx 30 }
595    
596 michael 1632 /* void add_conf_by_address(int, struct MaskItem *aconf)
597 michael 2916 * Input:
598 adx 30 * Output: None
599     * Side-effects: Adds this entry to the hash table.
600     */
601 michael 2811 struct AddressRec *
602 michael 1632 add_conf_by_address(const unsigned int type, struct MaskItem *conf)
603 adx 30 {
604 michael 4977 struct AddressRec *arec = NULL;
605     const char *const hostname = conf->host;
606     const char *const username = conf->user;
607 michael 1343 static unsigned int prec_value = 0xFFFFFFFF;
608 michael 1367 int bits = 0;
609 adx 30
610 michael 3003 assert(type && !EmptyString(hostname));
611 adx 30
612 michael 3504 arec = MyCalloc(sizeof(struct AddressRec));
613 michael 3001 arec->masktype = parse_netmask(hostname, &arec->Mask.ipa.addr, &bits);
614 adx 30 arec->Mask.ipa.bits = bits;
615 michael 1367 arec->username = username;
616 michael 1632 arec->conf = conf;
617 michael 1367 arec->precedence = prec_value--;
618     arec->type = type;
619 michael 1298
620 michael 1367 switch (arec->masktype)
621     {
622     case HM_IPV4:
623     /* We have to do this, since we do not re-hash for every bit -A1kmm. */
624     bits -= bits % 8;
625     dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]);
626     break;
627     case HM_IPV6:
628     /* We have to do this, since we do not re-hash for every bit -A1kmm. */
629     bits -= bits % 16;
630     dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]);
631     break;
632     default: /* HM_HOST */
633 michael 3001 arec->Mask.hostname = hostname;
634     dlinkAdd(arec, &arec->node, &atable[get_mask_hash(hostname)]);
635 michael 1367 break;
636 adx 30 }
637 michael 2811
638     return arec;
639 adx 30 }
640    
641 michael 1632 /* void delete_one_address(const char*, struct MaskItem*)
642     * Input: An address string, the associated MaskItem.
643 adx 30 * Output: None
644 michael 1632 * Side effects: Deletes an address record. Frees the MaskItem if there
645 adx 30 * is nothing referencing it, sets it as illegal otherwise.
646     */
647     void
648 michael 1632 delete_one_address_conf(const char *address, struct MaskItem *conf)
649 adx 30 {
650 michael 1367 int bits = 0;
651     uint32_t hv = 0;
652 michael 4815 dlink_node *node = NULL;
653 adx 30 struct irc_ssaddr addr;
654 michael 1298
655 michael 1367 switch (parse_netmask(address, &addr, &bits))
656     {
657     case HM_IPV4:
658     /* We have to do this, since we do not re-hash for every bit -A1kmm. */
659     bits -= bits % 8;
660     hv = hash_ipv4(&addr, bits);
661     break;
662     case HM_IPV6:
663     /* We have to do this, since we do not re-hash for every bit -A1kmm. */
664     bits -= bits % 16;
665     hv = hash_ipv6(&addr, bits);
666     break;
667     default: /* HM_HOST */
668     hv = get_mask_hash(address);
669     break;
670 adx 30 }
671 michael 1298
672 michael 4815 DLINK_FOREACH(node, atable[hv].head)
673 adx 30 {
674 michael 4815 struct AddressRec *arec = node->data;
675 michael 1367
676 michael 1632 if (arec->conf == conf)
677 adx 30 {
678 michael 1367 dlinkDelete(&arec->node, &atable[hv]);
679 michael 1298
680 michael 1644 if (!conf->ref_count)
681 michael 1632 conf_free(conf);
682 michael 1298
683 adx 30 MyFree(arec);
684     return;
685     }
686     }
687     }
688    
689     /* void clear_out_address_conf(void)
690     * Input: None
691     * Output: None
692     * Side effects: Clears out all address records in the hash table,
693 michael 1632 * frees them, and frees the MaskItems if nothing references
694 michael 2916 * them, otherwise sets them as illegal.
695 adx 30 */
696     void
697     clear_out_address_conf(void)
698     {
699 michael 4815 dlink_node *node = NULL, *node_next = NULL;
700 michael 2916
701 michael 3235 for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
702 adx 30 {
703 michael 4815 DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
704 adx 30 {
705 michael 4815 struct AddressRec *arec = node->data;
706 michael 1367
707 michael 1628 /*
708 michael 5846 * Destroy the ircd.conf items and keep those that are in the databases
709 michael 1628 */
710 michael 5846 if (IsConfDatabase(arec->conf))
711 michael 1628 continue;
712 michael 1622
713 michael 1628 dlinkDelete(&arec->node, &atable[i]);
714 michael 4523 arec->conf->active = 0;
715 michael 1298
716 michael 1644 if (!arec->conf->ref_count)
717 michael 1632 conf_free(arec->conf);
718 michael 1628 MyFree(arec);
719 adx 30 }
720     }
721     }
722    
723 michael 1369 static void
724 michael 4977 hostmask_send_expiration(const struct AddressRec *const arec)
725 michael 1369 {
726     char ban_type = '\0';
727    
728 michael 4340 if (!ConfigGeneral.tkline_expire_notices)
729 michael 1369 return;
730    
731     switch (arec->type)
732     {
733     case CONF_KLINE:
734     ban_type = 'K';
735     break;
736     case CONF_DLINE:
737     ban_type = 'D';
738     break;
739 michael 1644 default: break;
740 michael 1369 }
741 michael 2916
742 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
743 michael 1369 "Temporary %c-line for [%s@%s] expired", ban_type,
744 michael 1632 (arec->conf->user) ? arec->conf->user : "*",
745     (arec->conf->host) ? arec->conf->host : "*");
746 michael 1369 }
747    
748     void
749     hostmask_expire_temporary(void)
750     {
751 michael 4815 dlink_node *node = NULL, *node_next = NULL;
752 michael 1369
753 michael 3235 for (unsigned int i = 0; i < ATABLE_SIZE; ++i)
754 michael 1369 {
755 michael 4815 DLINK_FOREACH_SAFE(node, node_next, atable[i].head)
756 michael 1369 {
757 michael 4815 struct AddressRec *arec = node->data;
758 michael 1369
759 michael 1649 if (!arec->conf->until || arec->conf->until > CurrentTime)
760 michael 1369 continue;
761    
762     switch (arec->type)
763     {
764     case CONF_KLINE:
765     case CONF_DLINE:
766     hostmask_send_expiration(arec);
767    
768     dlinkDelete(&arec->node, &atable[i]);
769 michael 1632 conf_free(arec->conf);
770 michael 1369 MyFree(arec);
771     break;
772 michael 1644 default: break;
773 michael 1369 }
774     }
775     }
776     }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision