#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_secret = {
+/* Default client secret. */
+struct secret_quantity dflt_cs = {
.size = KNOT_OPT_COOKIE_CLNT,
- .data = cc
+ .data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
struct cookies_control kr_cookies_control = {
- .enabled = true,
- .secret = &client_secret
+ .enabled = false,
+ .current_cs = &dflt_cs
};
static int opt_rr_add_cookies(knot_rrset_t *opt_rr,
return kr_ok();
}
- if (!cntrl->secret) {
+ if (!cntrl->current_cs) {
return kr_error(EINVAL);
}
* and secret quantity. */
uint8_t cc[KNOT_OPT_COOKIE_CLNT];
int ret = kr_client_cokie_fnv64(cc, clnt_sockaddr, srvr_sockaddr,
- cntrl->secret);
+ cntrl->current_cs);
if (ret != kr_ok()) {
return ret;
}
/** Holds secret quantity. */
struct secret_quantity {
size_t size; /*!< Secret quantity size. */
- const uint8_t *data; /*!< Secret quantity data. */
+ uint8_t data[]; /*!< Secret quantity data. */
};
+/* Default client secret. */
+KR_EXPORT
+extern struct secret_quantity dflt_cs;
+
/** DNSSEC cookies controlling structure. */
struct cookies_control {
bool enabled; /*!< Enabled/disables DNS cookies functionality. */
- struct secret_quantity *secret; /*!< Client secret quantity. */
+
+ struct secret_quantity *current_cs; /*!< current client secret */
+ struct secret_quantity *recent_cs; /*!< recent client secret */
struct kr_cache cache; /*!< Server cookies cache. */
};
const struct sockaddr *srvr_sockaddr = NULL;
/* Abusing name server reputation mechanism to obtain IP addresses. */
- srvr_sockaddr = guess_server_addr(cc, ns, kr_cookies_control.secret);
+ srvr_sockaddr = guess_server_addr(cc, ns,
+ kr_cookies_control.current_cs);
+ bool returned_current = (srvr_sockaddr != NULL);
+ if (!srvr_sockaddr && kr_cookies_control.recent_cs) {
+ /* Try recent client secret to check obtained cookie. */
+ srvr_sockaddr = guess_server_addr(cc, ns,
+ kr_cookies_control.recent_cs);
+ }
if (!srvr_sockaddr) {
DEBUG_MSG(NULL, "%s\n", "could not match received cookie");
DEBUG_MSG(NULL, "%s\n", "falling back to TCP");
return KNOT_STATE_PRODUCE;
}
- if (!is_cookie_cached(&kr_cookies_control.cache, srvr_sockaddr,
+ /* Don't cache received cookies that don't match the current secret. */
+ if (returned_current &&
+ !is_cookie_cached(&kr_cookies_control.cache, srvr_sockaddr,
cookie_opt)) {
DEBUG_MSG(NULL, "%s\n", "caching server cookie");
struct engine *engine = module->data;
DEBUG_MSG(NULL, "initialising with engine %p\n", (void *) engine);
- kr_cookies_control.enabled = true; /* Leave enabled by default. */
+ memset(&kr_cookies_control, 0, sizeof(kr_cookies_control));
+
+ kr_cookies_control.enabled = false;
+
+ kr_cookies_control.current_cs = &dflt_cs;
+
memset(&kr_cookies_control.cache, 0, sizeof(kr_cookies_control.cache));
struct storage_api *lmdb_storage_api = find_storage_api(&engine->storage_registry,
KR_EXPORT
int cookies_deinit(struct kr_module *module)
{
+ kr_cookies_control.enabled = false;
+
+ if (kr_cookies_control.recent_cs &&
+ kr_cookies_control.recent_cs != &dflt_cs) {
+ free(kr_cookies_control.recent_cs);
+ }
+ kr_cookies_control.recent_cs = NULL;
+
+ if (kr_cookies_control.current_cs &&
+ kr_cookies_control.current_cs != &dflt_cs) {
+ free(kr_cookies_control.current_cs);
+ }
+ kr_cookies_control.current_cs = &dflt_cs;
+
+ kr_cache_close(&kr_cookies_control.cache);
+
return kr_ok();
}