From 441deaeba6a5dc09950f998b5ebdc979d37f3f8d Mon Sep 17 00:00:00 2001
From: Daniel Salzman <daniel.salzman@nic.cz>
Date: Sun, 30 Jun 2024 22:00:10 +0200
Subject: [PATCH] server: unify handler params initialization

---
 src/knot/server/handler.c      | 13 +++----------
 src/knot/server/handler.h      | 33 ++++++++++++++++++---------------
 src/knot/server/quic-handler.c |  2 +-
 src/knot/server/tcp-handler.c  | 29 +++++++++++++++--------------
 src/knot/server/xdp-handler.c  | 13 +++++++++----
 5 files changed, 46 insertions(+), 44 deletions(-)

diff --git a/src/knot/server/handler.c b/src/knot/server/handler.c
index 66d56a773d..bcd0ec5608 100644
--- a/src/knot/server/handler.c
+++ b/src/knot/server/handler.c
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -97,7 +97,7 @@ static void handle_quic_stream(knot_quic_conn_t *conn, int64_t stream_id, struct
 }
 
 void handle_quic_streams(knot_quic_conn_t *conn, knotd_qdata_params_t *params,
-                         knot_layer_t *layer, void *msg)
+                         knot_layer_t *layer)
 {
 	uint8_t ans_buf[KNOT_WIRE_MAX_PKTSIZE];
 
@@ -108,14 +108,7 @@ void handle_quic_streams(knot_quic_conn_t *conn, knotd_qdata_params_t *params,
 		assert(stream->inbufs != NULL);
 		assert(stream->inbufs->n_inbufs > 0);
 		struct iovec *inbufs = stream->inbufs->inbufs;
-		if (msg) {
-#ifdef ENABLE_XDP
-			params_xdp_update(params, KNOTD_QUERY_PROTO_QUIC, msg,
-			                  knot_quic_conn_rtt(conn), conn);
-#endif // ENABLE_XDP
-		} else {
-			params_update(params, knot_quic_conn_rtt(conn), conn, stream_id);
-		}
+		params_update_quic(params, knot_quic_conn_rtt(conn), conn, stream_id);
 		// NOTE: only the first msg in the stream is used, the rest is dropped.
 		handle_quic_stream(conn, stream_id, &inbufs[0], layer, params,
 		                   ans_buf, sizeof(ans_buf));
diff --git a/src/knot/server/handler.h b/src/knot/server/handler.h
index 730c9301c5..4b63a0c16b 100644
--- a/src/knot/server/handler.h
+++ b/src/knot/server/handler.h
@@ -20,6 +20,7 @@
 #include "knot/query/layer.h"
 #include "knot/server/server.h"
 #include "libknot/xdp/tcp_iobuf.h"
+#include "libknot/quic/tls.h"
 
 #ifdef ENABLE_QUIC
 #include "libknot/quic/quic.h"
@@ -52,17 +53,26 @@ inline static knotd_qdata_params_t params_init(knotd_query_proto_t proto,
 	return params;
 }
 
-inline static void params_update(knotd_qdata_params_t *params, uint32_t rtt,
-                                 struct knot_quic_conn *conn, int64_t stream_id)
+inline static void params_update_tcp(knotd_qdata_params_t *params, uint32_t rtt)
 {
+	params->measured_rtt = rtt;
+}
+
 #ifdef ENABLE_QUIC
+inline static void params_update_quic(knotd_qdata_params_t *params, uint32_t rtt,
+                                      knot_quic_conn_t *conn, int64_t stream_id)
+{
 	params->quic_conn = conn;
-#else
-	assert(conn == NULL);
-#endif
 	params->quic_stream = stream_id;
 	params->measured_rtt = rtt;
 }
+#endif // ENABLE_QUIC
+
+inline static void params_update_tls(knotd_qdata_params_t *params,
+                                     knot_tls_conn_t *conn)
+{
+	params->tls_conn = conn;
+}
 
 #ifdef ENABLE_XDP
 inline static knotd_qdata_params_t params_xdp_init(int sock, server_t *server,
@@ -72,6 +82,7 @@ inline static knotd_qdata_params_t params_xdp_init(int sock, server_t *server,
 		.socket = sock,
 		.thread_id = thread_id,
 		.server = server,
+		.quic_stream = -1,
 	};
 
 	return params;
@@ -79,20 +90,12 @@ inline static knotd_qdata_params_t params_xdp_init(int sock, server_t *server,
 
 inline static void params_xdp_update(knotd_qdata_params_t *params,
                                      knotd_query_proto_t proto,
-                                     struct knot_xdp_msg *msg,
-                                     uint32_t rtt,
-                                     struct knot_quic_conn *conn)
+                                     struct knot_xdp_msg *msg)
 {
 	params->proto = proto;
 	params->remote = (struct sockaddr_storage *)&msg->ip_from;
 	params->local = (struct sockaddr_storage *)&msg->ip_to;
 	params->xdp_msg = msg;
-#ifdef ENABLE_QUIC
-	params->quic_conn = conn;
-#else
-	assert(conn == NULL);
-#endif
-	params->measured_rtt = rtt;
 }
 #endif // ENABLE_XDP
 
@@ -117,7 +120,7 @@ void handle_udp_reply(knotd_qdata_params_t *params, knot_layer_t *layer,
 
 #ifdef ENABLE_QUIC
 void handle_quic_streams(knot_quic_conn_t *conn, knotd_qdata_params_t *params,
-                         knot_layer_t *layer, void *msg);
+                         knot_layer_t *layer);
 #endif // ENABLE_QUIC
 
 void log_swept(knot_sweep_stats_t *stats, bool tcp);
diff --git a/src/knot/server/quic-handler.c b/src/knot/server/quic-handler.c
index 6b3d19f12a..663167ef8b 100644
--- a/src/knot/server/quic-handler.c
+++ b/src/knot/server/quic-handler.c
@@ -101,7 +101,7 @@ void quic_handler(knotd_qdata_params_t *params, knot_layer_t *layer,
 	(void)knot_quic_handle(table, &rpl, idle_close, &conn);
 
 	if (conn != NULL) {
-		handle_quic_streams(conn, params, layer, NULL);
+		handle_quic_streams(conn, params, layer);
 
 		(void)knot_quic_send(table, conn, &rpl, QUIC_MAX_SEND_PER_RECV, 0);
 
diff --git a/src/knot/server/tcp-handler.c b/src/knot/server/tcp-handler.c
index c08f2091cb..7af2f582f8 100644
--- a/src/knot/server/tcp-handler.c
+++ b/src/knot/server/tcp-handler.c
@@ -156,20 +156,20 @@ static unsigned tcp_set_ifaces(const iface_t *ifaces, size_t n_ifaces,
 }
 
 static int tcp_handle(tcp_context_t *tcp, knotd_qdata_params_t *params,
-                      knot_tls_conn_t *tls_conn, struct iovec *rx, struct iovec *tx)
+                      struct iovec *rx, struct iovec *tx)
 {
 	rx->iov_len = KNOT_WIRE_MAX_PKTSIZE;
 	tx->iov_len = KNOT_WIRE_MAX_PKTSIZE;
 
 	/* Receive data. */
 	int recv;
-	if (tls_conn != NULL) {
-		int ret = knot_tls_handshake(tls_conn, true);
+	if (params->tls_conn != NULL) {
+		int ret = knot_tls_handshake(params->tls_conn, true);
 		switch (ret) {
 		case KNOT_EAGAIN: // Unfinished handshake, continue later.
 			return KNOT_EOK;
 		case KNOT_EOK: // Finished handshake, continue with receiving message.
-			recv = knot_tls_recv_dns(tls_conn, rx->iov_base, rx->iov_len);
+			recv = knot_tls_recv_dns(params->tls_conn, rx->iov_base, rx->iov_len);
 			break;
 		default: // E.g. handshake timeout.
 			return ret;
@@ -193,8 +193,8 @@ static int tcp_handle(tcp_context_t *tcp, knotd_qdata_params_t *params,
 		/* Send, if response generation passed and wasn't ignored. */
 		if (ans->size > 0 && send_state(tcp->layer.state)) {
 			int sent;
-			if (tls_conn != NULL) {
-				sent = knot_tls_send_dns(tls_conn, ans->wire, ans->size);
+			if (params->tls_conn != NULL) {
+				sent = knot_tls_send_dns(params->tls_conn, ans->wire, ans->size);
 			} else {
 				sent = net_dns_tcp_send(params->socket, ans->wire, ans->size,
 				                        tcp->io_timeout, NULL);
@@ -269,19 +269,20 @@ static int tcp_event_serve(tcp_context_t *tcp, unsigned i, const iface_t *iface)
 	}
 
 	/* Establish a TLS session. */
-	knot_tls_conn_t *tls_conn = *fdset_ctx2(&tcp->set, i);
-	assert(iface->tls || tls_conn == NULL);
-	if (iface->tls && tls_conn == NULL) {
+	if (iface->tls) {
 		assert(tcp->tls_ctx != NULL);
-		tls_conn = knot_tls_conn_new(tcp->tls_ctx, fd);
+		knot_tls_conn_t *tls_conn = *fdset_ctx2(&tcp->set, i);
 		if (tls_conn == NULL) {
-			return KNOT_ENOMEM;
+			tls_conn = knot_tls_conn_new(tcp->tls_ctx, fd);
+			if (tls_conn == NULL) {
+				return KNOT_ENOMEM;
+			}
+			*fdset_ctx2(&tcp->set, i) = tls_conn;
 		}
-		*fdset_ctx2(&tcp->set, i) = tls_conn;
+		params_update_tls(&params, tls_conn);
 	}
-	params.tls_conn = tls_conn;
 
-	int ret = tcp_handle(tcp, &params, tls_conn, &tcp->iov[0], &tcp->iov[1]);
+	int ret = tcp_handle(tcp, &params, &tcp->iov[0], &tcp->iov[1]);
 	if (ret == KNOT_EOK) {
 		/* Update socket activity timer. */
 		(void)fdset_set_watchdog(&tcp->set, i, tcp->idle_timeout);
diff --git a/src/knot/server/xdp-handler.c b/src/knot/server/xdp-handler.c
index 1cb29a91fa..403bb70cac 100644
--- a/src/knot/server/xdp-handler.c
+++ b/src/knot/server/xdp-handler.c
@@ -197,6 +197,8 @@ static void handle_udp(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
 			continue;
 		}
 
+		params_xdp_update(params, KNOTD_QUERY_PROTO_UDP, msg_recv);
+
 		if (process_query_proto(params, KNOTD_STAGE_PROTO_BEGIN) == KNOTD_PROTO_STATE_BLOCK) {
 			continue;
 		}
@@ -211,7 +213,6 @@ static void handle_udp(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
 		ctx->msg_udp_count++;
 
 		// Prepare a reply.
-		params_xdp_update(params, KNOTD_QUERY_PROTO_UDP, msg_recv, 0, NULL);
 		handle_udp_reply(params, layer, &msg_recv->payload, &msg_send->payload,
 		                 &proxied_remote);
 
@@ -233,6 +234,8 @@ static void handle_tcp(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
 			continue;
 		}
 
+		params_xdp_update(params, KNOTD_QUERY_PROTO_TCP, msg_recv);
+
 		if (process_query_proto(params, KNOTD_STAGE_PROTO_BEGIN) == KNOTD_PROTO_STATE_BLOCK) {
 			continue;
 		}
@@ -249,11 +252,11 @@ static void handle_tcp(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
 			continue;
 		}
 
+		params_update_tcp(params, rl->conn->establish_rtt);
+
 		// Process all complete DNS queries in one TCP stream.
 		for (size_t j = 0; rl->inbf != NULL && j < rl->inbf->n_inbufs; j++) {
 			// Consume the query.
-			params_xdp_update(params, KNOTD_QUERY_PROTO_TCP, ctx->msg_recv,
-			                  rl->conn->establish_rtt, NULL);
 			struct iovec *inbufs = rl->inbf->inbufs;
 			handle_query(params, layer, &inbufs[j], NULL);
 
@@ -294,6 +297,8 @@ static void handle_quic(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
 			continue;
 		}
 
+		params_xdp_update(params, KNOTD_QUERY_PROTO_QUIC, msg_recv);
+
 		if (process_query_proto(params, KNOTD_STAGE_PROTO_BEGIN) == KNOTD_PROTO_STATE_BLOCK) {
 			continue;
 		}
@@ -313,7 +318,7 @@ static void handle_quic(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
 		                       &ctx->quic_relays[i]);
 		knot_quic_conn_t *conn = ctx->quic_relays[i];
 
-		handle_quic_streams(conn, params, layer, &ctx->msg_recv[i]);
+		handle_quic_streams(conn, params, layer);
 
 		(void)process_query_proto(params, KNOTD_STAGE_PROTO_END);
 	}
-- 
GitLab