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

daemon: `net.ipv{4,6} = true|false`

effectively enables/disables usage of given IP protocol
for subrequests (the server can still listen on these)
parent 3dc193c8
......@@ -287,6 +287,19 @@ For when listening on ``localhost`` just doesn't cut it.
.. code-block:: lua
net = { '127.0.0.1', net.eth0, net.eth1.addr[1] }
net.ipv4 = false
.. function:: net.ipv6 = true|false
:return: boolean (default: true)
Enable/disable using IPv6 for recursion.
.. function:: net.ipv4 = true|false
:return: boolean (default: true)
Enable/disable using IPv4 for recursion.
.. function:: net.listen(address, [port = 53])
......
......@@ -88,9 +88,11 @@ struct pkt_rcode {
};
struct query_flag {
static const int NO_MINIMIZE = 1 << 0;
static const int CACHED = 1 << 8;
static const int NO_CACHE = 1 << 9;
static const int EXPIRING = 1 << 10;
static const int NO_IPV6 = 1 << 2;
static const int NO_IPV4 = 1 << 3;
static const int CACHED = 1 << 10;
static const int NO_CACHE = 1 << 11;
static const int EXPIRING = 1 << 12;
};
/*
......
......@@ -23,19 +23,26 @@ setmetatable(env, {
-- Quick access to interfaces
-- `net.<iface>` => `net.interfaces()[iface]`
-- `net = {addr1, ..}` => `net.listen(name, addr1)`
-- `net.ipv{4,6} = {true, false}` => enable/disable IPv{4,6}
setmetatable(net, {
__index = function (t, k)
local v = rawget(t, k)
if v then return v
elseif k == 'ipv6' then return not option('NO_IPV6')
elseif k == 'ipv4' then return not option('NO_IPV4')
else return net.interfaces()[k]
end
end,
__newindex = function (t,k,v)
if k == 'ipv6' then return option('NO_IPV6', not v)
elseif k == 'ipv4' then return option('NO_IPV4', not v)
else
local iname = rawget(net.interfaces(), v)
if iname then t.listen(iname)
else t.listen(v)
end
end
end
})
-- Syntactic sugar for module loading
......
......@@ -66,18 +66,26 @@ static void update_nsrep_set(struct kr_nsrep *ns, const knot_dname_t *name, uint
#undef ADDR_SET
static unsigned eval_addr_set(pack_t *addr_set, kr_nsrep_lru_t *rttcache, unsigned score, uint8_t *addr[])
static unsigned eval_addr_set(pack_t *addr_set, kr_nsrep_lru_t *rttcache, unsigned score, uint8_t *addr[], uint32_t opts)
{
/* Name server is better candidate if it has address record. */
uint8_t *it = pack_head(*addr_set);
while (it != pack_tail(*addr_set)) {
void *val = pack_obj_val(it);
size_t len = pack_obj_len(it);
unsigned favour = 0;
bool is_valid = false;
/* Check if the address isn't disabled. */
if (len == sizeof(struct in6_addr)) {
is_valid = !(opts & QUERY_NO_IPV6);
favour = FAVOUR_IPV6;
} else {
is_valid = !(opts & QUERY_NO_IPV4);
}
/* Get RTT for this address (if known) */
if (is_valid) {
unsigned *cached = rttcache ? lru_get(rttcache, val, len) : NULL;
unsigned addr_score = (cached) ? *cached : KR_NS_GLUED;
/* Give v6 a head start */
unsigned favour = (len == sizeof(struct in6_addr)) ? FAVOUR_IPV6 : 0;
if (addr_score < score + favour) {
/* Shake down previous contenders, last one is always unused */
for (size_t i = KR_NSREP_MAXADDR - 2; i > 0; --i)
......@@ -85,6 +93,7 @@ static unsigned eval_addr_set(pack_t *addr_set, kr_nsrep_lru_t *rttcache, unsign
addr[0] = it;
score = addr_score;
}
}
it = pack_obj_next(it);
}
return score;
......@@ -122,7 +131,7 @@ static int eval_nsrep(const char *k, void *v, void *baton)
}
}
} else {
score = eval_addr_set(addr_set, ctx->cache_rtt, score, addr_choice);
score = eval_addr_set(addr_set, ctx->cache_rtt, score, addr_choice, ctx->options);
}
/* Probabilistic bee foraging strategy (naive).
......@@ -181,7 +190,7 @@ int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx)
}
/* Evaluate addr list */
uint8_t *addr_choice[KR_NSREP_MAXADDR] = { NULL, };
unsigned score = eval_addr_set(addr_set, ctx->cache_rtt, ns->score, addr_choice);
unsigned score = eval_addr_set(addr_set, ctx->cache_rtt, ns->score, addr_choice, ctx->options);
update_nsrep_set(ns, ns->name, addr_choice, score);
return kr_ok();
}
......
......@@ -29,19 +29,21 @@
#define QUERY_FLAGS(X) \
X(NO_MINIMIZE, 1 << 0) /**< Don't minimize QNAME. */ \
X(NO_THROTTLE, 1 << 1) /**< No query/slow NS throttling. */ \
X(TCP , 1 << 2) /**< Use TCP for this query. */ \
X(RESOLVED , 1 << 3) /**< Query is resolved. */ \
X(AWAIT_IPV4 , 1 << 4) /**< Query is waiting for A address. */ \
X(AWAIT_IPV6 , 1 << 5) /**< Query is waiting for AAAA address. */ \
X(AWAIT_CUT , 1 << 6) /**< Query is waiting for zone cut lookup */ \
X(SAFEMODE , 1 << 7) /**< Don't use fancy stuff (EDNS...) */ \
X(CACHED , 1 << 8) /**< Query response is cached. */ \
X(NO_CACHE , 1 << 9) /**< Do not use expiring cache for lookup. */ \
X(EXPIRING , 1 << 10) /**< Query response is cached, but expiring. */ \
X(ALLOW_LOCAL, 1 << 11) /**< Allow queries to local or private address ranges. */ \
X(DNSSEC_WANT, 1 << 12) /**< Want DNSSEC secured answer. */ \
X(DNSSEC_BOGUS, 1 << 13) /**< Query response is DNSSEC bogus. */ \
X(DNSSEC_INSECURE, 1 << 14) /**< Query response is DNSSEC insecure. */ \
X(NO_IPV6, 1 << 2) /**< Disable IPv6 */ \
X(NO_IPV4, 1 << 3) /**< Disable IPv4 */ \
X(TCP, 1 << 4) /**< Use TCP for this query. */ \
X(RESOLVED, 1 << 5) /**< Query is resolved. */ \
X(AWAIT_IPV4, 1 << 6) /**< Query is waiting for A address. */ \
X(AWAIT_IPV6, 1 << 7) /**< Query is waiting for AAAA address. */ \
X(AWAIT_CUT, 1 << 8) /**< Query is waiting for zone cut lookup */ \
X(SAFEMODE, 1 << 9) /**< Don't use fancy stuff (EDNS...) */ \
X(CACHED, 1 << 10) /**< Query response is cached. */ \
X(NO_CACHE, 1 << 11) /**< Do not use expiring cache for lookup. */ \
X(EXPIRING, 1 << 12) /**< Query response is cached, but expiring. */ \
X(ALLOW_LOCAL, 1 << 13) /**< Allow queries to local or private address ranges. */ \
X(DNSSEC_WANT, 1 << 14) /**< Want DNSSEC secured answer. */ \
X(DNSSEC_BOGUS, 1 << 15) /**< Query response is DNSSEC bogus. */ \
X(DNSSEC_INSECURE, 1 << 16) /**< Query response is DNSSEC insecure. */ \
/** Query flags */
enum kr_query_flag {
......@@ -63,7 +65,7 @@ struct kr_query {
uint16_t stype;
uint16_t sclass;
uint16_t id;
uint16_t flags;
uint32_t flags;
uint32_t secret;
struct timeval timestamp;
struct kr_nsrep ns;
......
......@@ -329,10 +329,10 @@ static int fetch_ns(struct kr_context *ctx, struct kr_zonecut *cut, const knot_d
/* Fetch NS reputation and decide whether to prefetch A/AAAA records. */
unsigned *cached = lru_get(ctx->cache_rep, (const char *)ns_name, knot_dname_size(ns_name));
unsigned reputation = (cached) ? *cached : 0;
if (!(reputation & KR_NS_NOIP4)) {
if (!(reputation & KR_NS_NOIP4) && !(ctx->options & QUERY_NO_IPV4)) {
fetch_addr(cut, ns_name, KNOT_RRTYPE_A, txn, timestamp);
}
if (!(reputation & KR_NS_NOIP6)) {
if (!(reputation & KR_NS_NOIP6) && !(ctx->options & QUERY_NO_IPV6)) {
fetch_addr(cut, ns_name, KNOT_RRTYPE_AAAA, txn, timestamp);
}
}
......
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