pex: improve keepalive handling master
authorFelix Fietkau <nbd@nbd.name>
Wed, 29 Jan 2025 20:43:02 +0000 (21:43 +0100)
committerFelix Fietkau <nbd@nbd.name>
Wed, 29 Jan 2025 20:45:36 +0000 (21:45 +0100)
Whenever idle time exceeds keepalive time, ping up to once
every 1+keepalive/2 interval. Avoids spuriously treating a peer as
disconnected.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
host.h
pex.c
wg.c

diff --git a/host.h b/host.h
index a63a60b26415a3418aa56572cace4f3b95592154..c678046909ad9be9f3df9fd76d071f106e0ce0ee 100644 (file)
--- a/host.h
+++ b/host.h
@@ -30,7 +30,6 @@ struct network_peer {
                bool connected;
                bool handshake;
                bool has_local_ep_addr;
-               bool pinged;
                union network_addr local_ep_addr;
                union network_endpoint endpoint;
 
@@ -43,6 +42,7 @@ struct network_peer {
                uint64_t last_request;
                uint64_t last_query_sent;
 
+               int ping_wait;
                int last_handshake_diff;
                int idle;
                int num_net_queries;
diff --git a/pex.c b/pex.c
index db143fc71c91a4f7bd2d3d86133d5a80a1bbe171..cc374af77cce290294409b96f4a372f7ab9bdbf3 100644 (file)
--- a/pex.c
+++ b/pex.c
@@ -389,12 +389,12 @@ network_pex_query_hosts(struct network *net)
 static void
 network_pex_send_ping(struct network *net, struct network_peer *peer)
 {
-       if (peer->state.pinged || !peer->state.endpoint.sa.sa_family)
+       if (peer->state.ping_wait > 0 || !peer->state.endpoint.sa.sa_family)
                return;
 
        pex_msg_init(net, PEX_MSG_PING);
        pex_msg_send(net, peer);
-       peer->state.pinged = true;
+       peer->state.ping_wait = 1 + net->net_config.keepalive / 2;
 }
 
 static void
diff --git a/wg.c b/wg.c
index 74e8aae76b56fe014007128b76b326c8f48536ed..61554bcc14a23e2513a34b65f40f6c376ba71ac4 100644 (file)
--- a/wg.c
+++ b/wg.c
@@ -52,6 +52,8 @@ struct network_peer *wg_peer_update_start(struct network *net, const uint8_t *ke
 
        peer->state.handshake = false;
        peer->state.idle++;
+       if (peer->state.ping_wait > 0)
+               peer->state.ping_wait--;
        if (peer->state.idle >= 2 * net->net_config.keepalive)
                wg_peer_set_connected(net, peer, false);
        if (peer->state.idle > net->net_config.keepalive)
@@ -80,7 +82,6 @@ void wg_peer_set_last_handshake(struct network *net, struct network_peer *peer,
                if (peer->state.idle > sec)
                        peer->state.idle = sec;
                wg_peer_set_connected(net, peer, true);
-               peer->state.pinged = false;
        }
 }