Commit 3de76924 authored by Vladimír Čunát's avatar Vladimír Čunát

Merge !699: changes around checkout layer from cloudflare

parents a0aabdea f3607b42
Pipeline #42607 canceled with stages
in 2 minutes and 6 seconds
......@@ -575,7 +575,6 @@ static int qr_task_send(struct qr_task *task, struct session *session,
int ret = 0;
struct request_ctx *ctx = task->ctx;
struct kr_request *req = &ctx->req;
uv_handle_t *handle = session_get_handle(session);
assert(handle && handle->data == session);
......@@ -605,27 +604,6 @@ static int qr_task_send(struct qr_task *task, struct session *session,
worker_task_pkt_set_msgid(task, msg_id);
}
if (knot_wire_get_qr(pkt->wire) == 0) {
/*
* Query must be finalised using destination address before
* sending.
*
* Libuv does not offer a convenient way how to obtain a source
* IP address from a UDP handle that has been initialised using
* uv_udp_init(). The uv_udp_getsockname() fails because of the
* lazy socket initialisation.
*
* @note -- A solution might be opening a separate socket and
* trying to obtain the IP address from it.
*/
ret = kr_resolve_checkout(req, NULL, addr,
is_stream ? SOCK_STREAM : SOCK_DGRAM,
pkt);
if (ret != 0) {
return ret;
}
}
uv_handle_t *ioreq = malloc(is_stream ? sizeof(uv_write_t) : sizeof(uv_udp_send_t));
if (!ioreq) {
return qr_task_on_send(task, handle, kr_error(ENOMEM));
......@@ -947,7 +925,12 @@ static uv_handle_t *retransmit(struct qr_task *task)
if (task->pending_count >= MAX_PENDING) {
return ret;
}
ret = ioreq_spawn(task->ctx->worker, SOCK_DGRAM, choice->sin6_family);
/* Checkout answer before sending it */
struct request_ctx *ctx = task->ctx;
if (kr_resolve_checkout(&ctx->req, NULL, (struct sockaddr *)choice, SOCK_DGRAM, task->pktbuf) != 0) {
return ret;
}
ret = ioreq_spawn(ctx->worker, SOCK_DGRAM, choice->sin6_family);
if (!ret) {
return ret;
}
......@@ -1299,7 +1282,6 @@ static int tcp_task_step(struct qr_task *task,
const struct sockaddr *packet_source, knot_pkt_t *packet)
{
assert(task->pending_count == 0);
struct request_ctx *ctx = task->ctx;
const struct sockaddr *addr =
packet_source ? packet_source : task->addrlist;
......@@ -1310,6 +1292,13 @@ static int tcp_task_step(struct qr_task *task,
subreq_finalize(task, packet_source, packet);
return qr_task_finalize(task, KR_STATE_FAIL);
}
/* Checkout task before connecting */
struct request_ctx *ctx = task->ctx;
if (kr_resolve_checkout(&ctx->req, NULL, (struct sockaddr *)addr,
SOCK_STREAM, task->pktbuf) != 0) {
subreq_finalize(task, packet_source, packet);
return qr_task_finalize(task, KR_STATE_FAIL);
}
int ret;
struct session* session = NULL;
if ((session = worker_find_tcp_waiting(ctx->worker, addr)) != NULL) {
......
......@@ -144,6 +144,9 @@ KR_CONST static inline bool isletter(unsigned chr)
*/
static void randomized_qname_case(knot_dname_t * restrict qname, uint32_t secret)
{
if (secret == 0) {
return;
}
assert(qname);
const int len = knot_dname_size(qname) - 2; /* Skip first, last label. */
for (int i = 0; i < len; ++i) {
......@@ -715,7 +718,6 @@ static int query_finalize(struct kr_request *request, struct kr_query *qry, knot
knot_edns_set_do(pkt->opt_rr);
knot_wire_set_cd(pkt->wire);
}
ret = edns_put(pkt, true);
}
}
return ret;
......@@ -1515,7 +1517,7 @@ static bool outbound_request_update_cookies(struct kr_request *req,
}
#endif /* defined(ENABLE_COOKIES) */
int kr_resolve_checkout(struct kr_request *request, struct sockaddr *src,
int kr_resolve_checkout(struct kr_request *request, const struct sockaddr *src,
struct sockaddr *dst, int type, knot_pkt_t *packet)
{
/* @todo: Update documentation if this function becomes approved. */
......@@ -1532,14 +1534,6 @@ int kr_resolve_checkout(struct kr_request *request, struct sockaddr *src,
}
struct kr_query *qry = array_tail(rplan->pending);
/* Run the checkout layers and cancel on failure. */
int state = request->state;
ITERATE_LAYERS(request, qry, checkout, packet, dst, type);
if (request->state == KR_STATE_FAIL) {
request->state = state; /* Restore */
return kr_error(ECANCELED);
}
#if defined(ENABLE_COOKIES)
/* Update DNS cookies in request. */
if (type == SOCK_DGRAM) { /* @todo: Add cookies also over TCP? */
......@@ -1559,6 +1553,33 @@ int kr_resolve_checkout(struct kr_request *request, struct sockaddr *src,
return kr_error(EINVAL);
}
/* Track changes in minimization secret to enable/disable minimization */
uint32_t old_minimization_secret = qry->secret;
/* Run the checkout layers and cancel on failure.
* The checkout layer doesn't persist the state, so canceled subrequests
* don't affect the resolution or rest of the processing. */
int state = request->state;
ITERATE_LAYERS(request, qry, checkout, packet, dst, type);
if (request->state == KR_STATE_FAIL) {
request->state = state; /* Restore */
return kr_error(ECANCELED);
}
/* Randomize query case (if secret changed) */
knot_dname_t *qname = (knot_dname_t *)knot_pkt_qname(packet);
if (qry->secret != old_minimization_secret) {
randomized_qname_case(qname, qry->secret);
}
/* Write down OPT unless in safemode */
if (!(qry->flags.SAFEMODE)) {
ret = edns_put(packet, true);
if (ret != 0) {
return kr_error(EINVAL);
}
}
WITH_VERBOSE(qry) {
char ns_str[INET6_ADDRSTRLEN];
......
......@@ -298,7 +298,7 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t
* @return kr_ok() or error code
*/
KR_EXPORT
int kr_resolve_checkout(struct kr_request *request, struct sockaddr *src,
int kr_resolve_checkout(struct kr_request *request, const struct sockaddr *src,
struct sockaddr *dst, int type, knot_pkt_t *packet);
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment