diff --git a/lib/cookies/helper.c b/lib/cookies/helper.c index 6f8616170031f9029b0d0ca0e366c7577a8a9891..019b863dd40aaf241dbf001f8d01bd751c98c531 100644 --- a/lib/cookies/helper.c +++ b/lib/cookies/helper.c @@ -46,9 +46,9 @@ static const uint8_t *peek_and_check_cc(kr_cookie_lru_t *cache, const void *sa, } /** - * @brief Add a client cookie option into the RR Set. + * @brief Put a client cookie into the RR Set. */ -static int opt_rr_add_cookie(knot_rrset_t *opt_rr, uint8_t *data, +static int opt_rr_put_cookie(knot_rrset_t *opt_rr, uint8_t *data, uint16_t data_len, knot_mm_t *mm) { assert(opt_rr && data && data_len > 0); @@ -84,9 +84,9 @@ static int opt_rr_add_cookie(knot_rrset_t *opt_rr, uint8_t *data, } /** - * @brief Adds entire EDNS option into the RR Set. + * @brief Puts entire EDNS option into the RR Set. */ -static int opt_rr_add_cookie_opt(knot_rrset_t *opt_rr, uint8_t *option, knot_mm_t *mm) +static int opt_rr_put_cookie_opt(knot_rrset_t *opt_rr, uint8_t *option, knot_mm_t *mm) { assert(opt_rr && option); @@ -99,20 +99,20 @@ static int opt_rr_add_cookie_opt(knot_rrset_t *opt_rr, uint8_t *option, knot_mm_ uint16_t opt_len = knot_edns_opt_get_length(option); uint8_t *opt_data = knot_edns_opt_get_data(option); - return opt_rr_add_cookie(opt_rr, opt_data, opt_len, mm); + return opt_rr_put_cookie(opt_rr, opt_data, opt_len, mm); } int kr_request_put_cookie(const struct kr_cookie_comp *clnt_comp, kr_cookie_lru_t *cookie_cache, const struct sockaddr *clnt_sa, const struct sockaddr *srvr_sa, - knot_pkt_t *pkt) + struct kr_request *req) { - if (!clnt_comp || !pkt) { + if (!clnt_comp || !req) { return kr_error(EINVAL); } - if (!pkt->opt_rr) { + if (!req->ctx->opt_rr) { return kr_ok(); } @@ -120,8 +120,10 @@ int kr_request_put_cookie(const struct kr_cookie_comp *clnt_comp, return kr_error(EINVAL); } - /* Generate client cookie from client address, server address and - * secret quantity. */ + /* + * Generate client cookie from client address, server address and + * secret quantity. + */ struct knot_cc_input input = { .clnt_sockaddr = clnt_sa, .srvr_sockaddr = srvr_sa, @@ -141,25 +143,18 @@ int kr_request_put_cookie(const struct kr_cookie_comp *clnt_comp, const uint8_t *cached_cookie = peek_and_check_cc(cookie_cache, srvr_sa, cc, cc_len); - /* This is a very nasty hack that prevents the packet to be corrupted - * when using contemporary 'Cookie interface'. */ - assert(pkt->current == KNOT_ADDITIONAL); - pkt->sections[KNOT_ADDITIONAL].count -= 1; - pkt->rrset_count -= 1; - pkt->size -= knot_edns_wire_size(pkt->opt_rr); - knot_wire_set_arcount(pkt->wire, knot_wire_get_arcount(pkt->wire) - 1); - + /* Add cookie option. */ int ret; if (cached_cookie) { - ret = opt_rr_add_cookie_opt(pkt->opt_rr, + ret = opt_rr_put_cookie_opt(req->ctx->opt_rr, (uint8_t *)cached_cookie, - &pkt->mm); + req->ctx->pool); } else { - ret = opt_rr_add_cookie(pkt->opt_rr, cc, cc_len, &pkt->mm); + ret = opt_rr_put_cookie(req->ctx->opt_rr, cc, cc_len, + req->ctx->pool); } - /* Write to packet. */ - return knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, pkt->opt_rr, KNOT_PF_FREE); + return ret; } int kr_answer_write_cookie(const struct knot_sc_private *srvr_data, diff --git a/lib/cookies/helper.h b/lib/cookies/helper.h index 8ceee2029050782dfa1027c6449448fe4ac6107f..b876c8048fd039720ea8325f6fb49d28dc4ee5e6 100644 --- a/lib/cookies/helper.h +++ b/lib/cookies/helper.h @@ -23,15 +23,16 @@ #include "lib/cookies/lru_cache.h" #include "lib/cookies/nonce.h" #include "lib/defines.h" +#include "lib/resolve.h" /** - * @brief Insert a DNS cookie into query packet. - * @note The packet must already contain ENDS section. + * @brief Updates DNS cookie in the request EDNS options. + * @note This function must be called before the request packet is finalised. * @param clnt_comp client cookie control structure * @param cookie_cache cookie cache * @param clnt_sa client socket address * @param srvr_sa server socket address - * @param pkt DNS request packet + * @param req name resolution request * @return kr_ok() or error code */ KR_EXPORT @@ -39,7 +40,7 @@ int kr_request_put_cookie(const struct kr_cookie_comp *clnt_comp, kr_cookie_lru_t *cookie_cache, const struct sockaddr *clnt_sa, const struct sockaddr *srvr_sa, - knot_pkt_t *pkt); + struct kr_request *req); /** * @brief Inserts a cookie option into the OPT RR. It does not write any diff --git a/lib/resolve.c b/lib/resolve.c index 2e910f943fc4ad33cf25f85d2d564c5081a7cdfc..9d5a1da40d868d6283e0d54d77233d001b40cb5e 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -857,12 +857,10 @@ ns_election: #if defined(ENABLE_COOKIES) /** Update DNS cookie data in packet. */ -static bool outbound_query_add_cookies(struct kr_request *req, - const struct sockaddr *dst, - knot_pkt_t *pkt) +static bool outbound_request_update_cookies(struct kr_request *req, + const struct sockaddr *dst) { assert(req); - assert(pkt); /* RFC7873 4.1 strongly requires server address. */ if (!dst) { @@ -872,7 +870,7 @@ static bool outbound_query_add_cookies(struct kr_request *req, struct kr_cookie_settings *clnt_sett = &req->ctx->cookie_ctx.clnt; /* Cookies disabled or packet has no ENDS section. */ - if (!clnt_sett->enabled || !pkt->opt_rr) { + if (!clnt_sett->enabled) { return true; } @@ -890,7 +888,7 @@ static bool outbound_query_add_cookies(struct kr_request *req, */ kr_request_put_cookie(&clnt_sett->current, req->ctx->cache_cookie, - NULL, dst, pkt); + NULL, dst, req); return true; } @@ -919,13 +917,8 @@ int kr_resolve_query_finalize(struct kr_request *request, struct sockaddr *dst, * cons: Additional stress on API before sending every packet. */ - int ret = query_finalize(request, qry, packet); - if (ret != 0) { - return KNOT_STATE_FAIL; - } - #if defined(ENABLE_COOKIES) - /* Update DNS cookies data in query. */ + /* Update DNS cookies in request. */ if (type == SOCK_DGRAM) { /* @todo: Add cookies also over TCP? */ /* The actual server IP address is needed before generating the * actual cookie. If we don't know the server address then we @@ -933,12 +926,17 @@ int kr_resolve_query_finalize(struct kr_request *request, struct sockaddr *dst, * 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 (!outbound_query_add_cookies(request, dst, packet)) { + if (!outbound_request_update_cookies(request, dst)) { return KNOT_STATE_FAIL; } } #endif /* defined(ENABLE_COOKIES) */ + int ret = query_finalize(request, qry, packet); + if (ret != 0) { + return KNOT_STATE_FAIL; + } + WITH_DEBUG { char qname_str[KNOT_DNAME_MAXLEN], zonecut_str[KNOT_DNAME_MAXLEN], ns_str[INET6_ADDRSTRLEN], type_str[16]; knot_dname_to_str(qname_str, knot_pkt_qname(packet), sizeof(qname_str));