From: Marek VavruĊĦa Date: Fri, 8 Aug 2014 11:49:19 +0000 (+0200) Subject: context: root hints, slist bugfixes and sorting X-Git-Tag: v1.0.0-beta1~437 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a8f0874fbe4eeefd83123d621b8f839b91e6903;p=thirdparty%2Fknot-resolver.git context: root hints, slist bugfixes and sorting --- diff --git a/lib/context.c b/lib/context.c index b6b429325..8f64da2f2 100644 --- a/lib/context.c +++ b/lib/context.c @@ -4,9 +4,53 @@ #include #include "context.h" +/* \brief Root hint descriptor. */ +struct hint_info { + const char *name; + const char *addr; + const char *zone; +}; + +/* Initialize with SBELT name servers. */ +#define HINT_COUNT 13 +static const struct hint_info SBELT[HINT_COUNT] = { + { "a.root-servers.net.", "198.41.0.4", "." }, + { "b.root-servers.net.", "192.228.79.201", "." }, + { "c.root-servers.net.", "192.33.4.12", "." }, + { "d.root-servers.net.", "199.7.91.13", "." }, + { "e.root-servers.net.", "192.203.230.10", "." }, + { "f.root-servers.net.", "192.5.5.241", "." }, + { "g.root-servers.net.", "192.112.36.4", "." }, + { "h.root-servers.net.", "128.63.2.53", "." }, + { "i.root-servers.net.", "192.36.148.17", "." }, + { "j.root-servers.net.", "192.58.128.30", "." }, + { "k.root-servers.net.", "193.0.14.129", "." }, + { "l.root-servers.net.", "199.7.83.42", "." }, + { "m.root-servers.net.", "202.12.27.33", "." } +}; + +/* TODO: debug, remove */ +#ifndef NDEBUG +static void print_slist(struct kr_context *ctx) +{ + char *sname = knot_dname_to_str(ctx->sname); + printf("SLIST(%s): \n", sname); + free(sname); + struct kr_ns *ns = NULL; + WALK_LIST(ns, ctx->slist) { + char *strname = knot_dname_to_str(ns->name); + char addr_str[SOCKADDR_STRLEN]; + sockaddr_tostr(&ns->addr, addr_str, sizeof(addr_str)); + printf("[%d] %s:%s ", ns->closeness, strname, addr_str); + free(strname); + } + printf("\n"); +} +#endif + /*! \brief Initialize NS descriptor. */ static struct kr_ns *init_ns(mm_ctx_t *mm, const knot_dname_t *name, - const struct sockaddr *addr, unsigned closeness) + const struct sockaddr *addr) { struct kr_ns *ns = mm_alloc(mm, sizeof(struct kr_ns)); if (ns == NULL) { @@ -21,22 +65,48 @@ static struct kr_ns *init_ns(mm_ctx_t *mm, const knot_dname_t *name, } memcpy(&ns->addr, addr, sockaddr_len(addr)); - ns->closeness = closeness; return ns; } -/*! \brief Insert NS before an item. */ -static void insert_ns(struct kr_ns *cur, struct kr_ns *inserted) +/*! \brief Insert before an item. */ +static void insert_before(struct kr_ns *cur, struct kr_ns *inserted) { insert_node((node_t *)inserted, (node_t *)cur); rem_node((node_t *)cur); insert_node((node_t *)cur, (node_t *)inserted); } +/*! \brief Calculate closeness (# of common labels with sname). */ +static unsigned closeness_score(const knot_dname_t *sname, const knot_dname_t *zone) +{ + /* Longer or non-equal names of the same length can't contain delegations. */ + if (sname && (knot_dname_is_sub(sname, zone) || knot_dname_is_equal(zone, sname))) { + return KNOT_DNAME_MAXLABELS - knot_dname_matched_labels(zone, sname); + } + + return KNOT_DNAME_MAXLABELS + 1; /* N/A */ +} + +/* \brief (Re)insert name server to SLIST. */ +static void insert_ns(struct kr_context *ctx, struct kr_ns *ns) +{ + struct kr_ns *it = NULL; + WALK_LIST(it, ctx->slist) { + if (it->closeness > ns->closeness) { + insert_before(it, ns); + return; + } + } + + /* No closer match found. */ + add_tail(&ctx->slist, (node_t *)ns); +} + /*! \brief Remove NS descriptor. */ static void remove_ns(mm_ctx_t *mm, struct kr_ns *ns) { + rem_node((node_t *)ns); mm_free(mm, ns->name); mm_free(mm, ns); } @@ -45,13 +115,23 @@ int kr_context_init(struct kr_context *ctx, mm_ctx_t *mm) { memset(ctx, 0, sizeof(struct kr_context)); - ctx->mm = mm; + ctx->pool = mm; init_list(&ctx->slist); + kr_context_reset(ctx); return 0; } -int kr_context_close(struct kr_context *ctx) +int kr_context_reset(struct kr_context *ctx) +{ + while(kr_slist_pop(ctx) == 0); + + kr_slist_init(ctx); + + return 0; +} + +int kr_context_deinit(struct kr_context *ctx) { /* TODO: free slist, pending queries. */ return -1; @@ -61,7 +141,7 @@ int kr_result_init(struct kr_context *ctx, struct kr_result *result) { memset(result, 0, sizeof(struct kr_result)); - knot_pkt_t *ans = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, ctx->mm); + knot_pkt_t *ans = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, ctx->pool); if (ans == NULL) { return -1; } @@ -71,39 +151,41 @@ int kr_result_init(struct kr_context *ctx, struct kr_result *result) knot_wire_set_qr(ans->wire); result->ans = ans; - result->cname = ctx->sname; gettimeofday(&result->t_start, NULL); return 0; } -int kr_result_clear(struct kr_result *result) +int kr_result_deinit(struct kr_result *result) { knot_pkt_free(&result->ans); return 0; } -int kr_slist_add(struct kr_context *ctx, const knot_dname_t *name, const struct sockaddr *addr) +int kr_slist_init(struct kr_context *ctx) { - /* Closeness is represented by a number of common labels. */ - int closeness = knot_dname_matched_labels(name, ctx->sname); + int ret = 0; + struct sockaddr_storage ss; + for (unsigned i = 0; i < HINT_COUNT; ++i) { + ret = sockaddr_set(&ss, AF_INET, SBELT[i].addr, 53); + assert(ret == 0); + kr_slist_add(ctx, knot_dname_from_str(SBELT[i].zone), + (struct sockaddr *)&ss); + } + + return 0; +} - struct kr_ns *ns = init_ns(ctx->mm, name, addr, closeness); +int kr_slist_add(struct kr_context *ctx, const knot_dname_t *name, const struct sockaddr *addr) +{ + struct kr_ns *ns = init_ns(ctx->pool, name, addr); if (ns == NULL) { return -1; } - struct kr_ns *iter = NULL; - WALK_LIST(iter, ctx->slist) { - if (iter->closeness < closeness) { - insert_ns(iter, ns); - return 0; - } - } + insert_ns(ctx, ns); - /* No closer match found. */ - add_tail(&ctx->slist, (node_t *)ns); return 0; } @@ -116,14 +198,29 @@ struct kr_ns *kr_slist_top(struct kr_context *ctx) return (struct kr_ns *)HEAD(ctx->slist); } +int kr_slist_sort(struct kr_context *ctx) +{ + list_t copy = ctx->slist; + init_list(&ctx->slist); + + /* Recalculate closeness and reinsert. */ + struct kr_ns *it = NULL, *next = NULL; + WALK_LIST_DELSAFE(it, next, copy) { + it->closeness = closeness_score(ctx->sname, it->name); + insert_ns(ctx, it); + } + + return 0; +} + int kr_slist_pop(struct kr_context *ctx) { struct kr_ns *top = kr_slist_top(ctx); - if (top) { + if (top == NULL) { return -1; } - rem_node((node_t *)top); - remove_ns(ctx->mm, top); + remove_ns(ctx->pool, top); + return 0; } diff --git a/lib/context.h b/lib/context.h index 40571805a..7416dd9b3 100644 --- a/lib/context.h +++ b/lib/context.h @@ -49,17 +49,20 @@ struct kr_context uint16_t sclass; uint16_t next_id; list_t slist; - mm_ctx_t *mm; + mm_ctx_t *pool; unsigned state; unsigned options; }; int kr_context_init(struct kr_context *ctx, mm_ctx_t *mm); -int kr_context_close(struct kr_context *ctx); +int kr_context_reset(struct kr_context *ctx); +int kr_context_deinit(struct kr_context *ctx); int kr_result_init(struct kr_context *ctx, struct kr_result *result); -int kr_result_clear(struct kr_result *result); +int kr_result_deinit(struct kr_result *result); +int kr_slist_init(struct kr_context *ctx); int kr_slist_add(struct kr_context *ctx, const knot_dname_t *name, const struct sockaddr *addr); struct kr_ns *kr_slist_top(struct kr_context *ctx); +int kr_slist_sort(struct kr_context *ctx); int kr_slist_pop(struct kr_context *ctx); \ No newline at end of file