Commit cf5880f6 authored by Marek Vavruša's avatar Marek Vavruša

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
parent ba2fa2bf
......@@ -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,
},
})
......
......@@ -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);
......
......@@ -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;
......
......@@ -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
......@@ -18,6 +18,7 @@
#include <stdio.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <libknot/packet/pkt.h>
/*
......@@ -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
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