]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/nsrep: force resolution with given NS address
authorMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 28 Oct 2015 15:31:34 +0000 (16:31 +0100)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 28 Oct 2015 15:31:34 +0000 (16:31 +0100)
daemon/lua/kres.lua
lib/nsrep.c
lib/nsrep.h
lib/utils.c

index dd9dc07e0ae202b8d0f2a0369f41cba0fba74789..97e43e48c98f896095485c94a6d0cf90cb6fbbe9 100644 (file)
@@ -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
index 9d288cc822df852d41b2cff34ba10a6cb870c69e..9ba7a3a38a65097bba9abcffad5379c84b368660 100644 (file)
 } 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; \
index b6fd6fde41ecfe3a4df06a04c3c5132d21420249..f733074852d06aeb26726b647133c8f354bd6c7b 100644 (file)
@@ -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
index a10ca31d88f76c56a9b97a37c03ffc5fb4aa1790..5b8061ab7eb0472ab72d29a1d039b5cf7b666be0 100644 (file)
@@ -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)