diff --git a/lib/cookies/control.c b/lib/cookies/control.c new file mode 100644 index 0000000000000000000000000000000000000000..1873cb175b9a24b125dbc1ccf30e35c72e6bdb53 --- /dev/null +++ b/lib/cookies/control.c @@ -0,0 +1,68 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdint.h> +#include <libknot/error.h> +#include <libknot/rrtype/opt_cookie.h> + +#include "lib/cookies/control.h" + +struct cookies_control cookies_control = { + .enabled = true +}; + +static int opt_rr_add_cookies(knot_rrset_t *opt_rr, + uint8_t cc[KNOT_OPT_COOKIE_CLNT], + uint8_t *sc, uint16_t sc_len, + knot_mm_t *mm) +{ + int ret; + uint16_t cookies_size = 0; + uint8_t *cookies_data = NULL; + + cookies_size = knot_edns_opt_cookie_data_len(sc_len); + + ret = knot_edns_reserve_option(opt_rr, KNOT_EDNS_OPTION_COOKIE, + cookies_size, &cookies_data, mm); + if (ret != KNOT_EOK) { + return ret; + } + assert(cookies_data != NULL); + + ret = knot_edns_opt_cookie_create(cc, sc, sc_len, + cookies_data, &cookies_size); + if (ret != KNOT_EOK) { + return ret; + } + + assert(cookies_size == knot_edns_opt_cookie_data_len(sc_len)); + + return KNOT_EOK; +} + +int kr_pkt_add_cookie(knot_pkt_t *pkt) +{ + assert(pkt); + assert(pkt->opt_rr); + + /* 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}; + + int ret = opt_rr_add_cookies(pkt->opt_rr, cc, NULL, 0, &pkt->mm); + return ret; +} diff --git a/lib/cookies/control.h b/lib/cookies/control.h new file mode 100644 index 0000000000000000000000000000000000000000..179195c6c82bd1292b58a0a364c1d7ef101e004d --- /dev/null +++ b/lib/cookies/control.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <libknot/packet/pkt.h> +#include <stdbool.h> + +#define KR_COOKIE_PLD_MAX 44 /* Define in libknot. */ + +/** DNSSEC cookies controlling structure. */ +struct cookies_control { + bool enabled; /*!< Enabled/disables DNS cookies functionality. */ + /* Cache. */ +}; + +/** Global cookies control. */ +extern struct cookies_control cookies_control; + +/** + * Insert a DNS cookie into the packet. + * @note The packet must already contain ENDS section. + * @param pkt Packet. + */ +int kr_pkt_add_cookie(knot_pkt_t *pkt); diff --git a/lib/lib.mk b/lib/lib.mk index 1142699b190609d45d657573045f86fa2b50d766..b4cb4a99815062acde36cd8f78dca6c5e11d0d54 100644 --- a/lib/lib.mk +++ b/lib/lib.mk @@ -4,6 +4,7 @@ libkres_SOURCES := \ lib/layer/validate.c \ lib/layer/rrcache.c \ lib/layer/pktcache.c \ + lib/cookies/control.c \ lib/dnssec/nsec.c \ lib/dnssec/nsec3.c \ lib/dnssec/signature.c \ @@ -23,6 +24,7 @@ libkres_HEADERS := \ lib/generic/map.h \ lib/generic/set.h \ lib/layer.h \ + lib/cookies/control.h \ lib/dnssec/nsec.h \ lib/dnssec/nsec3.h \ lib/dnssec/signature.h \ diff --git a/lib/resolve.c b/lib/resolve.c index 01dfdaa18ce205379b3e5ce20ff745c05a70ed3b..243b3d336e2424563854742436954719702d0eb1 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -27,6 +27,7 @@ #include "lib/rplan.h" #include "lib/layer/iterate.h" #include "lib/dnssec/ta.h" +#include "lib/cookies/control.h" #define DEBUG_MSG(qry, fmt...) QRDEBUG((qry), "resl", fmt) @@ -266,7 +267,11 @@ static int edns_put(knot_pkt_t *pkt) static int edns_create(knot_pkt_t *pkt, knot_pkt_t *template, struct kr_request *req) { pkt->opt_rr = knot_rrset_copy(req->ctx->opt_rr, &pkt->mm); - return knot_pkt_reserve(pkt, knot_edns_wire_size(pkt->opt_rr)); + size_t wire_size = knot_edns_wire_size(pkt->opt_rr); + if (cookies_control.enabled) { + wire_size += KR_COOKIE_PLD_MAX; + } + return knot_pkt_reserve(pkt, wire_size); } static int answer_prepare(knot_pkt_t *answer, knot_pkt_t *query, struct kr_request *req) @@ -356,6 +361,10 @@ 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); } }