]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
added node purge functionality
authorYuri Schaeffer <yuri@nlnetlabs.nl>
Mon, 7 Oct 2013 15:11:53 +0000 (15:11 +0000)
committerYuri Schaeffer <yuri@nlnetlabs.nl>
Mon, 7 Oct 2013 15:11:53 +0000 (15:11 +0000)
ttl in tree

git-svn-id: file:///svn/unbound/branches/edns-subnet@2972 be551aaa-1e26-0410-a405-d3ace91eadb9

edns-subnet/addrtree.c
edns-subnet/addrtree.h
edns-subnet/subnetmod.c
testcode/unitvandergaast.c

index 103c0081482f2cca9c01cfaa3b1ea8dfa783fef9..46105cdc52296a624cf0635d0f8a0f280e701274 100644 (file)
@@ -24,18 +24,18 @@ static struct addredge*
 edge_create(struct addrnode* node, const addrkey_t* addr, addrlen_t addrlen)
 {
        size_t n;
-       struct addredge* edge = (struct addredge*)malloc( sizeof(*edge) );
+       struct addredge* edge = (struct addredge*)malloc( sizeof (*edge) );
        if (!edge)
                return NULL;
        edge->node = node;
        edge->len = addrlen;
        n = (size_t)((addrlen / KEYWIDTH) + ((addrlen % KEYWIDTH != 0)?1:0)); /*ceil()*/
-       edge->str = (addrkey_t*)calloc(n, sizeof(addrkey_t));
+       edge->str = (addrkey_t*)calloc(n, sizeof (addrkey_t));
        if (!edge->str) {
                free(edge);
                return NULL;
        }
-       memcpy(edge->str, addr, n * sizeof(addrkey_t));
+       memcpy(edge->str, addr, n * sizeof (addrkey_t));
        return edge;
 }
 
@@ -46,78 +46,99 @@ edge_create(struct addrnode* node, const addrkey_t* addr, addrlen_t addrlen)
  * @return new addrnode or NULL on failure
  */
 static struct addrnode* 
-node_create(struct reply_info* elem, addrlen_t scope)
+node_create(void* elem, addrlen_t scope, time_t ttl)
 {
-       struct addrnode* node = (struct addrnode*)malloc( sizeof(*node) );
+       struct addrnode* node = (struct addrnode*)malloc( sizeof (*node) );
        if (!node)
                return NULL;
        node->elem = elem;
        node->scope = scope;
+       node->ttl = ttl;
        node->edge[0] = NULL;
        node->edge[1] = NULL;
        return node;
 }
 
-struct addrtree* addrtree_create(addrlen_t max_depth, struct module_env* env)
+struct addrtree* addrtree_create(addrlen_t max_depth, 
+       void (*delfunc)(void *, void *), size_t (*sizefunc)(void *), void *env)
 {
        struct addrtree* tree;
-       log_assert(env != NULL);
-       tree = (struct addrtree*)malloc( sizeof(*tree) );
+       log_assert(delfunc != NULL);
+       log_assert(sizefunc != NULL);
+       tree = (struct addrtree*)malloc( sizeof (*tree) );
        if(!tree)
                return NULL;
-       tree->root = node_create(NULL, 0);
+       tree->root = node_create(NULL, 0, 0);
        if (!tree->root) {
                free(tree);
                return NULL;
        }
        tree->max_depth = max_depth;
+       tree->delfunc = delfunc;
+       tree->sizefunc = sizefunc;
        tree->env = env;
        return tree;
 }
 
 /**
- *  Recursively calculate size of tree from this node on downwards.
+ * Recursively calculate size of tree from this node on downwards.
  * */
-static size_t tree_size(const struct addrnode* node)
+static size_t tree_size(const struct addrtree* tree, 
+       const struct addrnode* node)
 {
-       int i;
-       size_t s = 0;
-       
-       if (!node) return s;
-       s += sizeof(struct addrnode);
-       if (node->elem) {
-               s += sizeof(struct reply_info) - sizeof(struct rrset_ref);
-               s += node->elem->rrset_count * sizeof(struct rrset_ref);
-               s += node->elem->rrset_count * sizeof(struct ub_packed_rrset_key*);
-       }
+       size_t s, i;
        
+       if (!node) return 0;
+       s = sizeof(struct addrnode);
+       if (node->elem && tree->sizefunc)
+               s += tree->sizefunc(node->elem);
        for (i = 0; i < 2; i++) {
                if (!node->edge[i]) continue;
-               s += sizeof(struct addredge);
-               s += (node->edge[i]->len / KEYWIDTH) + ((node->edge[i]->len % KEYWIDTH)!=0);
-               s += tree_size(node->edge[i]->node);
+               s += sizeof (struct addredge);
+               s += (node->edge[i]->len / KEYWIDTH);
+               s += (node->edge[i]->len % KEYWIDTH) != 0;
+               s += tree_size(tree, node->edge[i]->node);
        }
        return s;
 }
 
 size_t addrtree_size(const struct addrtree* tree)
 {
-       size_t s = 0;
-       if (tree) {
-               s += sizeof(struct addrtree);
-               s += tree_size(tree->root);
-       }
-       return s;
+       if (!tree) return 0;
+       return sizeof (struct addrtree) + tree_size(tree, tree->root);
 }
 
-void addrtree_clean_node(const struct addrtree* tree, struct addrnode* node)
+static void
+clean_node(const struct addrtree* tree, struct addrnode* node)
 {
-       if (node->elem) {
-               reply_info_delete(node->elem, NULL); //YBS niet NULL: regel 244
-               node->elem = NULL;
+       if (!node->elem) return;
+       tree->delfunc(tree->env, node->elem);
+       node->elem = NULL;
+}
+
+static void
+purge_node(const struct addrtree* tree, struct addrnode* node, 
+       struct addrnode* parentnode, struct addredge* parentedge)
+{
+       struct addredge *child_edge;
+       
+       int childcount = (node->edge[0] != NULL) + (node->edge[1] != NULL);
+       clean_node(tree, node);
+       if (childcount == 2 || !parentnode)
+               return;
+       log_assert(parentedge); /* parent node implies parent edge */
+       if (childcount == 1) {
+               child_edge = node->edge[0]?node->edge[0]:node->edge[1];
+               if (parentedge == parentnode->edge[0])
+                       parentnode->edge[0] = child_edge;
+               else
+                       parentnode->edge[1] = child_edge;
        }
+       free(parentedge->str);
+       free(parentedge);
 }
 
+
 /** 
  * Free node and all nodes below
  * @param tree: Tree the node lives in.
@@ -139,7 +160,7 @@ freenode_recursive(struct addrtree* tree, struct addrnode* node)
                }
                free(edge);
        }
-       addrtree_clean_node(tree, node);
+       clean_node(tree, node);
        free(node);
 }
 
@@ -149,11 +170,10 @@ freenode_recursive(struct addrtree* tree, struct addrnode* node)
  */
 void addrtree_delete(struct addrtree* tree)
 {
-       if (tree) {
-               if (tree->root)
-                       freenode_recursive(tree, tree->root);
-               free(tree);
-       }
+       if (!tree) return;
+       if (tree->root)
+               freenode_recursive(tree, tree->root);
+       free(tree);
 }
 
 /** Get N'th bit from address 
@@ -219,15 +239,14 @@ issub(const addrkey_t* s1, addrlen_t l1,
 
 void
 addrtree_insert(struct addrtree* tree, const addrkey_t* addr, 
-       addrlen_t sourcemask, addrlen_t scope, struct reply_info* elem)
+       addrlen_t sourcemask, addrlen_t scope, void* elem, time_t ttl)
 {
        /*TODO: 
-        * problem: code might delete elem so effectively owns elem.
-        * but fail is silent and elem may leak.
-        * plan return NULL or elem on insert to let caller decide.
-        * Also try again to make tree agnostic of elem type. We need a
-        * elem_size callback and clean_tree might have to  return a list
-        * of elem or require delete callback */
+        * check ttl of visited nodes.
+        * pass current time as arg
+        * 
+        * purge_node(tree, node, parent_node, edge);
+        */
        
        struct addrnode* newnode, *node;
        struct addredge* edge, *newedge;
@@ -249,8 +268,7 @@ addrtree_insert(struct addrtree* tree, const addrkey_t* addr,
                if (depth == sourcemask) {
                        /* update this node's scope and data */
                        if (node->elem)
-                               reply_info_parsedelete(node->elem, tree->env->alloc);
-                               //~ reply_info_parsedelete(node->elem, NULL);
+                               tree->delfunc(tree->env, node->elem);
                        node->elem = elem;
                        node->scope = scope;
                        return;
@@ -259,7 +277,7 @@ addrtree_insert(struct addrtree* tree, const addrkey_t* addr,
                edge = node->edge[index];
                /* Case 2: New leafnode */
                if (!edge) {
-                       newnode = node_create(elem, scope);
+                       newnode = node_create(elem, scope, ttl);
                        node->edge[index] = edge_create(newnode, addr, sourcemask);
                        if (!node->edge[index])
                                free(newnode);
@@ -277,7 +295,7 @@ addrtree_insert(struct addrtree* tree, const addrkey_t* addr,
                        continue;
                }
                /* Case 4: split. */
-               if (!(newnode = node_create(NULL, 0)))
+               if (!(newnode = node_create(NULL, 0, 0)))
                        return;
                if (!(newedge = edge_create(newnode, addr, common))) {
                        free(newnode);
@@ -291,10 +309,11 @@ addrtree_insert(struct addrtree* tree, const addrkey_t* addr,
                        /* Data is stored in the node */
                        newnode->elem = elem;
                        newnode->scope = scope;
+                       newnode->ttl = ttl;
                } else {
                        /* Data is stored in other leafnode */
                        node = newnode;
-                       newnode = node_create(elem, scope);
+                       newnode = node_create(elem, scope, ttl);
                        node->edge[index^1] = edge_create(newnode, addr, sourcemask);
                }
                return;
@@ -303,10 +322,10 @@ addrtree_insert(struct addrtree* tree, const addrkey_t* addr,
 
 struct addrnode*
 addrtree_find(const struct addrtree* tree, const addrkey_t* addr, 
-       addrlen_t sourcemask)
+       addrlen_t sourcemask, time_t now)
 {
-       struct addrnodenode = tree->root;
-       struct addredge* edge;
+       struct addrnode *parent_node = NULL, *node = tree->root;
+       struct addredge *edge = NULL;
        addrlen_t depth = 0;
 
        log_assert(node != NULL);
@@ -319,7 +338,9 @@ addrtree_find(const struct addrtree* tree, const addrkey_t* addr,
                        if (depth == node->scope ||
                                        (node->scope > sourcemask && depth == sourcemask)) {
                                /* Authority indicates it does not have a more precise
-                                * answer or we cannot ask a more specific question */
+                                * answer or we cannot ask a more specific question.
+                                * If expired don't clean up just now. */
+                               if (node->ttl < now) return NULL;
                                return node;
                        }
                }
@@ -335,8 +356,10 @@ addrtree_find(const struct addrtree* tree, const addrkey_t* addr,
                if (!issub(edge->str, edge->len, addr, sourcemask, depth))
                        return NULL;
                log_assert(depth < edge->len);
+               parent_node = node;
                depth = edge->len;
                node = edge->node;
+               
        }
 }
 
index 0f148c5a92c12e9e9bd36e3d949800308707966f..5133b7894f06b64ad800142313742650a79c2df3 100644 (file)
@@ -40,13 +40,17 @@ struct addrtree {
        struct addrnode* root;
        /** Maximum prefix length we are willing to cache. */
        addrlen_t max_depth;
-       struct module_env* env;
+       void (*delfunc)(void *, void *);
+       size_t (*sizefunc)(void *);
+       void *env;
        
 };
 
 struct addrnode {
        /** Payload of node, may be NULL */
        struct reply_info* elem;
+       /** Abs time in seconds in which elem is meaningful */
+       time_t ttl;
        /** Number of significant bits in address. */
        addrlen_t scope;
        /** A node can have 0-2 edges, set to NULL for unused */
@@ -73,7 +77,9 @@ size_t addrtree_size(const struct addrtree* tree);
  * @param env: Module environment for alloc information
  * @return new addrtree or NULL on failure
  */
-struct addrtree* addrtree_create(addrlen_t max_depth, struct module_env* env);
+struct addrtree* 
+addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *), 
+       size_t (*sizefunc)(void *), void *env);
 
 /** 
  * Free tree and all nodes below
@@ -81,13 +87,6 @@ struct addrtree* addrtree_create(addrlen_t max_depth, struct module_env* env);
  */
 void addrtree_delete(struct addrtree* tree);
 
-/** 
- * Free data stored at node
- * @param tree: Tree the node lives in.
- * @param node: Node to be scrubbed
- */
-void addrtree_clean_node(const struct addrtree* tree, struct addrnode* node);
-
 /**
  * Insert an element in the tree. Failures are silent. Sourcemask and
  * scope might be changed according to local policy.
@@ -99,7 +98,7 @@ void addrtree_clean_node(const struct addrtree* tree, struct addrnode* node);
  * @param elem: data to store in the tree
  */
 void addrtree_insert(struct addrtree* tree, const addrkey_t* addr, 
-       addrlen_t sourcemask, addrlen_t scope, struct reply_info* elem);
+       addrlen_t sourcemask, addrlen_t scope, void* elem, time_t ttl);
 
 /**
  * Find a node containing an element in the tree.
@@ -110,7 +109,7 @@ void addrtree_insert(struct addrtree* tree, const addrkey_t* addr,
  * @return addrnode or NULL on miss
  */
 struct addrnode* addrtree_find(const struct addrtree* tree, 
-       const addrkey_t* addr, addrlen_t sourcemask);
+       const addrkey_t* addr, addrlen_t sourcemask, time_t now);
 
 /** Wrappers for static functions to unit test */
 int unittest_wrapper_addrtree_cmpbit(const addrkey_t* key1, 
index e12dbfbb2dc16d0724e58a67428d79df5232cda7..5b6dd48eb208633031dfc3884c9115b1c78a7c84 100644 (file)
@@ -29,9 +29,9 @@
 
 /** externally called */
 void 
-subnet_data_delete(void* d, void* ATTR_UNUSED(arg))
+subnet_data_delete(void *d, void *ATTR_UNUSED(arg))
 {
-       struct subnet_msg_cache_datar;
+       struct subnet_msg_cache_data *r;
        r = (struct subnet_msg_cache_data*)d;
        addrtree_delete(r->tree4);
        addrtree_delete(r->tree6);
@@ -40,10 +40,10 @@ subnet_data_delete(void* d, void* ATTR_UNUSED(arg))
 
 /** externally called */
 size_t 
-msg_cache_sizefunc(void* k, void* d)
+msg_cache_sizefunc(void *k, void *d)
 {
-       struct msgreply_entryq = (struct msgreply_entry*)k;
-       struct subnet_msg_cache_datar = (struct subnet_msg_cache_data*)d;
+       struct msgreply_entry *q = (struct msgreply_entry*)k;
+       struct subnet_msg_cache_data *r = (struct subnet_msg_cache_data*)d;
        size_t s = sizeof(struct msgreply_entry) 
                + sizeof(struct subnet_msg_cache_data)
                + q->key.qname_len + lock_get_mem(&q->entry.lock);
@@ -54,9 +54,9 @@ msg_cache_sizefunc(void* k, void* d)
 
 /** new query for sn */
 static int
-subnet_new_qstate(struct module_qstateqstate, int id)
+subnet_new_qstate(struct module_qstate *qstate, int id)
 {
-       struct subnet_qstateiq = (struct subnet_qstate*)regional_alloc(
+       struct subnet_qstate *iq = (struct subnet_qstate*)regional_alloc(
                qstate->region, sizeof(struct subnet_qstate));
        qstate->minfo[id] = iq;
        if(!iq) 
@@ -65,9 +65,9 @@ subnet_new_qstate(struct module_qstate* qstate, int id)
        return 1;
 }
 
-int subnetmod_init(struct module_envenv, int id)
+int subnetmod_init(struct module_env *env, int id)
 {
-       struct subnet_envsn_env = (struct subnet_env*)calloc(1,
+       struct subnet_env *sn_env = (struct subnet_env*)calloc(1,
                sizeof(struct subnet_env));
        if(!sn_env) {
                log_err("malloc failure");
@@ -86,9 +86,9 @@ int subnetmod_init(struct module_env* env, int id)
        return 1;
 }
 
-void subnetmod_deinit(struct module_envenv, int id)
+void subnetmod_deinit(struct module_env *env, int id)
 {
-       struct subnet_envsn_env;
+       struct subnet_env *sn_env;
        if(!env || !env->modinfo[id])
                return;
        sn_env = (struct subnet_env*)env->modinfo[id];
@@ -98,52 +98,64 @@ void subnetmod_deinit(struct module_env* env, int id)
 }
 
 /** Tells client that upstream has no/improper support */
-void cp_edns_bad_response(struct edns_data* target, struct edns_data* source)
+void cp_edns_bad_response(struct edns_data *target, struct edns_data *source)
 {
        target->subnet_scope_mask  = 0;
        target->subnet_source_mask = source->subnet_source_mask;
        target->subnet_addr_fam    = source->subnet_addr_fam;
-       memcpy(target->subnet_addr,  source->subnet_addr, INET6_SIZE);
+       memcpy(target->subnet_addr, source->subnet_addr, INET6_SIZE);
        target->subnet_validdata = 1;
 }
 
+static void delfunc(void *envptr, void *elemptr) {
+       struct reply_info *elem = (struct reply_info *)elemptr;
+       struct module_env *env = (struct module_env *)envptr;
+       reply_info_parsedelete(elem, env->alloc);
+}
+
+static size_t sizefunc(void *elemptr) {
+       struct reply_info *elem  = (struct reply_info *)elemptr;
+       return sizeof (struct reply_info) - sizeof (struct rrset_ref)
+               + elem->rrset_count * sizeof (struct rrset_ref)
+               + elem->rrset_count * sizeof (struct ub_packed_rrset_key *);
+}
 
 /* select tree from cache entry based on edns data.
  * If for address family not present it will create a new one.
  * NULL on failure to create. */
 static struct addrtree* 
-get_tree(struct subnet_msg_cache_data* data, struct edns_data* edns, 
-       struct module_envenv)
+get_tree(struct subnet_msg_cache_data *data, struct edns_data *edns, 
+       struct module_env *env)
 {
-       struct addrtreetree;
+       struct addrtree *tree;
        if (edns->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
                if (!data->tree4)
-                       data->tree4 = addrtree_create(EDNSSUBNET_MAX_SUBNET_IP4, env);
+                       data->tree4 = addrtree_create(EDNSSUBNET_MAX_SUBNET_IP4, &delfunc, &sizefunc, env);
                tree = data->tree4;
        } else {
                if (!data->tree6)
-                       data->tree6 = addrtree_create(EDNSSUBNET_MAX_SUBNET_IP6, env);
+                       data->tree6 = addrtree_create(EDNSSUBNET_MAX_SUBNET_IP6, &delfunc, &sizefunc, env);
                tree = data->tree6;
        }
        return tree;
 }
 
-void update_cache(struct module_qstateqstate, int id)
+void update_cache(struct module_qstate *qstate, int id)
 {
-       struct msgreply_entrymrep_entry;
-       struct addrtreetree;
+       struct msgreply_entry *mrep_entry;
+       struct addrtree *tree;
        struct reply_info *rep;
        struct query_info qinf;
-       struct slabhashsubnet_msg_cache = 
+       struct slabhash *subnet_msg_cache = 
                ((struct subnet_env*)qstate->env->modinfo[id])->subnet_msg_cache;
-       struct edns_dataedns = &qstate->edns_client_in;
+       struct edns_data *edns = &qstate->edns_client_in;
        
        /** We already calculated hash upon lookup */
        hashvalue_t h = qstate->minfo[id] ? 
                ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash : 
                query_info_hash(&qstate->qinfo);
        /** Step 1, general qinfo lookup */
-       struct lruhash_entrylru_entry = slabhash_lookup(subnet_msg_cache, h, &qstate->qinfo, 1);
+       struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h, &qstate->qinfo, 1);
        int acquired_lock = (lru_entry != NULL);
        if (!lru_entry) {
                qinf = qstate->qinfo;
@@ -177,24 +189,24 @@ void update_cache(struct module_qstate* qstate, int id)
        rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache   */
        addrtree_insert(tree, (addrkey_t*)edns->subnet_addr, 
                edns->subnet_source_mask, 
-               qstate->edns_server_in.subnet_scope_mask, rep);
+               qstate->edns_server_in.subnet_scope_mask, rep, rep->ttl);
        if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
 }
 
 
 /* return true iff reply is sent. */
-int lookup_and_reply(struct module_qstateqstate, int id)
+int lookup_and_reply(struct module_qstate *qstate, int id)
 {
-       struct lruhash_entrye;
-       struct module_envenv = qstate->env;
-       struct subnet_envsne = (struct subnet_env*)env->modinfo[id];
-       struct subnet_qstateiq = (struct subnet_qstate*)qstate->minfo[id];
+       struct lruhash_entry *e;
+       struct module_env *env = qstate->env;
+       struct subnet_env *sne = (struct subnet_env*)env->modinfo[id];
+       struct subnet_qstate *iq = (struct subnet_qstate*)qstate->minfo[id];
        hashvalue_t h = query_info_hash(&qstate->qinfo);
-       struct subnet_msg_cache_datadata;
-       struct edns_dataedns = &qstate->edns_client_in;
-       struct addrtreetree;
-       struct addrnodenode;
-       struct reply_inforep;
+       struct subnet_msg_cache_data *data;
+       struct edns_data *edns = &qstate->edns_client_in;
+       struct addrtree *tree;
+       struct addrnode *node;
+       struct reply_info *rep;
        
        if (iq) iq->qinfo_hash = h; /** Might be useful on cache miss */
        e = slabhash_lookup(sne->subnet_msg_cache, h, &qstate->qinfo, 0);
@@ -207,18 +219,13 @@ int lookup_and_reply(struct module_qstate* qstate, int id)
                return 0;
        }
        node = addrtree_find(tree, (addrkey_t*)edns->subnet_addr, 
-               edns->subnet_source_mask);
+               edns->subnet_source_mask, *env->now);
        if (!node) { /** plain old cache miss */
                lock_rw_unlock(&e->lock);
                return 0;
        }
        rep = node->elem;
-       if(rep->ttl < *env->now) { /** msg expired, remove from node */
-               addrtree_clean_node(tree, node);
-               lock_rw_unlock(&e->lock);
-               return 0;
-       }
-       rep = reply_info_copy(rep, env->alloc, NULL);
+       rep = reply_info_copy(rep, env->alloc, qstate->region);
        lock_rw_unlock(&e->lock);
        qstate->return_msg = (struct dns_msg*)regional_alloc(
                qstate->region, sizeof(struct dns_msg));
@@ -248,7 +255,7 @@ common_prefix(uint8_t *a, uint8_t *b, uint8_t net)
        return !memcmp(a, b, n) && ((net % 8) == 0 || a[n] == b[n]);
 }
 
-enum module_ext_state eval_response(struct module_qstateqstate, int id)
+enum module_ext_state eval_response(struct module_qstate *qstate, int id)
 {
        size_t sn_octs;
        struct edns_data *c_in  = &qstate->edns_client_in; /* rcvd from client */
@@ -307,8 +314,8 @@ enum module_ext_state eval_response(struct module_qstate* qstate, int id)
        return module_finished;
 }
 
-void subnetmod_operate(struct module_qstateqstate, enum module_ev event, 
-       int id, struct outbound_entryATTR_UNUSED(outbound))
+void subnetmod_operate(struct module_qstate *qstate, enum module_ev event, 
+       int id, struct outbound_entry *ATTR_UNUSED(outbound))
 {
        verbose(VERB_QUERY, "subnet[module %d] operate: extstate:%s "
                "event:%s", id, strextstate(qstate->ext_state[id]), 
@@ -361,18 +368,18 @@ void subnetmod_operate(struct module_qstate* qstate, enum module_ev event,
        return;
 }
 
-void subnetmod_clear(struct module_qstateqstate, int id)
+void subnetmod_clear(struct module_qstate *qstate, int id)
 {
        /* qstate has no data outside region */
 }
 
-void subnetmod_inform_super(struct module_qstateqstate, int id, 
-       struct module_qstatesuper)
+void subnetmod_inform_super(struct module_qstate *qstate, int id, 
+       struct module_qstate *super)
 {
        /* Not used */
 }
 
-size_t subnetmod_get_mem(struct module_envenv, int id)
+size_t subnetmod_get_mem(struct module_env *env, int id)
 {
        verbose(VERB_ALGO, "subnetmod: get_mem, id: %d, NOTIMPL", id);
        return 550;
@@ -386,7 +393,7 @@ static struct module_func_block subnetmod_block = {
        &subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
 };
 
-struct module_func_blocksubnetmod_get_funcblock(void)
+struct module_func_block *subnetmod_get_funcblock(void)
 {
        return &subnetmod_block;
 }
index aca2271d15226355d3c49f062bc7ef62eba511f1..ff408ea0b6c2e6d86eb8ced7bf1e061de27fc90b 100644 (file)
@@ -138,6 +138,13 @@ static int randomkey(addrkey_t **k, int maxlen)
        return bits;
 }
 
+static void elemfree(void *envptr, void *elemptr)
+{
+       struct reply_info *elem = (struct reply_info *)elemptr;
+       struct module_env *env = (struct module_env *)envptr;
+       free(elem);
+}
+
 static void consistency_test(void)
 {
        int i, l, r;
@@ -145,16 +152,16 @@ static void consistency_test(void)
        struct addrtree* t;
        struct module_env env;
        struct reply_info *elem;
+       time_t timenow = 0;
        unit_show_func("edns-subnet/addrtree.h", "Tree consistency check");
        srand(9195); /* just some value for reproducibility */
 
-       env.alloc = NULL;
-       t = addrtree_create(100, &env);
+       t = addrtree_create(100, &elemfree, NULL, &env);
 
        for (i = 0; i < 1000; i++) {
                l = randomkey(&k, 128);
                elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
-               addrtree_insert(t, k, l, 64, elem);
+               addrtree_insert(t, k, l, 64, elem, timenow + 10);
                free(k);
                unit_assert( !addrtree_inconsistent(t) );
        }