#include "lib/cache.h"
+/** DNS cookie cache entry tag. */
#define KR_CACHE_COOKIE (KR_CACHE_USER + 'C')
#define COOKIE_TTL 72000
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))
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);
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;
}
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);
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 {