Skip to content

Commit 29aacb9

Browse files
committed
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 <[email protected]>
1 parent 52144f7 commit 29aacb9

File tree

5 files changed

+19
-12
lines changed

5 files changed

+19
-12
lines changed

host.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ network_peer_update(struct vlist_tree *tree,
4040
return;
4141
}
4242

43+
if ((h_new ? h_new : h_old)->indirect)
44+
return;
45+
4346
if (h_new)
4447
ret = wg_peer_update(net, h_new, h_old ? WG_PEER_UPDATE : WG_PEER_CREATE);
4548
else
@@ -335,10 +338,11 @@ __network_hosts_update_done(struct network *net, bool free_net)
335338
avl_for_each_element(&net->hosts, host, node) {
336339
if (host == local)
337340
continue;
341+
host->peer.indirect = false;
338342
if (host->gateway && strcmp(host->gateway, local_name) != 0)
339-
continue;
343+
host->peer.indirect = true;
340344
if (local->gateway && strcmp(local->gateway, network_host_name(host)) != 0)
341-
continue;
345+
host->peer.indirect = true;
342346
vlist_add(&net->peers, &host->peer.node, host->peer.key);
343347
}
344348

@@ -407,7 +411,7 @@ network_hosts_connect_cb(struct uloop_timeout *t)
407411
wg_peer_refresh(net);
408412

409413
vlist_for_each_element(&net->peers, peer, node) {
410-
if (peer->state.connected)
414+
if (peer->state.connected || peer->indirect)
411415
continue;
412416

413417
ep = network_peer_next_endpoint(peer);

host.h

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct network_peer {
2323
int port;
2424
int pex_port;
2525
bool dynamic;
26+
bool indirect;
2627

2728
struct {
2829
int connect_attempt;

pex-stun.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static bool has_connected_peer(struct network *net, bool pex)
2222
if (pex && !peer->pex_port)
2323
continue;
2424

25-
if (peer->state.connected)
25+
if (peer->state.connected || peer->indirect)
2626
return true;
2727
}
2828

pex.c

+9-7
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pex_msg_init_ext(struct network *net, uint8_t opcode, bool ext)
3939
}
4040

4141
static struct network_peer *
42-
pex_msg_peer(struct network *net, const uint8_t *id)
42+
pex_msg_peer(struct network *net, const uint8_t *id, bool allow_indirect)
4343
{
4444
struct network_peer *peer;
4545
uint8_t key[WG_KEY_LEN] = {};
@@ -50,6 +50,8 @@ pex_msg_peer(struct network *net, const uint8_t *id)
5050
D_NET(net, "can't find peer %s", pex_peer_id_str(id));
5151
return NULL;
5252
}
53+
if (peer->indirect && !allow_indirect)
54+
return NULL;
5355

5456
return peer;
5557
}
@@ -154,7 +156,7 @@ network_pex_handle_endpoint_change(struct network *net, struct network_peer *pee
154156
struct network_peer *cur;
155157

156158
vlist_for_each_element(&net->peers, cur, node) {
157-
if (cur == peer || !cur->state.connected)
159+
if (cur == peer || !cur->state.connected || cur->indirect)
158160
continue;
159161

160162
pex_msg_init(net, PEX_MSG_NOTIFY_PEERS);
@@ -483,7 +485,7 @@ network_pex_recv_peers(struct network *net, struct network_peer *peer,
483485
continue;
484486
}
485487

486-
cur = pex_msg_peer(net, data->peer_id);
488+
cur = pex_msg_peer(net, data->peer_id, false);
487489
if (!cur || cur == peer)
488490
continue;
489491

@@ -507,7 +509,7 @@ network_pex_recv_query(struct network *net, struct network_peer *peer,
507509

508510
pex_msg_init(net, PEX_MSG_NOTIFY_PEERS);
509511
for (; len >= 8; data += 8, len -= 8) {
510-
cur = pex_msg_peer(net, data);
512+
cur = pex_msg_peer(net, data, false);
511513
if (!cur || !cur->state.connected)
512514
continue;
513515

@@ -717,7 +719,7 @@ network_pex_fd_cb(struct uloop_fd *fd, unsigned int events)
717719
if (!hdr)
718720
continue;
719721

720-
peer = pex_msg_peer(net, hdr->id);
722+
peer = pex_msg_peer(net, hdr->id, false);
721723
if (!peer)
722724
continue;
723725

@@ -958,7 +960,7 @@ global_pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr)
958960
case PEX_MSG_PONG:
959961
break;
960962
case PEX_MSG_UPDATE_REQUEST:
961-
peer = pex_msg_peer(net, hdr->id);
963+
peer = pex_msg_peer(net, hdr->id, true);
962964
network_pex_recv_update_request(net, peer, data, hdr->len,
963965
addr);
964966
break;
@@ -974,7 +976,7 @@ global_pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr)
974976
ep_idx = ENDPOINT_TYPE_ENDPOINT_PORT_NOTIFY;
975977
fallthrough;
976978
case PEX_MSG_ENDPOINT_NOTIFY:
977-
peer = pex_msg_peer(net, hdr->id);
979+
peer = pex_msg_peer(net, hdr->id, true);
978980
if (!peer)
979981
break;
980982

wg.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct network_peer *wg_peer_update_start(struct network *net, const uint8_t *ke
4747
struct network_peer *peer;
4848

4949
peer = vlist_find(&net->peers, key, peer, node);
50-
if (!peer)
50+
if (!peer || peer->indirect)
5151
return NULL;
5252

5353
peer->state.handshake = false;

0 commit comments

Comments
 (0)