From: Marek VavruĊĦa Date: Wed, 28 Oct 2015 15:31:34 +0000 (+0100) Subject: lib/nsrep: force resolution with given NS address X-Git-Tag: v1.0.0-beta2~29^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1454cc162f8e261f0bc1f57573eb00866da67fc4;p=thirdparty%2Fknot-resolver.git lib/nsrep: force resolution with given NS address --- diff --git a/daemon/lua/kres.lua b/daemon/lua/kres.lua index dd9dc07e0..97e43e48c 100644 --- a/daemon/lua/kres.lua +++ b/daemon/lua/kres.lua @@ -242,6 +242,8 @@ struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent, const knot_dname_t *name, uint16_t cls, uint16_t type); struct kr_query *kr_rplan_resolved(struct kr_rplan *rplan); struct kr_query *kr_rplan_next(struct kr_query *qry); +/* Nameservers */ +int kr_nsrep_set(struct kr_query *qry, uint8_t *addr, size_t addr_len); /* Query */ /* Utils */ unsigned kr_rand_uint(unsigned max); @@ -331,6 +333,7 @@ ffi.metatype( knot_pkt_t, { }, }) -- Metatype for query +local ub_t = ffi.typeof('unsigned char *') local kr_query_t = ffi.typeof('struct kr_query') ffi.metatype( kr_query_t, { __index = { @@ -345,6 +348,10 @@ ffi.metatype( kr_query_t, { final = function(qry) return qry:resolved() and (qry.parent == nil) end, + nslist = function(qry, ns) + if ns ~= nil then C.kr_nsrep_set(qry, ffi.cast(ub_t, ns), #ns) end + -- @todo: Return list of NS entries, not possible ATM because the NSLIST is union and missing typedef + end, }, }) -- Metatype for request diff --git a/lib/nsrep.c b/lib/nsrep.c index 9d288cc82..9ba7a3a38 100644 --- a/lib/nsrep.c +++ b/lib/nsrep.c @@ -37,20 +37,18 @@ } while (0) /** Update nameserver representation with current name/address pair. */ -static void update_nsrep(struct kr_nsrep *ns, uint8_t *addr, size_t pos) +static void update_nsrep(struct kr_nsrep *ns, size_t pos, uint8_t *addr, size_t addr_len) { if (addr == NULL) { ns->addr[pos].ip.sa_family = AF_UNSPEC; return; } - size_t len = pack_obj_len(addr); - void *addr_val = pack_obj_val(addr); - switch(len) { + switch(addr_len) { case sizeof(struct in_addr): - ADDR_SET(ns->addr[pos].ip4.sin, AF_INET, addr_val, len); break; + ADDR_SET(ns->addr[pos].ip4.sin, AF_INET, addr, addr_len); break; case sizeof(struct in6_addr): - ADDR_SET(ns->addr[pos].ip6.sin6, AF_INET6, addr_val, len); break; + ADDR_SET(ns->addr[pos].ip6.sin6, AF_INET6, addr, addr_len); break; default: assert(0); break; } } @@ -60,7 +58,13 @@ static void update_nsrep_set(struct kr_nsrep *ns, const knot_dname_t *name, uint ns->name = name; ns->score = score; for (size_t i = 0; i < KR_NSREP_MAXADDR; ++i) { - update_nsrep(ns, addr[i], i); + if (addr[i]) { + void *addr_val = pack_obj_val(addr[i]); + size_t len = pack_obj_len(addr[i]); + update_nsrep(ns, i, addr_val, len); + } else { + update_nsrep(ns, i, NULL, 0); + } } } @@ -157,6 +161,19 @@ static int eval_nsrep(const char *k, void *v, void *baton) return kr_ok(); } +int kr_nsrep_set(struct kr_query *qry, uint8_t *addr, size_t addr_len) +{ + if (!qry || !addr) { + return kr_error(EINVAL); + } + qry->ns.name = (const uint8_t *)""; + qry->ns.score = KR_NS_UNKNOWN; + qry->ns.reputation = 0; + update_nsrep(&qry->ns, 0, addr, addr_len); + update_nsrep(&qry->ns, 1, NULL, 0); + return kr_ok(); +} + #define ELECT_INIT(ns, ctx_) do { \ (ns)->ctx = (ctx_); \ (ns)->addr[0].ip.sa_family = AF_UNSPEC; \ diff --git a/lib/nsrep.h b/lib/nsrep.h index b6fd6fde4..f73307485 100644 --- a/lib/nsrep.h +++ b/lib/nsrep.h @@ -80,6 +80,15 @@ struct kr_nsrep #define kr_nsrep_inaddr_len(addr) \ ((addr).ip.sa_family == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr)) +/** + * Set given NS address. + * @param qry updated query + * @param addr address bytes (struct in_addr or struct in6_addr) + * @param addr_len address bytes length (type will be derived from this) + * @return 0 or an error code + */ +int kr_nsrep_set(struct kr_query *qry, uint8_t *addr, size_t addr_len); + /** * Elect best nameserver/address pair from the nsset. * @param qry updated query diff --git a/lib/utils.c b/lib/utils.c index a10ca31d8..5b8061ab7 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -217,7 +217,11 @@ int kr_straddr_family(const char *addr) int kr_family_len(int family) { - return (family == AF_INET) ? sizeof(struct in_addr) : sizeof(struct in6_addr); + switch (family) { + case AF_INET: return sizeof(struct in_addr); + case AF_INET6: return sizeof(struct in6_addr); + default: return kr_error(EINVAL); + } } int kr_straddr_subnet(void *dst, const char *addr)