]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
zonecut: store zone cut info, allow empty root
authorMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 8 Dec 2014 13:10:36 +0000 (14:10 +0100)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 8 Dec 2014 13:10:36 +0000 (14:10 +0100)
lib/delegpt.c
lib/delegpt.h

index 681908538fed0104462dc1098684d6645d54c46e..c9130f351a7854eacaa0373525d6103c90cf0302 100644 (file)
@@ -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);
 }
index 35f97fde529df846b424bc3a9be66b86550a5af3..1a0e17c34617a3456ae40f0d7c1a45aeccb880c7 100644 (file)
@@ -20,26 +20,21 @@ limitations under the License.
 #include <libknot/internal/sockaddr.h>
 #include <libknot/internal/trie/hat-trie.h>
 
-/*! \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);