]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Function kr_rplan_push() fails again with null name.
authorKarel Slany <karel.slany@nic.cz>
Thu, 4 Aug 2016 14:29:05 +0000 (16:29 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 11 Aug 2016 12:06:45 +0000 (14:06 +0200)
Introduced kr_rplan_push_empty() to create empty query for DNS cookies.

lib/resolve.c
lib/rplan.c
lib/rplan.h
tests/test_rplan.c

index 498b43218dbf922cc7017f524f4d519d2c90f4b7..e4f61e4314815cc3b3d0cd27d9b2d6027ec73eba 100644 (file)
@@ -396,7 +396,16 @@ static int resolve_query(struct kr_request *request, const knot_pkt_t *packet)
        const knot_dname_t *qname = knot_pkt_qname(packet);
        uint16_t qclass = knot_pkt_qclass(packet);
        uint16_t qtype = knot_pkt_qtype(packet);
-       struct kr_query *qry = kr_rplan_push(rplan, NULL, qname, qclass, qtype);
+       struct kr_query *qry = NULL;
+
+       if (qname != NULL) {
+               qry = kr_rplan_push(rplan, NULL, qname, qclass, qtype);
+       } else if (knot_wire_get_qdcount(packet->wire) == 0 &&
+                   knot_pkt_has_edns(packet) &&
+                   knot_edns_has_option(packet->opt_rr, KNOT_EDNS_OPTION_COOKIE)) {
+               /* Plan empty query only for cookies. */
+               qry = kr_rplan_push_empty(rplan, NULL);
+       }
        if (!qry) {
                return KNOT_STATE_FAIL;
        }
index bc6ff7c374fe51551edeab71acc7e2d28608a1c3..4a610c6c0a82be1b59021aa8bcecd22795583f96 100644 (file)
@@ -107,8 +107,9 @@ bool kr_rplan_empty(struct kr_rplan *rplan)
        return rplan->pending.len == 0;
 }
 
-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)
+static struct kr_query *kr_rplan_push_query(struct kr_rplan *rplan,
+                                            struct kr_query *parent,
+                                            const knot_dname_t *name)
 {
        if (rplan == NULL) {
                return NULL;
@@ -124,8 +125,7 @@ struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
        if (qry == NULL) {
                return NULL;
        }
-       qry->sclass = cls;
-       qry->stype = type;
+       /* Class and type must be set outside this function. */
        qry->flags = rplan->request->options;
        qry->parent = parent;
        qry->ns.addr[0].ip.sa_family = AF_UNSPEC;
@@ -133,6 +133,41 @@ struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
        kr_zonecut_init(&qry->zone_cut, (const uint8_t *)"", rplan->pool);
        array_push(rplan->pending, qry);
 
+       return qry;
+}
+
+struct kr_query *kr_rplan_push_empty(struct kr_rplan *rplan, struct kr_query *parent)
+{
+       if (rplan == NULL) {
+               return NULL;
+       }
+
+       struct kr_query *qry = kr_rplan_push_query(rplan, parent, NULL);
+       if (qry == NULL) {
+               return NULL;
+       }
+
+       WITH_DEBUG {
+       DEBUG_MSG(parent, "plan '%s' type '%s'\n", "", "");
+       }
+       return qry;
+}
+
+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) {
+               return NULL;
+       }
+
+       struct kr_query *qry = kr_rplan_push_query(rplan, parent, name);
+       if (qry == NULL) {
+               return NULL;
+       }
+
+       qry->sclass = cls;
+       qry->stype = type;
+
        WITH_DEBUG {
        char name_str[KNOT_DNAME_MAXLEN], type_str[16];
        knot_dname_to_str(name_str, name, sizeof(name_str));
index aa6fa5fe37908184dc888712fc31e0fc2bce75e5..80a675c0c4bad4a9ad88d4940db424f89d091c7a 100644 (file)
@@ -120,6 +120,17 @@ void kr_rplan_deinit(struct kr_rplan *rplan);
 KR_EXPORT KR_PURE
 bool kr_rplan_empty(struct kr_rplan *rplan);
 
+/**
+ * Push empty query to the top of the resolution plan.
+ * @note This query serves as a cookie query only.
+ * @param rplan plan instance
+ * @param parent query parent (or NULL)
+ * @return query instance or NULL
+ */
+KR_EXPORT
+struct kr_query *kr_rplan_push_empty(struct kr_rplan *rplan,
+                                     struct kr_query *parent);
+
 /**
  * Push a query to the top of the resolution plan.
  * @note This means that this query takes precedence before all pending queries.
index f628b29546a7ed0549cf9a01d9baba5da6d35c3a..0374fe1b9cb63f435be90bcc211f02f3a64ebaec 100644 (file)
@@ -32,8 +32,7 @@ static void test_rplan_params(void **state)
 
        struct kr_rplan rplan;
        assert_int_equal(kr_rplan_init(&rplan, NULL, NULL), KNOT_EOK);
-       // TODO: add test for empty dname
-//     assert_null((void *)kr_rplan_push(&rplan, NULL, NULL, 0, 0));
+       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);