From: Marek VavruĊĦa Date: Mon, 8 Dec 2014 13:10:36 +0000 (+0100) Subject: zonecut: store zone cut info, allow empty root X-Git-Tag: v1.0.0-beta1~404 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc5168f8b164f6b0ab76d248639308ebd9efaffb;p=thirdparty%2Fknot-resolver.git zonecut: store zone cut info, allow empty root --- diff --git a/lib/delegpt.c b/lib/delegpt.c index 681908538..c9130f351 100644 --- a/lib/delegpt.c +++ b/lib/delegpt.c @@ -21,8 +21,9 @@ static void delegmap_clear(struct kr_delegmap *map) { hattrie_iter_t *i = hattrie_iter_begin(map->trie, false); while(!hattrie_iter_finished(i)) { - list_t *nslist = *hattrie_iter_val(i); - nslist_free(nslist, map->pool); + struct kr_zonecut *zonecut = *hattrie_iter_val(i); + nslist_free(&zonecut->nslist, map->pool); + mm_free(map->pool, zonecut->name); hattrie_iter_next(i); } hattrie_iter_free(i); @@ -35,10 +36,17 @@ int kr_delegmap_init(struct kr_delegmap *map, mm_ctx_t *mm) map->pool = mm; map->trie = hattrie_create_n(TRIE_BUCKET_SIZE, mm); if (map->trie == NULL) { - return -1; + return KNOT_ENOMEM; } - return 0; + /* Initialize root entry. */ + struct kr_zonecut *root = kr_delegmap_get(map, (const knot_dname_t*)"\0"); + if (root == NULL) { + hattrie_free(map->trie); + return KNOT_ENOMEM; + } + + return KNOT_EOK; } void kr_delegmap_deinit(struct kr_delegmap *map) @@ -47,30 +55,37 @@ void kr_delegmap_deinit(struct kr_delegmap *map) hattrie_free(map->trie); } -list_t *kr_delegmap_get(struct kr_delegmap *map, const knot_dname_t *name) +struct kr_zonecut *kr_delegmap_get(struct kr_delegmap *map, const knot_dname_t *name) { value_t *val = hattrie_get(map->trie, (const char *)name, knot_dname_size(name)); if (*val == NULL) { - *val = mm_alloc(map->pool, sizeof(list_t)); - if (*val == NULL) { + struct kr_zonecut *dp = mm_alloc(map->pool, sizeof(struct kr_zonecut)); + if (dp == NULL) { + return NULL; + } + + dp->name = knot_dname_copy(name, map->pool); + if (dp->name == NULL) { + mm_free(map->pool, dp); return NULL; } - init_list((list_t *)*val); + + init_list(&dp->nslist); + *val = dp; } return *val; } -list_t *kr_delegmap_find(struct kr_delegmap *map, const knot_dname_t *name) +struct kr_zonecut *kr_delegmap_find(struct kr_delegmap *map, const knot_dname_t *name) { value_t *val = NULL; while(val == NULL) { val = hattrie_tryget(map->trie, (const char *)name, knot_dname_size(name)); if (val == NULL || EMPTY_LIST(*((list_t *)*val))) { - /* No root delegation, failure. */ + /* Root delegation, may be empty. */ if (*name == '\0') { - assert(0); - return NULL; + return *val; } /* Look up parent. */ name = knot_wire_next_label(name, NULL); @@ -81,6 +96,15 @@ list_t *kr_delegmap_find(struct kr_delegmap *map, const knot_dname_t *name) return *val; } +struct kr_ns *kr_ns_first(list_t *list) +{ + if (EMPTY_LIST(*list)) { + return NULL; + } + + return HEAD(*list); +} + struct kr_ns *kr_ns_get(list_t *list, const knot_dname_t *name, mm_ctx_t *mm) { /* Check for duplicates. */ @@ -96,7 +120,6 @@ struct kr_ns *kr_ns_get(list_t *list, const knot_dname_t *name, mm_ctx_t *mm) memset(ns, 0, sizeof(struct kr_ns)); ns->name = knot_dname_copy(name, mm); - ns->flags = DP_LAME; add_tail(list, (node_t *)ns); @@ -115,24 +138,8 @@ struct kr_ns *kr_ns_find(list_t *list, const knot_dname_t *name) return NULL; } -void kr_ns_invalidate(struct kr_ns *ns) -{ - /* Slow start. */ - ns->flags = DP_LAME; - ns->stat.M = KR_CONN_RTT_MAX; - ns->stat.S = 0; - ns->stat.n = 1; - - /* Move to the end of the preference list. */ - node_t *next = ns->node.next; - if (next->next) { - rem_node(&ns->node); - insert_node(&ns->node, next); - } -} - -void kr_ns_remove(struct kr_ns *ns, mm_ctx_t *mm) +void kr_ns_del(list_t *list, struct kr_ns *ns, mm_ctx_t *mm) { - rem_node((node_t *)ns); + rem_node(&ns->node); ns_free(ns, mm); } diff --git a/lib/delegpt.h b/lib/delegpt.h index 35f97fde5..1a0e17c34 100644 --- a/lib/delegpt.h +++ b/lib/delegpt.h @@ -20,26 +20,21 @@ limitations under the License. #include #include -/*! \brief Name server flag. */ -enum kr_ns_flag { - DP_LAME = 0, - DP_PENDING = 1 << 0, - DP_RESOLVED = 1 << 1 -}; - struct kr_context; /*! \brief Name server. */ struct kr_ns { node_t node; knot_dname_t *name; - struct sockaddr_storage addr; - unsigned valid_until; struct { double M, S; /* Mean, Variance S/n */ unsigned n; } stat; - unsigned flags; +}; + +struct kr_zonecut { + list_t nslist; + knot_dname_t *name; }; struct kr_delegmap { @@ -49,16 +44,15 @@ struct kr_delegmap { int kr_delegmap_init(struct kr_delegmap *map, mm_ctx_t *mm); void kr_delegmap_deinit(struct kr_delegmap *map); -list_t *kr_delegmap_get(struct kr_delegmap *map, const knot_dname_t *name); -list_t *kr_delegmap_find(struct kr_delegmap *map, const knot_dname_t *name); +struct kr_zonecut *kr_delegmap_get(struct kr_delegmap *map, const knot_dname_t *name); +struct kr_zonecut *kr_delegmap_find(struct kr_delegmap *map, const knot_dname_t *name); /* TODO: find out how to do expire/refresh efficiently, maybe a sweep point and * evaluate only DPs with validity before or around the sweep point, then * choose next and move DPs from the other half for next sweep. */ +struct kr_ns *kr_ns_first(list_t *list); struct kr_ns *kr_ns_get(list_t *list, const knot_dname_t *name, mm_ctx_t *mm); struct kr_ns *kr_ns_find(list_t *list, const knot_dname_t *name); -void kr_ns_invalidate(struct kr_ns *ns); -void kr_ns_remove(struct kr_ns *ns, mm_ctx_t *mm); - +void kr_ns_del(list_t *list, struct kr_ns *ns, mm_ctx_t *mm);