X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/9451417624bf1da79af586c5fb1ba8c7047e620a..ddb996fc994eb24bd0b0632f4aff47817e3a8a40:/patricia/patricialib.c diff --git a/patricia/patricialib.c b/patricia/patricialib.c index 0752016c..86584c34 100644 --- a/patricia/patricialib.c +++ b/patricia/patricialib.c @@ -27,6 +27,18 @@ char patricia_copyright[] = #include "patricia.h" +//#define LEAK_DETECTION + +#ifdef LEAK_DETECTION +#define MAGIC 0x6a3b4ef3 + +struct fake_node { + patricia_node_t node; + uint32_t magic; + patricia_node_t *real_node; +}; +#endif + /* prefix_tochar * convert prefix information to bytes */ @@ -90,8 +102,8 @@ patricia_deref_prefix (prefix_t * prefix) prefix->ref_count--; if (prefix->ref_count <= 0) { - freeprefix(prefix); - return; + freeprefix(prefix); + return; } } @@ -374,7 +386,6 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) } new_node = patricia_new_node(patricia, prefix->bitlen, patricia_ref_prefix (prefix)); - if (node->bit == differ_bit) { new_node->parent = node; if (node->bit < patricia->maxbits && @@ -391,7 +402,7 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) if (bitlen == differ_bit) { if (bitlen < patricia->maxbits && - (is_bit_set(addr,bitlen))) { + (is_bit_set(test_addr,bitlen))) { new_node->r = node; } else { @@ -409,11 +420,11 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) node->parent->l = new_node; } node->parent = new_node; + new_node->usercount = node->usercount; } else { glue = patricia_new_node(patricia, differ_bit, NULL); glue->parent = node->parent; - if (differ_bit < patricia->maxbits && (is_bit_set(addr, differ_bit))) { glue->r = new_node; @@ -436,7 +447,9 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) node->parent->l = glue; } node->parent = glue; + glue->usercount = node->usercount; } + return (new_node); } @@ -530,6 +543,16 @@ patricia_remove (patricia_tree_t *patricia, patricia_node_t *node) } } +#ifdef LEAK_DETECTION +static patricia_node_t *getrealnode(patricia_node_t *node) { + struct fake_node *f = (struct fake_node *)node; + if(f->magic != MAGIC) { + printf("magic failure\n"); + abort(); + } + return f->real_node; +} +#endif patricia_node_t * refnode(patricia_tree_t *tree, struct irc_in_addr *sin, int bitlen) { @@ -546,6 +569,14 @@ refnode(patricia_tree_t *tree, struct irc_in_addr *sin, int bitlen) { patricia_ref_prefix(node->prefix); } +#ifdef LEAK_DETECTION + struct fake_node *f = malloc(sizeof(struct fake_node)); + f->magic = MAGIC; + f->node = *node; + f->real_node = node; + node = (patricia_node_t *)f; +#endif + return node; } @@ -554,6 +585,15 @@ derefnode(patricia_tree_t *tree, patricia_node_t *node) { if (!node || !node->prefix) return; +#ifdef LEAK_DETECTION + patricia_node_t *real_node = getrealnode(node); + free(node); + node = real_node; + + if (!node || !node->prefix) + return; +#endif + if (node->prefix->ref_count == 1) { patricia_remove(tree, node); } else @@ -572,3 +612,35 @@ patricia_node_t *patricia_new_node(patricia_tree_t *patricia, unsigned char bit, return new_node; } +void node_increment_usercount( patricia_node_t *node) { +#ifdef LEAK_DETECTION + node = getrealnode(node); +#endif + + while(node) { + node->usercount++; + node=node->parent; + } +} + +void node_decrement_usercount( patricia_node_t *node) { +#ifdef LEAK_DETECTION + node = getrealnode(node); +#endif + + while(node) { + node->usercount--; + node=node->parent; + } +} + +int is_normalized_ipmask( struct irc_in_addr *sin, unsigned char bitlen ) { + u_char *addr = (u_char *)sin; + + while (bitlen < PATRICIA_MAXBITS) { + if (is_bit_set(addr,bitlen)) + return 0; + bitlen++; + } + return 1; +}