#include <malloc.h>
#endif
#include <assert.h>
+#include "lib/cookies/control.h"
#include "lib/utils.h"
#include "lib/layer.h"
#include "daemon/worker.h"
}
}
+/** 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);
/* 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. */
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,
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);
}
#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);