]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Obtaining server IP address when generating query.
authorKarel Slany <karel.slany@nic.cz>
Tue, 10 May 2016 13:26:50 +0000 (15:26 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 11 Aug 2016 12:06:45 +0000 (14:06 +0200)
daemon/worker.c
lib/cookies/control.c
lib/cookies/control.h
lib/resolve.c

index 1ab3d5d76ebdcda62eaa4b3ca0b8bdd9279b7da1..a7ef6df77050d68a1cc7a6cbb86ea6edfa4da4b4 100644 (file)
@@ -25,6 +25,7 @@
 #include <malloc.h>
 #endif
 #include <assert.h>
+#include "lib/cookies/control.h"
 #include "lib/utils.h"
 #include "lib/layer.h"
 #include "daemon/worker.h"
@@ -645,6 +646,25 @@ static void subreq_lead(struct qr_task *task)
        }
 }
 
+/** UpdateDNS cookie data in */
+static bool subreq_update_cookies(struct qr_task *task)
+{
+       assert(task);
+       if (!kr_cookies_control.enabled || !task->pktbuf->opt_rr) {
+               fprintf(stderr, "XXX [%s %s %d]: packet has no edns\n", __FILE__, __func__, __LINE__);
+               return true;
+       }
+
+       fprintf(stderr, "XXX [%s %s %d]: packet has edns\n", __FILE__, __func__, __LINE__);
+
+       struct sockaddr_in6 *choice = &((struct sockaddr_in6 *)task->addrlist)[task->addrlist_turn];
+
+       kr_pkt_put_cookie(&kr_cookies_control, choice, task->pktbuf);
+
+       /*TODO */
+       return true;
+}
+
 static bool subreq_enqueue(struct qr_task *task)
 {
        assert(task);
@@ -712,6 +732,8 @@ static int qr_task_step(struct qr_task *task, const struct sockaddr *packet_sour
        /* Start fast retransmit with UDP, otherwise connect. */
        int ret = 0;
        if (sock_type == SOCK_DGRAM) {
+               /* Update DNS cookies data. */
+               subreq_update_cookies(task);
                /* If there is already outgoing query, enqueue to it. */
                if (subreq_enqueue(task)) {
                        return kr_ok(); /* Will be notified when outgoing query finishes. */
index 1873cb175b9a24b125dbc1ccf30e35c72e6bdb53..582b9c58c92a66c6b0cba50ca29ed9189caa0ab7 100644 (file)
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <sys/socket.h>
+#include <netinet/in.h>
 #include <assert.h>
 #include <stdint.h>
 #include <libknot/error.h>
 #include <libknot/rrtype/opt_cookie.h>
 
 #include "lib/cookies/control.h"
+#include "lib/layer.h"
+#include "lib/utils.h"
 
-struct cookies_control cookies_control = {
-       .enabled = true
+#define DEBUG_MSG(qry, fmt...) QRDEBUG(qry, "cookies_control",  fmt)
+
+static uint8_t cc[KNOT_OPT_COOKIE_CLNT] = { 1, 2, 3, 4, 5, 6, 7, 8};
+
+static struct secret_quantity client = {
+       .size = KNOT_OPT_COOKIE_CLNT,
+       .secret = cc
+};
+
+struct cookies_control kr_cookies_control = {
+       .enabled = true,
+       .client = &client
 };
 
 static int opt_rr_add_cookies(knot_rrset_t *opt_rr,
@@ -54,15 +68,67 @@ static int opt_rr_add_cookies(knot_rrset_t *opt_rr,
        return KNOT_EOK;
 }
 
-int kr_pkt_add_cookie(knot_pkt_t *pkt)
+int prepare_client_cookie(uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+                           const void *srvr_addr,
+                           const struct secret_quantity *csq)
+{
+       assert(cc);
+       assert(srvr_addr);
+       assert(csq);
+
+       assert(csq->size >= KNOT_OPT_COOKIE_CLNT);
+
+       /* According to the draft (section A.1) the recommended sequence is
+        * client IP address | server IP address , client secret. */
+
+       int addr_family = ((struct sockaddr *) srvr_addr)->sa_family;
+       if (addr_family == AF_INET) {
+               srvr_addr = &((struct sockaddr_in *) srvr_addr)->sin_addr;
+       } else if (addr_family == AF_INET6) {
+               srvr_addr = &((struct sockaddr_in6 *) srvr_addr)->sin6_addr;
+       } else {
+               assert(0);
+               return kr_error(EINVAL);
+       }
+
+       WITH_DEBUG {
+               char ns_str[INET6_ADDRSTRLEN];
+               inet_ntop(addr_family, srvr_addr, ns_str, sizeof(ns_str));
+               DEBUG_MSG(NULL, "adding server address '%s' into client cookie\n", ns_str);
+       }
+
+       memcpy(cc, csq->secret, KNOT_OPT_COOKIE_CLNT);
+}
+
+int kr_pkt_put_cookie(struct cookies_control *cntrl, void *sockaddr,
+                      knot_pkt_t *pkt)
 {
+       assert(cntrl);
        assert(pkt);
-       assert(pkt->opt_rr);
+
+       uint8_t cc[KNOT_OPT_COOKIE_CLNT];
+
+       if (!pkt->opt_rr) {
+               return kr_ok();
+       }
+
+       if (!cntrl->client) {
+               return kr_error(EINVAL);
+       }
+
+       int ret = prepare_client_cookie(cc, sockaddr, cntrl->client);
+
+       /* Reclaim reserved size. */
+       ret = knot_pkt_reclaim(pkt, knot_edns_wire_size(pkt->opt_rr));
+       if (ret != KNOT_EOK) {
+               return ret;
+       }
 
        /* TODO -- generate cleitn cookie from client address, server address
         * and secret quentity. */
-       static uint8_t cc[KNOT_OPT_COOKIE_CLNT] = { 1, 2, 3, 4, 5, 6, 7, 8};
+       ret = opt_rr_add_cookies(pkt->opt_rr, cc, NULL, 0, &pkt->mm);
 
-       int ret = opt_rr_add_cookies(pkt->opt_rr, cc, NULL, 0, &pkt->mm);
-       return ret;
+       /* Write to packet. */
+       assert(pkt->current == KNOT_ADDITIONAL);
+       return knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, pkt->opt_rr, KNOT_PF_FREE);
 }
index 179195c6c82bd1292b58a0a364c1d7ef101e004d..f204ee7282aa3dad2465fbbfc08e400c4d9fc11b 100644 (file)
 #include <libknot/packet/pkt.h>
 #include <stdbool.h>
 
+#include "lib/defines.h"
+
 #define KR_COOKIE_PLD_MAX 44 /* Define in libknot. */
 
+/** Holds secret quantity. */
+struct secret_quantity {
+       size_t size; /*!< Secret quantity size. */
+       const uint8_t *secret;
+};
+
 /** DNSSEC cookies controlling structure. */
 struct cookies_control {
        bool enabled; /*!< Enabled/disables DNS cookies functionality. */
-       /* Cache. */
+       struct secret_quantity *client; /*!< Client secret quantity. */
+       /* TODO -- Cache. */
 };
 
 /** Global cookies control. */
-extern struct cookies_control cookies_control;
+KR_EXPORT
+extern struct cookies_control kr_cookies_control;
 
 /**
  * Insert a DNS cookie into the packet.
  * @note The packet must already contain ENDS section.
- * @param pkt Packet.
+ * @param cntrl Cookie control structure.
+ * @param pkt   Packet.
  */
-int kr_pkt_add_cookie(knot_pkt_t *pkt);
+KR_EXPORT
+int kr_pkt_put_cookie(struct cookies_control *cntrl, void *sockaddr,
+                      knot_pkt_t *pkt);
index 243b3d336e2424563854742436954719702d0eb1..189a5fe82e11cf9655064a76def2cc67352a0e46 100644 (file)
@@ -268,7 +268,7 @@ static int edns_create(knot_pkt_t *pkt, knot_pkt_t *template, struct kr_request
 {
        pkt->opt_rr = knot_rrset_copy(req->ctx->opt_rr, &pkt->mm);
        size_t wire_size = knot_edns_wire_size(pkt->opt_rr);
-       if (cookies_control.enabled) {
+       if (kr_cookies_control.enabled) {
                wire_size += KR_COOKIE_PLD_MAX;
        }
        return knot_pkt_reserve(pkt, wire_size);
@@ -361,10 +361,6 @@ static int query_finalize(struct kr_request *request, struct kr_query *qry, knot
                                knot_edns_set_do(pkt->opt_rr);
                                knot_wire_set_cd(pkt->wire);
                        }
-                       /* Insert cookies. */
-                       if (cookies_control.enabled) {
-                               ret = kr_pkt_add_cookie(pkt);
-                       }
                        ret = edns_put(pkt);
                }
        }