diff options
Diffstat (limited to 'src/negcache.c')
-rw-r--r-- | src/negcache.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/negcache.c b/src/negcache.c new file mode 100644 index 0000000..070c503 --- /dev/null +++ b/src/negcache.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2002-2003 Andy Smith + * Copyright (c) 2014-2018 ircd-hybrid development team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +/* + * A Negative caching implementation for IPv4/IPv6 addresses. The idea is that + * every time an IP address is seen, it is checked against a patricia trie. If + * the IP address was previously seen and within an acceptable period of time, + * it is not scanned again. Otherwise, the address is scanned as normal. If + * it is proven to be OK (i.e. it doesn't run an open proxy) then it is added + * to the trie. + */ + +#include "setup.h" + +#include <time.h> + +#include "list.h" +#include "patricia.h" +#include "negcache.h" +#include "config.h" +#include "memory.h" +#include "log.h" + + +extern unsigned int OPT_DEBUG; + +static list_t negcache_list; +static patricia_tree_t *negcache_trie; + + +/* + * Initialise the patricia trie we use for storing our negative cache. + */ +void +negcache_init(void) +{ + if (negcache_trie) + return; /* Cache already exists */ + + negcache_trie = patricia_new(PATRICIA_MAXBITS); +} + +/* + * Check whether an IP address is in our negative cache and was added + * recently enough. Return a pointer to its node if so, NULL otherwise. + */ +struct negcache_item * +negcache_check(const char *ipstr) +{ + if (OptionsItem.negcache == 0) + return NULL; + + patricia_node_t *pnode = patricia_try_search_exact(negcache_trie, ipstr); + if (pnode) + { + struct negcache_item *n = pnode->data; + + if (time(NULL) - n->seen <= OptionsItem.negcache) + return n; + } + + return NULL; +} + +/* + * Prepare an ASCII string representing an IPv4/IPv6 address for inserting into + * our negative cache. + */ +void +negcache_insert(const char *ipstr) +{ + patricia_node_t *pnode = patricia_make_and_lookup(negcache_trie, ipstr); + if (pnode == NULL || pnode->data) + return; /* Malformed IP address or already added to the trie */ + + struct negcache_item *n = xcalloc(sizeof(*n)); + n->seen = time(NULL); + + pnode->data = n; + list_add(pnode, &n->node, &negcache_list); +} + +/* + * Wrapper for recursive rebuild function. + */ +void +negcache_rebuild(void) +{ + node_t *node, *node_next; + + LIST_FOREACH_SAFE(node, node_next, negcache_list.head) + { + patricia_node_t *pnode = node->data; + struct negcache_item *n = pnode->data; + + if (n->seen + OptionsItem.negcache < time(NULL)) + { + if (OPT_DEBUG >= 2) + log_printf("NEGCACHE -> Deleting expired negcache node for %s added at %lu", + patricia_prefix_toa(pnode->prefix, 0), n->seen); + + list_remove(&n->node, &negcache_list); + + xfree(n); + patricia_remove(negcache_trie, pnode); + } + } +} |