return KNOT_STATE_CONSUME;
}
-#if defined(ENABLE_COOKIES)
-/**
- * @brief Put cookie into answer packet.
- * @param clnt_sockaddr client socket address
- * @param srvr_sett settings structure of the server cookie algorithm
- * @param cookies obtained cookies
- * @param answer answer packet
- * @return state
- */
-static int cookie_answer(const void *clnt_sockaddr,
- const struct kr_cookie_settings *srvr_sett,
- struct knot_dns_cookies *cookies, knot_pkt_t *answer)
-{
- assert(srvr_sett && cookies && answer);
-
- /* Initialise answer. */
- knot_wire_set_qr(answer->wire);
- knot_wire_clear_aa(answer->wire);
- knot_wire_set_ra(answer->wire);
- knot_wire_set_rcode(answer->wire, KNOT_RCODE_NOERROR);
-
- struct knot_sc_private srvr_data = {
- .clnt_sockaddr = clnt_sockaddr,
- .secret_data = srvr_sett->current.secr->data,
- .secret_len = srvr_sett->current.secr->size
- };
-
- struct timeval tv;
- gettimeofday(&tv, NULL);
-
- struct kr_nonce_input nonce = {
- .rand = kr_rand_uint(UINT32_MAX),
- .time = tv.tv_sec
- };
-
- /* Add fres cookie into the answer. */
- int ret = kr_answer_write_cookie(&srvr_data,
- cookies->cc, cookies->cc_len, &nonce,
- kr_sc_algs[srvr_sett->current.alg_id], answer);
- if (ret != kr_ok()) {
- return KNOT_STATE_FAIL;
- }
-
- /* Check server cookie only with current settings. */
- ret = knot_sc_check(KR_NONCE_LEN, cookies, &srvr_data,
- kr_sc_algs[srvr_sett->current.alg_id]);
- if (ret != KNOT_EOK) {
- /* RFC7873 5.4 */
- kr_pkt_set_ext_rcode(answer, KNOT_RCODE_BADCOOKIE);
- return KNOT_STATE_FAIL | KNOT_STATE_DONE;
- }
-
- return KNOT_STATE_DONE;
-}
-#endif /* defined(ENABLE_COOKIES) */
-
static int resolve_query(struct kr_request *request, const knot_pkt_t *packet)
{
struct kr_rplan *rplan = &request->rplan;
uint16_t qtype = knot_pkt_qtype(packet);
struct kr_query *qry = kr_rplan_push(rplan, NULL, qname, qclass, qtype);
if (!qry) {
-#if defined(ENABLE_COOKIES)
- /* RFC7873 5.4 specifies a query for server cookie. Such query
- * has QDCOUNT == 0 and contains a cookie option.
- *
- * The layers don't expect to handle queries with QDCOUNT != 1
- * so such queries are handled directly here. */
- struct knot_dns_cookies cookies = { 0, };
- uint8_t *cookie_opt = kr_no_question_cookie_query(packet);
- if (cookie_opt && request->ctx->cookie_ctx.clnt.enabled) {
- if (kr_ok() != kr_parse_cookie_opt(cookie_opt,
- &cookies)) {
- /* RFC7873 5.2.2 malformed cookie. */
- knot_wire_set_rcode(request->answer->wire,
- KNOT_RCODE_FORMERR);
- return KNOT_STATE_FAIL;
- }
- }
-
- return cookie_answer(request->qsource.addr,
- &request->ctx->cookie_ctx.srvr,
- &cookies, request->answer);
-#else /* !defined(ENABLE_COOKIES) */
return KNOT_STATE_FAIL;
-#endif /* defined(ENABLE_COOKIES) */
}
/* Deferred zone cut lookup for this query. */
static struct kr_query *query_create(knot_mm_t *pool, const knot_dname_t *name)
{
- if (name == NULL) {
- return NULL;
- }
-
struct kr_query *qry = mm_alloc(pool, sizeof(struct kr_query));
if (qry == NULL) {
return NULL;
}
memset(qry, 0, sizeof(struct kr_query));
- qry->sname = knot_dname_copy(name, pool);
- if (qry->sname == NULL) {
- mm_free(pool, qry);
- return NULL;
+ if (name != NULL) {
+ qry->sname = knot_dname_copy(name, pool);
+ if (qry->sname == NULL) {
+ mm_free(pool, qry);
+ return NULL;
+ }
+ qry->qdcount = 1;
}
knot_dname_to_lower(qry->sname);
struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
const knot_dname_t *name, uint16_t cls, uint16_t type)
{
- if (rplan == NULL || name == NULL) {
+ if (rplan == NULL) {
return NULL;
}
.time = req->current_query->timestamp.tv_sec
};
+ const struct kr_query *qry = req->current_query;
+
if (!cookies.sc) {
- /* Request has no server cookie. TODO -- Silently discard? */
- if (!ignore_badcookie) {
+ /* Request has no server cookie. */
+ if (qry->qdcount == 0) {
+ /* RFC7873 5.4 */
+ return_state = KNOT_STATE_DONE;
+ } else if (!ignore_badcookie) { /* TODO -- Silently discard? */
/* Generate BADCOOKIE response. */
DEBUG_MSG(NULL, "%s\n",
"request is missing server cookie");
kr_sc_algs[srvr_sett->recent.alg_id]);
}
if (ret != KNOT_EOK) {
- /* TODO -- Silently discard? */
- if (!ignore_badcookie) {
+ /* Invalid server cookie. */
+ if (qry->qdcount == 0) {
+ /* RFC7873 5.4 */
+ kr_pkt_set_ext_rcode(req->answer, KNOT_RCODE_BADCOOKIE);
+ return_state = KNOT_STATE_DONE | KNOT_STATE_FAIL;
+ } else if (!ignore_badcookie) { /* TODO -- Silently discard? */
/* Generate BADCOOKIE response. */
DEBUG_MSG(NULL, "%s\n",
"request has invalid server cookie");