Commit 1454cc16 authored by Marek Vavruša's avatar Marek Vavruša

lib/nsrep: force resolution with given NS address

parent 1882ec27
......@@ -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
......
......@@ -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; \
......
......@@ -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
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment