Commit 1aabd4a9 authored by Vladimír Čunát's avatar Vladimír Čunát

Merge !756: modules/hints: allow overriding TTL, change default

Closes #442.
parents f4ae1631 bee22317
Pipeline #44778 passed with stages
in 17 minutes and 8 seconds
......@@ -8,6 +8,10 @@ Bugfixes
that were loaded as unmanaged trust anchors (!753)
- trust_anchors.add(): include these TAs in .summary() (!753)
Improvements
------------
- hints module: allow configuring the TTL and change default from 0 to 5s
Knot Resolver 3.2.1 (2019-01-10)
================================
......
......@@ -4,6 +4,7 @@ local condition = require('cqueues.condition')
modules = { 'hints', 'dns64' }
hints['dns64.example'] = '192.168.1.1'
hints.use_nodata(true) -- Respond NODATA to AAAA query
hints.ttl(60)
dns64.config('fe80::21b:77ff:0:0')
-- helper to wait for query resolution
......@@ -37,7 +38,7 @@ local function test_builtin_rules()
local rcode, answers = wait_resolve('dns64.example', kres.type.AAAA)
same(rcode, kres.rcode.NOERROR, 'dns64.example returns NOERROR')
same(#answers, 1, 'dns64.example synthesised answer')
local expect = {'dns64.example.', '0', 'AAAA', 'fe80::21b:77ff:c0a8:101'}
local expect = {'dns64.example.', '60', 'AAAA', 'fe80::21b:77ff:c0a8:101'}
if #answers > 0 then
local rr = {kres.rr2str(answers[1]):match('(%S+)%s+(%S+)%s+(%S+)%s+(%S+)')}
same(rr, expect, 'dns64.example synthesised correct AAAA record')
......@@ -49,4 +50,4 @@ local tests = {
test_builtin_rules,
}
return tests
\ No newline at end of file
return tests
......@@ -111,3 +111,10 @@ Properties
If set to true (the default), NODATA will be synthesised for matching hint name, but mismatching type (e.g. AAAA query when only A hint exists).
.. function:: hints.ttl([new_ttl])
:param int new_ttl: new TTL to set (optional)
:return: the TTL setting
This function allows to read and write the TTL value used for records generated by the hints module.
......@@ -33,6 +33,9 @@
#include "lib/module.h"
#include "lib/layer.h"
#include <inttypes.h>
#include <math.h>
/* Defaults */
#define VERBOSE_MSG(qry, ...) QRVERBOSE(qry, "hint", __VA_ARGS__)
#define ERR_MSG(...) kr_log_error("[ ][hint] " __VA_ARGS__)
......@@ -41,7 +44,9 @@ struct hints_data {
struct kr_zonecut hints;
struct kr_zonecut reverse_hints;
bool use_nodata; /**< See hint_use_nodata() description, exposed via lua. */
uint32_t ttl; /**< TTL used for the hints, exposed via lua. */
};
static const uint32_t HINTS_TTL_DEFAULT = 5;
/** Useful for returning from module properties. */
static char * bool2jsonstr(bool val)
......@@ -79,16 +84,17 @@ static int put_answer(knot_pkt_t *pkt, struct kr_query *qry, knot_rrset_t *rr, b
return ret;
}
static int satisfy_reverse(struct kr_zonecut *hints, knot_pkt_t *pkt, struct kr_query *qry, bool use_nodata)
static int satisfy_reverse(/*const*/ struct hints_data *data,
knot_pkt_t *pkt, struct kr_query *qry)
{
/* Find a matching name */
pack_t *addr_set = kr_zonecut_find(hints, qry->sname);
pack_t *addr_set = kr_zonecut_find(&data->reverse_hints, qry->sname);
if (!addr_set || addr_set->len == 0) {
return kr_error(ENOENT);
}
knot_dname_t *qname = knot_dname_copy(qry->sname, &pkt->mm);
knot_rrset_t rr;
knot_rrset_init(&rr, qname, KNOT_RRTYPE_PTR, KNOT_CLASS_IN, 0);
knot_rrset_init(&rr, qname, KNOT_RRTYPE_PTR, KNOT_CLASS_IN, data->ttl);
/* Append address records from hints */
uint8_t *addr = pack_last(*addr_set);
......@@ -98,19 +104,20 @@ static int satisfy_reverse(struct kr_zonecut *hints, knot_pkt_t *pkt, struct kr_
knot_rrset_add_rdata(&rr, addr_val, len, &pkt->mm);
}
return put_answer(pkt, qry, &rr, use_nodata);
return put_answer(pkt, qry, &rr, data->use_nodata);
}
static int satisfy_forward(struct kr_zonecut *hints, knot_pkt_t *pkt, struct kr_query *qry, bool use_nodata)
static int satisfy_forward(/*const*/ struct hints_data *data,
knot_pkt_t *pkt, struct kr_query *qry)
{
/* Find a matching name */
pack_t *addr_set = kr_zonecut_find(hints, qry->sname);
pack_t *addr_set = kr_zonecut_find(&data->hints, qry->sname);
if (!addr_set || addr_set->len == 0) {
return kr_error(ENOENT);
}
knot_dname_t *qname = knot_dname_copy(qry->sname, &pkt->mm);
knot_rrset_t rr;
knot_rrset_init(&rr, qname, qry->stype, qry->sclass, 0);
knot_rrset_init(&rr, qname, qry->stype, qry->sclass, data->ttl);
size_t family_len = sizeof(struct in_addr);
if (rr.type == KNOT_RRTYPE_AAAA) {
family_len = sizeof(struct in6_addr);
......@@ -127,7 +134,7 @@ static int satisfy_forward(struct kr_zonecut *hints, knot_pkt_t *pkt, struct kr_
addr = pack_obj_next(addr);
}
return put_answer(pkt, qry, &rr, use_nodata);
return put_answer(pkt, qry, &rr, data->use_nodata);
}
static int query(kr_layer_t *ctx, knot_pkt_t *pkt)
......@@ -147,11 +154,11 @@ static int query(kr_layer_t *ctx, knot_pkt_t *pkt)
switch(qry->stype) {
case KNOT_RRTYPE_A:
case KNOT_RRTYPE_AAAA: /* Find forward record hints */
if (satisfy_forward(&data->hints, pkt, qry, data->use_nodata) != 0)
if (satisfy_forward(data, pkt, qry) != 0)
return ctx->state;
break;
case KNOT_RRTYPE_PTR: /* Find PTR record */
if (satisfy_reverse(&data->reverse_hints, pkt, qry, data->use_nodata) != 0)
if (satisfy_reverse(data, pkt, qry) != 0)
return ctx->state;
break;
default:
......@@ -570,6 +577,29 @@ static char* hint_use_nodata(void *env, struct kr_module *module, const char *ar
return bool2jsonstr(true);
}
static char* hint_ttl(void *env, struct kr_module *module, const char *args)
{
struct hints_data *data = module->data;
/* Do no change on nonsense TTL values (incl. suspicious floats). */
JsonNode *root_node = args ? json_decode(args) : NULL;
if (root_node && root_node->tag == JSON_NUMBER) {
double ttl_d = root_node->number_;
uint32_t ttl = round(ttl_d);
if (ttl_d >= 0 && fabs(ttl_d - ttl) * 64 < 1) {
data->ttl = ttl;
}
}
json_delete(root_node);
/* Always return the current TTL setting. Plain number is valid JSON. */
char *result = NULL;
if (-1 == asprintf(&result, "%"PRIu32, data->ttl)) {
result = NULL;
}
return result;
}
/*
* Module implementation.
*/
......@@ -609,6 +639,7 @@ int hints_init(struct kr_module *module)
kr_zonecut_init(&data->hints, (const uint8_t *)(""), pool);
kr_zonecut_init(&data->reverse_hints, (const uint8_t *)(""), pool);
data->use_nodata = true;
data->ttl = HINTS_TTL_DEFAULT;
module->data = data;
return kr_ok();
......@@ -654,6 +685,7 @@ struct kr_prop *hints_props(void)
{ &hint_set, "set", "Set {name, address} hint.", },
{ &hint_del, "del", "Delete one {name, address} hint or all addresses for the name.", },
{ &hint_get, "get", "Retrieve hint for given name.", },
{ &hint_ttl, "ttl", "Set/get TTL used for the hints.", },
{ &hint_add_hosts, "add_hosts", "Load a file with hosts-like formatting and add contents into hints.", },
{ &hint_root, "root", "Replace root hints set (empty value to return current list).", },
{ &hint_root_file, "root_file", "Replace root hints set from a zonefile.", },
......
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