diff --git a/daemon/worker.c b/daemon/worker.c index 2d13e0ba3e1b63b9d2ac4785e4d407e51a5d372f..c3542ceb8190dbaebd807324f2f8f48f95b57b7d 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -451,16 +451,18 @@ static void on_write(uv_write_t *req, int status) #if defined(ENABLE_COOKIES) /** Update DNS cookie data in packet. */ -static bool subreq_update_cookies(uv_udp_t *handle, struct sockaddr *srvr_addr, - struct kr_cache *cookie_cache, - knot_pkt_t *pkt) +static bool subreq_update_cookies(struct qr_task *task, uv_udp_t *handle, + struct sockaddr *srvr_addr, knot_pkt_t *pkt) { + assert(task); assert(handle); assert(srvr_addr); assert(pkt); + struct kr_cookie_settings *clnt_sett = &task->req.ctx->cookie_ctx.clnt; + /* Cookies disabled or packet has no ENDS section. */ - if (!kr_glob_cookie_ctx.clnt.enabled || !pkt->opt_rr) { + if (!clnt_sett->enabled || !pkt->opt_rr) { return true; } @@ -484,7 +486,8 @@ static bool subreq_update_cookies(uv_udp_t *handle, struct sockaddr *srvr_addr, } #endif /* 0 */ - kr_request_put_cookie(&kr_glob_cookie_ctx.clnt.current, cookie_cache, + kr_request_put_cookie(&clnt_sett->current, + &task->worker->engine->resolver.cache, (struct sockaddr*) sockaddr_ptr, srvr_addr, pkt); return true; @@ -513,13 +516,15 @@ static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockad if (handle->type == UV_UDP) { #if defined(ENABLE_COOKIES) /* The actual server IP address is needed before generating the - * actual cookie. Also the resolver somehow mangles the query - * packets before building the query i.e. the space needed for - * the cookie cannot be allocated in the cookie layer. */ + * actual cookie. If we don't know the server address then we + * also don't know the actual cookie size. + * Also the resolver somehow mangles the query packets before + * building the query i.e. the space needed for the cookie + * cannot be allocated in the cookie layer. */ if (knot_wire_get_qr(pkt->wire) == 0) { /* Update DNS cookies data in query. */ - subreq_update_cookies((uv_udp_t *) handle, addr, - &task->worker->engine->resolver.cache, pkt); + subreq_update_cookies(task, (uv_udp_t *) handle, addr, + pkt); } #endif /* defined(ENABLE_COOKIES) */ diff --git a/lib/cookies/control.c b/lib/cookies/control.c index 87b9dc52dfd315bc21ebff2caf866e8e0db0a14c..6e0fec3c502e21f8d70f9b94dc14eb3d0b99eb31 100644 --- a/lib/cookies/control.c +++ b/lib/cookies/control.c @@ -14,10 +14,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <string.h> + #include "lib/cookies/control.h" -struct kr_cookie_ctx kr_glob_cookie_ctx = { - .clnt = { false, { NULL, -1 }, { NULL, -1} }, - .srvr = { false, { NULL, -1 }, { NULL, -1} }, - .cache_ttl = DFLT_COOKIE_TTL -}; +void kr_cookie_ctx_init(struct kr_cookie_ctx *ctx) +{ + if (!ctx) { + return; + } + + memset(ctx, 0, sizeof(*ctx)); + + ctx->clnt.current.alg_id = ctx->clnt.recent.alg_id = -1; + ctx->srvr.current.alg_id = ctx->srvr.recent.alg_id = -1; + + ctx->cache_ttl = DFLT_COOKIE_TTL; +} diff --git a/lib/cookies/control.h b/lib/cookies/control.h index 97e6e5ad98a7ef11dc83b84c8a63cc92304a5abc..beb544c2c281bd30bb0fb27d127ac4bffa92b9a1 100644 --- a/lib/cookies/control.h +++ b/lib/cookies/control.h @@ -16,13 +16,10 @@ #pragma once -#include <libknot/rrtype/opt-cookie.h> #include <stdbool.h> #include <stdint.h> #include <stdlib.h> -#include "lib/cookies/alg_containers.h" -#include "lib/cache.h" #include "lib/defines.h" /** Holds secret quantity. */ @@ -56,6 +53,9 @@ struct kr_cookie_ctx { uint32_t cache_ttl; /**< TTL used when caching cookies */ }; -/** Global cookie control context. */ +/** + * @brief Initialises cookie control context. + * @param ctx cookie control context + */ KR_EXPORT -extern struct kr_cookie_ctx kr_glob_cookie_ctx; +void kr_cookie_ctx_init(struct kr_cookie_ctx *ctx); diff --git a/lib/cookies/helper.h b/lib/cookies/helper.h index ad780972d2323c00d22f0636b2b38c478ea583c1..ddacbc11654299e4a83190d3b9b26bf340c1695d 100644 --- a/lib/cookies/helper.h +++ b/lib/cookies/helper.h @@ -16,10 +16,13 @@ #pragma once +#include <libknot/rrtype/opt-cookie.h> #include <libknot/packet/pkt.h> +#include "lib/cookies/alg_containers.h" #include "lib/cookies/control.h" #include "lib/cookies/nonce.h" +#include "lib/cache.h" #include "lib/defines.h" /** diff --git a/lib/layer/cookiemonster.c b/lib/layer/cookiemonster.c index 73032f7b087f6ebdc01c1676d0401433d0fc5257..cf60a8e1f9542135cd7a647e316b5c1d02087307 100644 --- a/lib/layer/cookiemonster.c +++ b/lib/layer/cookiemonster.c @@ -308,8 +308,9 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt) { struct kr_request *req = ctx->data; struct kr_query *qry = req->current_query; + struct kr_cookie_ctx *cookie_ctx = &req->ctx->cookie_ctx; - if (!kr_glob_cookie_ctx.clnt.enabled || (qry->flags & QUERY_TCP)) { + if (!cookie_ctx->clnt.enabled || (qry->flags & QUERY_TCP)) { return ctx->state; } @@ -338,8 +339,8 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt) return ctx->state; } - if (!check_cookie_content_and_cache(&kr_glob_cookie_ctx.clnt, - kr_glob_cookie_ctx.cache_ttl, qry, + if (!check_cookie_content_and_cache(&cookie_ctx->clnt, + cookie_ctx->cache_ttl, qry, pkt_cookie_opt, cookie_cache)) { return KNOT_STATE_FAIL; } @@ -383,13 +384,15 @@ static inline uint8_t *req_cookie_option(struct kr_request *req) static int check_request(knot_layer_t *ctx, void *module_param) { - if (!kr_glob_cookie_ctx.srvr.enabled) { + struct kr_request *req = ctx->data; + struct kr_cookie_settings *srvr_sett = &req->ctx->cookie_ctx.srvr; + + if (!srvr_sett->enabled) { /* TODO -- IS there a way how to determine whether the original * request came via TCP? */ return ctx->state; } - struct kr_request *req = ctx->data; uint8_t *req_cookie_opt = req_cookie_option(req); if (!req_cookie_opt) { return ctx->state; /* Don't do anything without cookies. */ @@ -406,7 +409,6 @@ static int check_request(knot_layer_t *ctx, void *module_param) bool ignore_badcookie = true; /* TODO -- Occasionally ignore? */ - struct kr_cookie_settings *srvr_sett = &kr_glob_cookie_ctx.srvr; if (!req->qsource.addr || !srvr_sett->current.secr || (srvr_sett->current.alg_id < 0)) { DEBUG_MSG(NULL, "%s\n", "missing server cookie context"); diff --git a/lib/resolve.c b/lib/resolve.c index 5d11b54cc428ac38911278dcce51619d34031d07..94511d502035c4fe1128b253d68c222085956fdd 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -273,7 +273,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); #if defined(ENABLE_COOKIES) size_t wire_size = knot_edns_wire_size(pkt->opt_rr); - if (kr_glob_cookie_ctx.clnt.enabled) { + if (req->ctx->cookie_ctx.clnt.enabled) { wire_size += KR_COOKIE_OPT_MAX_LEN; } return knot_pkt_reserve(pkt, wire_size); @@ -462,7 +462,7 @@ static int resolve_query(struct kr_request *request, const knot_pkt_t *packet) * so such queries are handled directly here. */ struct knot_dns_cookies cookies = { 0, }; uint8_t *cookie_opt = kr_is_cookie_query(packet); - if (cookie_opt && kr_glob_cookie_ctx.clnt.enabled) { + if (cookie_opt && request->ctx->cookie_ctx.clnt.enabled) { if (kr_ok() != kr_parse_cookie_opt(cookie_opt, &cookies)) { /* TODO -- KNOT_RCODE_FORMERR? */ @@ -471,7 +471,7 @@ static int resolve_query(struct kr_request *request, const knot_pkt_t *packet) } return cookie_answer(request->qsource.addr, - &kr_glob_cookie_ctx.srvr, + &request->ctx->cookie_ctx.srvr, &cookies, request->answer); #else /* !defined(ENABLE_COOKIES) */ return KNOT_STATE_FAIL; diff --git a/lib/resolve.h b/lib/resolve.h index 1f5fbecfab4ed1cbdb91402716969b0d6584459d..a2f116f69b1879afdc8056309ac479763e04acec 100644 --- a/lib/resolve.h +++ b/lib/resolve.h @@ -19,6 +19,7 @@ #include <netinet/in.h> #include <libknot/packet/pkt.h> +#include "lib/cookies/control.h" #include "lib/layer.h" #include "lib/generic/map.h" #include "lib/generic/array.h" @@ -92,6 +93,11 @@ struct kr_context kr_nsrep_lru_t *cache_rtt; kr_nsrep_lru_t *cache_rep; module_array_t *modules; +#if defined(ENABLE_COOKIES) + /* The structure should not be held within the cookies module because + * of better access. */ + struct kr_cookie_ctx cookie_ctx; +#endif /* defined(ENABLE_COOKIES) */ knot_mm_t *pool; }; diff --git a/modules/cookiectl/cookiectl.c b/modules/cookiectl/cookiectl.c index 8f1d16b759f720c666a87690cf1faf60ded3a57a..fe62a765e519996d3b986cc1d312a746036a709a 100644 --- a/modules/cookiectl/cookiectl.c +++ b/modules/cookiectl/cookiectl.c @@ -16,6 +16,7 @@ #include <assert.h> #include <ccan/json/json.h> +#include <libknot/rrtype/opt-cookie.h> #include <libknot/db/db_lmdb.h> #include <stdlib.h> #include <string.h> @@ -399,11 +400,14 @@ char *read_config(struct kr_cookie_ctx *ctx) */ static char *cookiectl_config(void *env, struct kr_module *module, const char *args) { + struct kr_cookie_ctx *cookie_ctx = module->data; + assert(cookie_ctx); + /* Apply configuration, if any. */ - apply_config(&kr_glob_cookie_ctx, args); + apply_config(cookie_ctx, args); /* Return current configuration. */ - return read_config(&kr_glob_cookie_ctx); + return read_config(cookie_ctx); } /* @@ -415,7 +419,9 @@ int cookiectl_init(struct kr_module *module) { struct engine *engine = module->data; - memset(&kr_glob_cookie_ctx, 0, sizeof(kr_glob_cookie_ctx)); + struct kr_cookie_ctx *cookie_ctx = &engine->resolver.cookie_ctx; + + kr_cookie_ctx_init(cookie_ctx); struct kr_cookie_secret *cs = new_cookie_secret(KNOT_OPT_COOKIE_CLNT, true); @@ -427,25 +433,24 @@ int cookiectl_init(struct kr_module *module) return kr_error(ENOMEM); } - const knot_lookup_t *lookup; - - kr_glob_cookie_ctx.clnt.enabled = false; - kr_glob_cookie_ctx.clnt.current.secr = cs; - lookup = knot_lookup_by_name(kr_cc_alg_names, "FNV-64"); - assert(lookup); - kr_glob_cookie_ctx.clnt.current.alg_id = lookup->id; - kr_glob_cookie_ctx.clnt.recent.alg_id = -1; + const knot_lookup_t *clookup = knot_lookup_by_name(kr_cc_alg_names, + "FNV-64"); + const knot_lookup_t *slookup = knot_lookup_by_name(kr_sc_alg_names, + "FNV-64"); + if (!clookup || !slookup) { + free(cs); + free(ss); + return kr_error(ENOKEY); + } - kr_glob_cookie_ctx.srvr.enabled = false; - kr_glob_cookie_ctx.srvr.current.secr = ss; - lookup = knot_lookup_by_name(kr_sc_alg_names, "FNV-64"); - assert(lookup); - kr_glob_cookie_ctx.srvr.current.alg_id = lookup->id; - kr_glob_cookie_ctx.srvr.recent.alg_id = -1; + cookie_ctx->clnt.current.secr = cs; + cookie_ctx->clnt.current.alg_id = clookup->id; - kr_glob_cookie_ctx.cache_ttl = DFLT_COOKIE_TTL; + cookie_ctx->srvr.current.secr = ss; + cookie_ctx->srvr.current.alg_id = slookup->id; - module->data = NULL; + /* Replace engine pointer. */ + module->data = cookie_ctx; return kr_ok(); } @@ -453,21 +458,25 @@ int cookiectl_init(struct kr_module *module) KR_EXPORT int cookiectl_deinit(struct kr_module *module) { - kr_glob_cookie_ctx.clnt.enabled = false; + struct engine *engine = module->data; + + struct kr_cookie_ctx *cookie_ctx = module->data; + + cookie_ctx->clnt.enabled = false; - free(kr_glob_cookie_ctx.clnt.recent.secr); - kr_glob_cookie_ctx.clnt.recent.secr = NULL; + free(cookie_ctx->clnt.recent.secr); + cookie_ctx->clnt.recent.secr = NULL; - free(kr_glob_cookie_ctx.clnt.current.secr); - kr_glob_cookie_ctx.clnt.current.secr = NULL; + free(cookie_ctx->clnt.current.secr); + cookie_ctx->clnt.current.secr = NULL; - kr_glob_cookie_ctx.srvr.enabled = false; + cookie_ctx->srvr.enabled = false; - free(kr_glob_cookie_ctx.srvr.recent.secr); - kr_glob_cookie_ctx.srvr.recent.secr = NULL; + free(cookie_ctx->srvr.recent.secr); + cookie_ctx->srvr.recent.secr = NULL; - free(kr_glob_cookie_ctx.srvr.current.secr); - kr_glob_cookie_ctx.srvr.current.secr = NULL; + free(cookie_ctx->srvr.current.secr); + cookie_ctx->srvr.current.secr = NULL; return kr_ok(); }