local ffi = require('ffi')
local bit = require('bit')
-local csym = ffi.C
+local bor = bit.bor
+local band = bit.band
+local C = ffi.C
local knot = ffi.load('knot')
ffi.cdef[[
* Data structures
*/
+/* stdlib */
+struct sockaddr {
+ uint16_t sa_family;
+ uint8_t _stub[]; /* Do not touch */
+};
+
/* libknot */
typedef struct node {
struct node *next, *prev;
} node_t;
typedef uint8_t knot_dname_t;
+typedef struct knot_rdataset {
+ uint16_t count;
+ uint8_t *data;
+} knot_rdataset_t;
+typedef struct knot_rrset {
+ knot_dname_t *_owner;
+ uint16_t type;
+ uint16_t class;
+ knot_rdataset_t rr;
+} knot_rrset_t;
typedef struct {
uint8_t *wire;
size_t size;
uint16_t qname_size;
uint16_t rrset_count;
uint16_t flags;
+ knot_rrset_t *opt;
+ knot_rrset_t *tsig;
uint8_t _stub[]; /* Do not touch */
} knot_pkt_t;
struct kr_request {
struct kr_context *_ctx;
knot_pkt_t *answer;
+ struct {
+ const knot_rrset_t *key;
+ const struct sockaddr *addr;
+ } qsource;
uint32_t options;
int state;
uint8_t _stub[]; /* Do not touch */
unsigned kr_rand_uint(unsigned max);
int kr_pkt_put(knot_pkt_t *pkt, const knot_dname_t *name, uint32_t ttl,
uint16_t rclass, uint16_t rtype, const uint8_t *rdata, uint16_t rdlen);
+const char *kr_inaddr(const struct sockaddr *addr);
+int kr_inaddr_len(const struct sockaddr *addr);
]]
+-- Metatype for sockaddr
+local sockaddr_t = ffi.typeof('struct sockaddr')
+ffi.metatype( sockaddr_t, {
+ __index = {
+ len = function(sa) return C.kr_inaddr_len(sa) end,
+ addr = function (sa) return ffi.string(C.kr_inaddr(sa), C.kr_inaddr_len(sa)) end,
+ }
+})
+
+-- Metatype for RR set
+local knot_rrset_t = ffi.typeof('knot_rrset_t')
+ffi.metatype( knot_rrset_t, {
+ __index = {
+ owner = function(rr) return ffi.string(rr._owner) end,
+ }
+})
+
-- Metatype for packet
-local bor = bit.bor
-local band = bit.band
local knot_pkt_t = ffi.typeof('knot_pkt_t')
ffi.metatype( knot_pkt_t, {
__index = {
end,
begin = function (pkt, section) return knot.knot_pkt_begin(pkt, section) end,
put = function (pkt, owner, ttl, rclass, rtype, rdata)
- return csym.kr_pkt_put(pkt, owner, ttl, rclass, rtype, rdata, string.len(rdata))
+ return C.kr_pkt_put(pkt, owner, ttl, rclass, rtype, rdata, string.len(rdata))
end
},
})
__index = {
current = function(req)
assert(req)
- return csym.kr_rplan_current(csym.kr_resolve_plan(req))
+ return C.kr_rplan_current(C.kr_resolve_plan(req))
end,
},
})
task->source.handle = handle;
uv_timer_init(worker->loop, &task->timeout);
task->timeout.data = task;
+ /* Remember query source addr */
if (addr) {
memcpy(&task->source.addr, addr, sockaddr_len(addr));
+ task->req.qsource.addr = (const struct sockaddr *)&task->source.addr;
} else {
task->source.addr.ip4.sin_family = AF_UNSPEC;
}
+ /* Remember query source TSIG key */
+ if (query->tsig_rr) {
+ task->req.qsource.key = knot_rrset_copy(query->tsig_rr, &task->req.pool);
+ }
/* Start resolution */
kr_resolve_begin(&task->req, &engine->resolver, answer);
#include "lib/defines.h"
#include "lib/utils.h"
#include "lib/generic/array.h"
+#include "lib/nsrep.h"
/** @internal CSPRNG context */
static isaac_ctx ISAAC;
/* Append RR */
return knot_pkt_put(pkt, 0, &rr, KNOT_PF_FREE);
}
+
+const char *kr_inaddr(const struct sockaddr *addr)
+{
+ if (!addr) {
+ return NULL;
+ }
+ switch (addr->sa_family) {
+ case AF_INET: return (const char *)&(((const struct sockaddr_in *)addr)->sin_addr);
+ case AF_INET6: return (const char *)&(((const struct sockaddr_in6 *)addr)->sin6_addr);
+ default: return NULL;
+ }
+}
+
+int kr_inaddr_len(const struct sockaddr *addr)
+{
+ if (!addr) {
+ return kr_error(EINVAL);
+ }
+ return addr->sa_family == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr);
+}
+
+int kr_inaddr_family(const char *addr)
+{
+ if (!addr) {
+ return kr_error(EINVAL);
+ }
+ if (strchr(addr, ':')) {
+ return AF_INET6;
+ }
+ return AF_INET;
+}
\ No newline at end of file
#include <stdio.h>
#include <sys/time.h>
+#include <netinet/in.h>
#include <libknot/packet/pkt.h>
/*
/** Construct and put record to packet. */
int kr_pkt_put(knot_pkt_t *pkt, const knot_dname_t *name, uint32_t ttl,
uint16_t rclass, uint16_t rtype, const uint8_t *rdata, uint16_t rdlen);
+
+/** Address bytes for given family. */
+const char *kr_inaddr(const struct sockaddr *addr);
+/** Address length for given family. */
+int kr_inaddr_len(const struct sockaddr *addr);
+/** Return address type for string. */
+int kr_inaddr_family(const char *addr);
\ No newline at end of file