Commit e6471bcd authored by Karel Slaný's avatar Karel Slaný Committed by Ondřej Surý
Browse files

Querying again when BADCOOKIE received.

The cookies layer injects a new query into the plan when a DADCOOKIE
response is detected. After failing the second attempt a TCP fallback is
signalised.
parent 6a98ba42
......@@ -18,6 +18,7 @@
#include "lib/cache.h"
/** DNS cookie cache entry tag. */
#define KR_CACHE_COOKIE (KR_CACHE_USER + 'C')
#define COOKIE_TTL 72000
......@@ -98,5 +99,11 @@ int kr_cookie_cache_insert_cookie(struct kr_cache_txn *txn, const void *sockaddr
const struct timed_cookie *cookie,
uint32_t timestamp);
/**
* Remove asset from cache.
* @param txn transaction instance
* @param sockaddr socket address
* @return 0 or an error code
*/
#define kr_cookie_cache_remove_cookie(txn, sockaddr) \
kr_cookie_cache_remove((txn), KR_CACHE_COOKIE, (sockaddr))
......@@ -351,9 +351,18 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
uint16_t rcode = knot_pkt_get_ext_rcode(pkt);
if (rcode == KNOT_RCODE_BADCOOKIE) {
DEBUG_MSG(NULL, "%s\n", "falling back to TCP");
qry->flags |= QUERY_TCP;
return KNOT_STATE_CONSUME;
if (qry->flags & QUERY_COOKIE_AGAIN) {
DEBUG_MSG(NULL, "%s\n", "falling back to TCP");
qry->flags &= ~QUERY_COOKIE_AGAIN;
qry->flags |= QUERY_TCP;
return KNOT_STATE_CONSUME;
} else {
struct kr_query *next = kr_rplan_push(&req->rplan, qry->parent, qry->sname, qry->sclass, qry->stype);
next->flags = qry->flags;
DEBUG_MSG(NULL, "%s\n", "BADCOOKIE querying again");
qry->flags |= QUERY_COOKIE_AGAIN;
return KNOT_STATE_CONSUME;
}
}
print_packet_dflt(pkt);
......
......@@ -576,7 +576,7 @@ static int resolve(knot_layer_t *ctx, knot_pkt_t *pkt)
assert(pkt && ctx);
struct kr_request *req = ctx->data;
struct kr_query *query = req->current_query;
if (!query || (query->flags & QUERY_RESOLVED)) {
if (!query || (query->flags & (QUERY_RESOLVED|QUERY_COOKIE_AGAIN))) {
return ctx->state;
}
......
......@@ -750,7 +750,7 @@ ns_election:
if (qry->flags & (QUERY_AWAIT_IPV4|QUERY_AWAIT_IPV6)) {
kr_nsrep_elect_addr(qry, request->ctx);
} else if (!qry->ns.name || !(qry->flags & (QUERY_TCP|QUERY_STUB))) { /* Keep NS when requerying/stub. */
} else if (!qry->ns.name || !(qry->flags & (QUERY_TCP|QUERY_STUB|QUERY_COOKIE_AGAIN))) { /* Keep NS when requerying/stub/badcookie. */
/* Root DNSKEY must be fetched from the hints to avoid chicken and egg problem. */
if (qry->sname[0] == '\0' && qry->stype == KNOT_RRTYPE_DNSKEY) {
kr_zonecut_set_sbelt(request->ctx, &qry->zone_cut);
......
......@@ -46,7 +46,8 @@
X(ALWAYS_CUT, 1 << 18) /**< Always recover zone cut (even if cached). */ \
X(DNSSEC_WEXPAND, 1 << 19) /**< Query response has wildcard expansion. */ \
X(PERMISSIVE, 1 << 20) /**< Permissive resolver mode. */ \
X(STRICT, 1 << 21) /**< Strict resolver mode. */
X(STRICT, 1 << 21) /**< Strict resolver mode. */ \
X(BADCOOKIE_AGAIN, 1 << 22) /**< Query again because bad cookie returned. */
/** Query flags */
enum kr_query_flag {
......
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