From: Frantisek Tobias Date: Mon, 30 Sep 2024 06:01:49 +0000 (+0200) Subject: daemon udp connect: use connected udp communication X-Git-Tag: v6.0.9~10^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82e1d596;p=thirdparty%2Fknot-resolver.git daemon udp connect: use connected udp communication --- diff --git a/daemon/io.c b/daemon/io.c index 86bd314e8..366489075 100644 --- a/daemon/io.c +++ b/daemon/io.c @@ -67,7 +67,7 @@ void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, if (s->closing || nread <= 0 || comm_addr->sa_family == AF_UNSPEC) return; - if (s->outgoing) { + if (!the_network->enable_connect_udp && s->outgoing) { const struct sockaddr *peer = session2_get_peer(s); if (kr_fails_assert(peer->sa_family != AF_UNSPEC)) return; diff --git a/daemon/lua/kres-gen-33.lua b/daemon/lua/kres-gen-33.lua index c99a1dda2..8f4386b27 100644 --- a/daemon/lua/kres-gen-33.lua +++ b/daemon/lua/kres-gen-33.lua @@ -590,6 +590,7 @@ struct network { int snd; int rcv; } listen_tcp_buflens; + _Bool enable_connect_udp; }; struct args *the_args; struct endpoint { diff --git a/daemon/network.c b/daemon/network.c index 59d478093..5551b15a0 100644 --- a/daemon/network.c +++ b/daemon/network.c @@ -78,6 +78,7 @@ void network_init(uv_loop_t *loop, int tcp_backlog) the_network->tcp.tls_handshake_timeout = TLS_MAX_HANDSHAKE_TIME; the_network->tcp.user_timeout = 1000; // 1s should be more than enough the_network->tcp_backlog = tcp_backlog; + the_network->enable_connect_udp = true; // On Linux, unset means some auto-tuning mechanism also depending on RAM, // which might be OK default (together with the user_timeout above) diff --git a/daemon/network.h b/daemon/network.h index 83d1b6f48..9d50e46d3 100644 --- a/daemon/network.h +++ b/daemon/network.h @@ -115,6 +115,13 @@ struct network { struct { int snd, rcv; } listen_udp_buflens, listen_tcp_buflens; + + /** Use uv_udp_connect as the transport method for UDP. + * Enabling this increases the total number of syscalls, with a variable + * impact on the time spent processing them, sometimes resulting in + * a slight improvement in syscall processing efficiency. + * Note: This does not necessarily lead to overall performance gains. */ + bool enable_connect_udp; }; /** Pointer to the singleton network state. NULL if not initialized. */ diff --git a/daemon/session2.c b/daemon/session2.c index 91aeb8295..683b2e618 100644 --- a/daemon/session2.c +++ b/daemon/session2.c @@ -1447,8 +1447,8 @@ static int session2_transport_pushv(struct session2 *s, ctx); return kr_ok(); } else { - int ret = uv_udp_try_send((uv_udp_t*)handle, - (uv_buf_t *)iov, iovcnt, comm->comm_addr); + int ret = uv_udp_try_send((uv_udp_t*)handle, (uv_buf_t *)iov, iovcnt, + the_network->enable_connect_udp ? NULL : comm->comm_addr); if (ret > 0) // equals buffer size, only confuses us ret = 0; if (ret == UV_EAGAIN) { diff --git a/daemon/worker.c b/daemon/worker.c index 83915b011..17fe1f821 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -829,6 +829,17 @@ static int transmit(struct qr_task *task) struct comm_info out_comm = { .comm_addr = (struct sockaddr *)choice }; + + if (the_network->enable_connect_udp && session->outgoing && !session->stream) { + uv_udp_t *udp = (uv_udp_t *)session2_get_handle(session); + int connect_tries = 3; + + do { + ret = uv_udp_connect(udp, out_comm.comm_addr); + } while (ret == UV_EADDRINUSE && --connect_tries > 0); + if (ret < 0) + kr_log_error(IO, "Failed to establish udp connection: %s\n", uv_strerror(ret)); + } ret = qr_task_send(task, session, &out_comm, task->pktbuf); if (ret) { session2_close(session);