#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
*/
return (0);
}
+
prefix_t *
patricia_new_prefix (struct irc_in_addr *dest, int bitlen)
{
prefix->ref_count--;
if (prefix->ref_count <= 0) {
- freeprefix(prefix);
- return;
+ freeprefix(prefix);
+ return;
}
}
addr = (u_char *)sin;
while (node->bit < bitlen) {
- if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
+ if (is_bit_set(addr,node->bit))
node = node->r;
else
node = node->l;
return (NULL);
assert (node->bit == bitlen);
assert (node->bit == node->prefix->bitlen);
- if (comp_with_mask (prefix_tochar (node->prefix), addr, bitlen)) {
+ if (comp_with_mask (prefix_tochar (node->prefix), addr, bitlen)) {
return (node);
}
return (NULL);
stack[cnt++] = node;
}
- if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
+ if (is_bit_set(addr,node->bit)) {
node = node->r;
}
else {
while (node->bit < bitlen || node->prefix == NULL) {
/* check that we're not at the lowest leaf i.e. node->bit is less than max bits */
if (node->bit < patricia->maxbits &&
- (addr[node->bit >> 3]) & (0x80 >> (node->bit & 0x07))) {
+ (is_bit_set(addr,node->bit))) {
if (node->r == NULL)
break;
node = node->r;
continue;
}
/* I know the better way, but for now */
- for (j = 0; j < 8; j++) {
+ for (j = 0; j < 8; j++) {
if ((r) & ((0x80 >> j)))
break;
}
}
if (differ_bit == bitlen && node->bit == bitlen) {
- if (node->prefix) {
- return (node);
- }
- node->prefix = patricia_ref_prefix (prefix);
+ if (!node->prefix) {
+ node->prefix = patricia_ref_prefix (prefix);
+ }
return (node);
}
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 &&
- (addr[node->bit >> 3]) & (0x80 >> (node->bit & 0x07))) {
+ (is_bit_set(addr, node->bit))) {
assert (node->r == NULL);
node->r = new_node;
}
if (bitlen == differ_bit) {
if (bitlen < patricia->maxbits &&
- (test_addr[bitlen >> 3]) & (0x80 >> (bitlen & 0x07))) {
+ (is_bit_set(test_addr,bitlen))) {
new_node->r = node;
}
else {
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 &&
- (addr[differ_bit >> 3]) & (0x80 >> (differ_bit & 0x07))) {
+ (is_bit_set(addr, differ_bit))) {
glue->r = new_node;
glue->l = node;
}
node->parent->l = glue;
}
node->parent = glue;
+ glue->usercount = node->usercount;
}
+
return (new_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) {
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;
}
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
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;
+}