pex: track indirect hosts (reachable via gateway) as peers without adding them to wg
[project/unetd.git] / wg.c
diff --git a/wg.c b/wg.c
index 1d406779d99f533546d1d06426332b8ff5b878a0..1f80e00826c354e4558a60e8dbf970134d158bde 100644 (file)
--- a/wg.c
+++ b/wg.c
@@ -1,10 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
+ */
 #include "unetd.h"
 
 static const struct wg_ops *wg_get_ops(struct network *net)
 {
-       if (dummy_mode)
-               return &wg_dummy_ops;
-
        if (wg_user_ops.check(net))
                return &wg_user_ops;
 
@@ -31,18 +32,28 @@ void wg_cleanup_network(struct network *net)
                net->wg.ops->cleanup(net);
 }
 
+static void
+wg_peer_set_connected(struct network *net, struct network_peer *peer, bool val)
+{
+       if (peer->state.connected == val)
+               return;
+
+       peer->state.connected = val;
+       network_services_peer_update(net, peer);
+}
+
 struct network_peer *wg_peer_update_start(struct network *net, const uint8_t *key)
 {
        struct network_peer *peer;
 
        peer = vlist_find(&net->peers, key, peer, node);
-       if (!peer)
+       if (!peer || peer->indirect)
                return NULL;
 
        peer->state.handshake = false;
        peer->state.idle++;
        if (peer->state.idle >= 2 * net->net_config.keepalive)
-               peer->state.connected = false;
+               wg_peer_set_connected(net, peer, false);
        if (peer->state.idle > net->net_config.keepalive)
                network_pex_event(net, peer, PEX_EV_PING);
 
@@ -65,9 +76,10 @@ void wg_peer_set_last_handshake(struct network *net, struct network_peer *peer,
        peer->state.last_handshake = sec;
        sec = now - sec;
        if (sec <= net->net_config.keepalive) {
-               peer->state.connected = true;
                if (peer->state.idle > sec)
                        peer->state.idle = sec;
+               wg_peer_set_connected(net, peer, true);
+               peer->state.pinged = false;
        }
 }
 
@@ -79,7 +91,7 @@ void wg_peer_set_rx_bytes(struct network *net, struct network_peer *peer,
        peer->state.rx_bytes = bytes;
        if (diff > 0) {
                peer->state.idle = 0;
-               peer->state.connected = true;
+               wg_peer_set_connected(net, peer, true);
        }
 }