]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Querying again when BADCOOKIE received.
authorKarel Slany <karel.slany@nic.cz>
Tue, 31 May 2016 13:02:11 +0000 (15:02 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 11 Aug 2016 12:06:45 +0000 (14:06 +0200)
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.

lib/cookies/cache.h
lib/layer/cookies.c
lib/layer/iterate.c
lib/resolve.c
lib/rplan.h

index 80a79b4c2fc61c284fefceb67272cec607d36272..a6ad73267fdfa9497244f8ddad72683b0f743bbf 100644 (file)
@@ -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))
index 829ac0dffdb2f45e3e1200df16be50ae98eddcbc..f5088894f0d63d6c541197e137f630368e06977d 100644 (file)
@@ -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);
index bfe9b51cc63ffc05a5ce0bba8ca70bddcac7f18b..e77a319c269b8eb38c786fc5be1cfd6c831b0394 100644 (file)
@@ -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;
        }
 
index b42f35e7579ba46136e2bc48058828ffba3fa76b..9100705c75649ebd77688859b56e6c837a4cb34f 100644 (file)
@@ -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);
index 4720a518a3249767e8460ace890137d828800b92..de679deb1cee58354b49f7b4b57e5f17c1c5e6fe 100644 (file)
@@ -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 {