summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau2023-08-21 20:27:37 +0000
committerFelix Fietkau2023-08-21 20:27:38 +0000
commit29aacb9386e058408ed8a835bad37d58d3c9d57f (patch)
treea0f00d5a9510891e9b990c13d9c81447b6344b08
parent52144f723bec2f0dc3b2658c38fb8cbefa9a0cfc (diff)
downloadunetd-29aacb9386e058408ed8a835bad37d58d3c9d57f.tar.gz
pex: track indirect hosts (reachable via gateway) as peers without adding them to wg
This allows other hosts to respond to them via global PEX, in order to help them find their gateway Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--host.c10
-rw-r--r--host.h1
-rw-r--r--pex-stun.c2
-rw-r--r--pex.c16
-rw-r--r--wg.c2
5 files changed, 19 insertions, 12 deletions
diff --git a/host.c b/host.c
index e4e38d3..2bfc500 100644
--- a/host.c
+++ b/host.c
@@ -40,6 +40,9 @@ network_peer_update(struct vlist_tree *tree,
return;
}
+ if ((h_new ? h_new : h_old)->indirect)
+ return;
+
if (h_new)
ret = wg_peer_update(net, h_new, h_old ? WG_PEER_UPDATE : WG_PEER_CREATE);
else
@@ -335,10 +338,11 @@ __network_hosts_update_done(struct network *net, bool free_net)
avl_for_each_element(&net->hosts, host, node) {
if (host == local)
continue;
+ host->peer.indirect = false;
if (host->gateway && strcmp(host->gateway, local_name) != 0)
- continue;
+ host->peer.indirect = true;
if (local->gateway && strcmp(local->gateway, network_host_name(host)) != 0)
- continue;
+ host->peer.indirect = true;
vlist_add(&net->peers, &host->peer.node, host->peer.key);
}
@@ -407,7 +411,7 @@ network_hosts_connect_cb(struct uloop_timeout *t)
wg_peer_refresh(net);
vlist_for_each_element(&net->peers, peer, node) {
- if (peer->state.connected)
+ if (peer->state.connected || peer->indirect)
continue;
ep = network_peer_next_endpoint(peer);
diff --git a/host.h b/host.h
index cb4085e..56d359c 100644
--- a/host.h
+++ b/host.h
@@ -23,6 +23,7 @@ struct network_peer {
int port;
int pex_port;
bool dynamic;
+ bool indirect;
struct {
int connect_attempt;
diff --git a/pex-stun.c b/pex-stun.c
index 444612b..0be3160 100644
--- a/pex-stun.c
+++ b/pex-stun.c
@@ -22,7 +22,7 @@ static bool has_connected_peer(struct network *net, bool pex)
if (pex && !peer->pex_port)
continue;
- if (peer->state.connected)
+ if (peer->state.connected || peer->indirect)
return true;
}
diff --git a/pex.c b/pex.c
index 7db9ab8..61977cc 100644
--- a/pex.c
+++ b/pex.c
@@ -39,7 +39,7 @@ pex_msg_init_ext(struct network *net, uint8_t opcode, bool ext)
}
static struct network_peer *
-pex_msg_peer(struct network *net, const uint8_t *id)
+pex_msg_peer(struct network *net, const uint8_t *id, bool allow_indirect)
{
struct network_peer *peer;
uint8_t key[WG_KEY_LEN] = {};
@@ -50,6 +50,8 @@ pex_msg_peer(struct network *net, const uint8_t *id)
D_NET(net, "can't find peer %s", pex_peer_id_str(id));
return NULL;
}
+ if (peer->indirect && !allow_indirect)
+ return NULL;
return peer;
}
@@ -154,7 +156,7 @@ network_pex_handle_endpoint_change(struct network *net, struct network_peer *pee
struct network_peer *cur;
vlist_for_each_element(&net->peers, cur, node) {
- if (cur == peer || !cur->state.connected)
+ if (cur == peer || !cur->state.connected || cur->indirect)
continue;
pex_msg_init(net, PEX_MSG_NOTIFY_PEERS);
@@ -483,7 +485,7 @@ network_pex_recv_peers(struct network *net, struct network_peer *peer,
continue;
}
- cur = pex_msg_peer(net, data->peer_id);
+ cur = pex_msg_peer(net, data->peer_id, false);
if (!cur || cur == peer)
continue;
@@ -507,7 +509,7 @@ network_pex_recv_query(struct network *net, struct network_peer *peer,
pex_msg_init(net, PEX_MSG_NOTIFY_PEERS);
for (; len >= 8; data += 8, len -= 8) {
- cur = pex_msg_peer(net, data);
+ cur = pex_msg_peer(net, data, false);
if (!cur || !cur->state.connected)
continue;
@@ -717,7 +719,7 @@ network_pex_fd_cb(struct uloop_fd *fd, unsigned int events)
if (!hdr)
continue;
- peer = pex_msg_peer(net, hdr->id);
+ peer = pex_msg_peer(net, hdr->id, false);
if (!peer)
continue;
@@ -958,7 +960,7 @@ global_pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr)
case PEX_MSG_PONG:
break;
case PEX_MSG_UPDATE_REQUEST:
- peer = pex_msg_peer(net, hdr->id);
+ peer = pex_msg_peer(net, hdr->id, true);
network_pex_recv_update_request(net, peer, data, hdr->len,
addr);
break;
@@ -974,7 +976,7 @@ global_pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr)
ep_idx = ENDPOINT_TYPE_ENDPOINT_PORT_NOTIFY;
fallthrough;
case PEX_MSG_ENDPOINT_NOTIFY:
- peer = pex_msg_peer(net, hdr->id);
+ peer = pex_msg_peer(net, hdr->id, true);
if (!peer)
break;
diff --git a/wg.c b/wg.c
index 64687f1..1f80e00 100644
--- a/wg.c
+++ b/wg.c
@@ -47,7 +47,7 @@ struct network_peer *wg_peer_update_start(struct network *net, const uint8_t *ke
struct network_peer *peer;
peer = vlist_find(&net->peers, key, peer, node);
- if (!peer)
+ if (!peer || peer->indirect)
return NULL;
peer->state.handshake = false;