]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Served cookie queries are handled inside cookie module.
authorKarel Slany <karel.slany@nic.cz>
Thu, 21 Jul 2016 10:13:19 +0000 (12:13 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 11 Aug 2016 12:06:45 +0000 (14:06 +0200)
daemon/lua/kres.lua
lib/layer/iterate.c
lib/resolve.c
lib/rplan.c
lib/rplan.h
modules/cookies/cookiemonster.c
tests/test_rplan.c

index 563ee8777927503c73e839f8d372e5524a9569f5..ebf8754a4616946cc4fb7a827cb022cf5b56c5c2 100644 (file)
@@ -203,6 +203,7 @@ struct kr_zonecut {
 };
 struct kr_query {
        struct kr_query *parent;
+       uint16_t qdcount;
        knot_dname_t *sname;
        uint16_t type;
        uint16_t class;
index f963596d07520de29201557562f6a6311fcc6c6b..f668638a4fc968c77ee0bf17635f14a288ff439d 100644 (file)
@@ -511,6 +511,15 @@ static int begin(knot_layer_t *ctx, void *module_param)
        if (ctx->state & (KNOT_STATE_DONE|KNOT_STATE_FAIL)) {
                return ctx->state;
        }
+       /*
+        * Fail if no query section. DNS cookies must be handled before
+        * this layer.
+        */
+       const struct kr_request *req = ctx->data;
+       const struct kr_query *qry = req->current_query;
+       if (qry->qdcount == 0) {
+               return KNOT_STATE_FAIL;
+       }
        return reset(ctx);
 }
 
index 9d5a1da40d868d6283e0d54d77233d001b40cb5e..d974452f8d924ef7ea6955a900e7fd72e77ca26c 100644 (file)
@@ -389,62 +389,6 @@ int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pk
        return KNOT_STATE_CONSUME;
 }
 
-#if defined(ENABLE_COOKIES)
-/**
- * @brief Put cookie into answer packet.
- * @param clnt_sockaddr client socket address
- * @param srvr_sett settings structure of the server cookie algorithm
- * @param cookies obtained cookies
- * @param answer answer packet
- * @return state
- */
-static int cookie_answer(const void *clnt_sockaddr,
-                         const struct kr_cookie_settings *srvr_sett,
-                         struct knot_dns_cookies *cookies, knot_pkt_t *answer)
-{
-       assert(srvr_sett && cookies && answer);
-
-       /* Initialise answer. */
-       knot_wire_set_qr(answer->wire);
-       knot_wire_clear_aa(answer->wire);
-       knot_wire_set_ra(answer->wire);
-       knot_wire_set_rcode(answer->wire, KNOT_RCODE_NOERROR);
-
-       struct knot_sc_private srvr_data = {
-               .clnt_sockaddr = clnt_sockaddr,
-               .secret_data = srvr_sett->current.secr->data,
-               .secret_len = srvr_sett->current.secr->size
-       };
-
-       struct timeval tv;
-       gettimeofday(&tv, NULL);
-
-       struct kr_nonce_input nonce = {
-               .rand = kr_rand_uint(UINT32_MAX),
-               .time = tv.tv_sec
-       };
-
-       /* Add fres cookie into the answer. */
-       int ret = kr_answer_write_cookie(&srvr_data,
-                                        cookies->cc, cookies->cc_len, &nonce,
-                                        kr_sc_algs[srvr_sett->current.alg_id], answer);
-       if (ret != kr_ok()) {
-               return KNOT_STATE_FAIL;
-       }
-
-       /* Check server cookie only with current settings. */
-       ret = knot_sc_check(KR_NONCE_LEN, cookies, &srvr_data,
-                           kr_sc_algs[srvr_sett->current.alg_id]);
-       if (ret != KNOT_EOK) {
-               /* RFC7873 5.4 */
-               kr_pkt_set_ext_rcode(answer, KNOT_RCODE_BADCOOKIE);
-               return KNOT_STATE_FAIL | KNOT_STATE_DONE;
-       }
-
-       return KNOT_STATE_DONE;
-}
-#endif /* defined(ENABLE_COOKIES) */
-
 static int resolve_query(struct kr_request *request, const knot_pkt_t *packet)
 {
        struct kr_rplan *rplan = &request->rplan;
@@ -453,30 +397,7 @@ static int resolve_query(struct kr_request *request, const knot_pkt_t *packet)
        uint16_t qtype = knot_pkt_qtype(packet);
        struct kr_query *qry = kr_rplan_push(rplan, NULL, qname, qclass, qtype);
        if (!qry) {
-#if defined(ENABLE_COOKIES)
-               /* RFC7873 5.4 specifies a query for server cookie. Such query
-                * has QDCOUNT == 0 and contains a cookie option.
-                *
-                * The layers don't expect to handle queries with QDCOUNT != 1
-                * so such queries are handled directly here. */
-               struct knot_dns_cookies cookies = { 0, };
-               uint8_t *cookie_opt = kr_no_question_cookie_query(packet);
-               if (cookie_opt && request->ctx->cookie_ctx.clnt.enabled) {
-                       if (kr_ok() != kr_parse_cookie_opt(cookie_opt,
-                                                          &cookies)) {
-                               /* RFC7873 5.2.2 malformed cookie. */
-                               knot_wire_set_rcode(request->answer->wire,
-                                                   KNOT_RCODE_FORMERR);
-                               return KNOT_STATE_FAIL;
-                       }
-               }
-
-               return cookie_answer(request->qsource.addr,
-                                    &request->ctx->cookie_ctx.srvr,
-                                    &cookies, request->answer);
-#else /* !defined(ENABLE_COOKIES) */
                return KNOT_STATE_FAIL;
-#endif /* defined(ENABLE_COOKIES) */
        }
 
        /* Deferred zone cut lookup for this query. */
index f5d050e80cb722dff247367c61cea4c912655d4a..0479b47edeb909d11c1a91193ed530703e4a96a4 100644 (file)
@@ -42,20 +42,19 @@ const knot_lookup_t *kr_query_flag_names(void)
 
 static struct kr_query *query_create(knot_mm_t *pool, const knot_dname_t *name)
 {
-       if (name == NULL) {
-               return NULL;
-       }
-
        struct kr_query *qry = mm_alloc(pool, sizeof(struct kr_query));
        if (qry == NULL) {
                return NULL;
        }
 
        memset(qry, 0, sizeof(struct kr_query));
-       qry->sname = knot_dname_copy(name, pool);
-       if (qry->sname == NULL) {
-               mm_free(pool, qry);
-               return NULL;
+       if (name != NULL) {
+               qry->sname = knot_dname_copy(name, pool);
+               if (qry->sname == NULL) {
+                       mm_free(pool, qry);
+                       return NULL;
+               }
+               qry->qdcount = 1;
        }
 
        knot_dname_to_lower(qry->sname);
@@ -112,7 +111,7 @@ bool kr_rplan_empty(struct kr_rplan *rplan)
 struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
                                const knot_dname_t *name, uint16_t cls, uint16_t type)
 {
-       if (rplan == NULL || name == NULL) {
+       if (rplan == NULL) {
                return NULL;
        }
 
index aa6fa5fe37908184dc888712fc31e0fc2bce75e5..944261ce88896e9e6c8a2c20056c637c8a15056c 100644 (file)
@@ -65,6 +65,7 @@ const knot_lookup_t *kr_query_flag_names(void);
  */
 struct kr_query {
        struct kr_query *parent;
+       uint16_t qdcount; /* Can be 0 when querying server cookie. */
        knot_dname_t *sname;
        uint16_t stype;
        uint16_t sclass;
index 6a60f5d6bd55804969a605ae8807d9bef74f5032..e2739224ac7dd96753c4c2cb0690150e049c163d 100644 (file)
@@ -397,9 +397,14 @@ int check_request(knot_layer_t *ctx, void *module_param)
                .time = req->current_query->timestamp.tv_sec
        };
 
+       const struct kr_query *qry = req->current_query;
+
        if (!cookies.sc) {
-               /* Request has no server cookie. TODO -- Silently discard? */
-               if (!ignore_badcookie) {
+               /* Request has no server cookie. */
+               if (qry->qdcount == 0) {
+                       /* RFC7873 5.4 */
+                       return_state = KNOT_STATE_DONE;
+               } else if (!ignore_badcookie) { /* TODO -- Silently discard? */
                        /* Generate BADCOOKIE response. */
                        DEBUG_MSG(NULL, "%s\n",
                                  "request is missing server cookie");
@@ -431,8 +436,12 @@ int check_request(knot_layer_t *ctx, void *module_param)
                                    kr_sc_algs[srvr_sett->recent.alg_id]);
        }
        if (ret != KNOT_EOK) {
-               /* TODO -- Silently discard? */
-               if (!ignore_badcookie) {
+               /* Invalid server cookie. */
+               if (qry->qdcount == 0) {
+                       /* RFC7873 5.4 */
+                       kr_pkt_set_ext_rcode(req->answer, KNOT_RCODE_BADCOOKIE);
+                       return_state = KNOT_STATE_DONE | KNOT_STATE_FAIL;
+               } else if (!ignore_badcookie) { /* TODO -- Silently discard? */
                        /* Generate BADCOOKIE response. */
                        DEBUG_MSG(NULL, "%s\n",
                                  "request has invalid server cookie");
index 0374fe1b9cb63f435be90bcc211f02f3a64ebaec..f628b29546a7ed0549cf9a01d9baba5da6d35c3a 100644 (file)
@@ -32,7 +32,8 @@ static void test_rplan_params(void **state)
 
        struct kr_rplan rplan;
        assert_int_equal(kr_rplan_init(&rplan, NULL, NULL), KNOT_EOK);
-       assert_null((void *)kr_rplan_push(&rplan, NULL, NULL, 0, 0));
+       // TODO: add test for empty dname
+//     assert_null((void *)kr_rplan_push(&rplan, NULL, NULL, 0, 0));
        assert_int_equal(kr_rplan_pop(&rplan, NULL), KNOT_EINVAL);
        assert_true(kr_rplan_empty(&rplan) == true);
        kr_rplan_deinit(&rplan);