From: Marek VavruĊĦa Date: Mon, 10 Aug 2015 15:06:18 +0000 (+0200) Subject: lib: added query source information to request (optional) X-Git-Tag: v1.0.0-beta1~59^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cf5880f64a934580f2a9f5dd35e337a1dc2e29b8;p=thirdparty%2Fknot-resolver.git lib: added query source information to request (optional) the requestor can provide information identifying the query originator here (address and TSIG key), both fields are optional update Lua FFI bindings --- diff --git a/daemon/lua/kres.lua b/daemon/lua/kres.lua index 23e4bddf3..15165b4bb 100644 --- a/daemon/lua/kres.lua +++ b/daemon/lua/kres.lua @@ -3,7 +3,9 @@ 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[[ @@ -88,11 +90,27 @@ struct pkt_rcode { * 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; @@ -102,6 +120,8 @@ typedef struct { 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; @@ -123,6 +143,10 @@ struct kr_rplan { 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 */ @@ -152,11 +176,28 @@ struct kr_query *kr_rplan_current(struct kr_rplan *rplan); 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 = { @@ -173,7 +214,7 @@ ffi.metatype( knot_pkt_t, { 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 }, }) @@ -190,7 +231,7 @@ ffi.metatype( kr_request_t, { __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, }, }) diff --git a/daemon/worker.c b/daemon/worker.c index cd61e2aa4..5f1e01ee3 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -139,11 +139,17 @@ static struct qr_task *qr_task_create(struct worker_ctx *worker, uv_handle_t *ha 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); diff --git a/lib/resolve.h b/lib/resolve.h index 4720eb212..9daae8b85 100644 --- a/lib/resolve.h +++ b/lib/resolve.h @@ -126,6 +126,10 @@ struct kr_context 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; struct kr_rplan rplan; diff --git a/lib/utils.c b/lib/utils.c index 35b527170..0ff603f05 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -25,6 +25,7 @@ #include "lib/defines.h" #include "lib/utils.h" #include "lib/generic/array.h" +#include "lib/nsrep.h" /** @internal CSPRNG context */ static isaac_ctx ISAAC; @@ -173,3 +174,34 @@ int kr_pkt_put(knot_pkt_t *pkt, const knot_dname_t *name, uint32_t ttl, /* 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 diff --git a/lib/utils.h b/lib/utils.h index d6e0b1fe2..41524e012 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -18,6 +18,7 @@ #include #include +#include #include /* @@ -78,3 +79,10 @@ int mm_reserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *ha /** 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