]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon udp connect: use connected udp communication
authorFrantisek Tobias <frantisek.tobias@nic.cz>
Mon, 30 Sep 2024 06:01:49 +0000 (08:01 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 30 Sep 2024 07:50:09 +0000 (09:50 +0200)
daemon/io.c
daemon/lua/kres-gen-33.lua
daemon/network.c
daemon/network.h
daemon/session2.c
daemon/worker.c

index 86bd314e88ae358a6d8109b9b5c4098e3da34f09..3664890752f75cef13280835e5d8edc22a305402 100644 (file)
@@ -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;
index c99a1dda256e45cd61092286f714fd2881d46296..8f4386b27caa8105770ccd4e79b8c54cdb0c6bfc 100644 (file)
@@ -590,6 +590,7 @@ struct network {
                int snd;
                int rcv;
        } listen_tcp_buflens;
+       _Bool enable_connect_udp;
 };
 struct args *the_args;
 struct endpoint {
index 59d478093e11e659e6dcb2eb7f375ab1f42f78bb..5551b15a04cfbef9fd245bd80a9ae835450c02a5 100644 (file)
@@ -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)
index 83d1b6f4816b4ae6de231bc528eac10baba09ddb..9d50e46d3a912f9430fde6618bc6d2db3d0f6837 100644 (file)
@@ -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. */
index 91aeb82953360f0187f7ea854e5bb5e3ecd497fc..683b2e61828cc4c02144543bc98033cd4fa5e2c3 100644 (file)
@@ -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) {
index 83915b011572b5514a5e6691fcc1b35a66555555..17fe1f821de715132fc8d14d50893c481c71ddc3 100644 (file)
@@ -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);