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);
},
})
-- 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 = {
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
} 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;
}
}
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);
+ }
}
}
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; \
#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