diff options
| author | Felix Fietkau | 2023-08-21 20:27:37 +0000 |
|---|---|---|
| committer | Felix Fietkau | 2023-08-21 20:27:38 +0000 |
| commit | 29aacb9386e058408ed8a835bad37d58d3c9d57f (patch) | |
| tree | a0f00d5a9510891e9b990c13d9c81447b6344b08 | |
| parent | 52144f723bec2f0dc3b2658c38fb8cbefa9a0cfc (diff) | |
| download | unetd-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.c | 10 | ||||
| -rw-r--r-- | host.h | 1 | ||||
| -rw-r--r-- | pex-stun.c | 2 | ||||
| -rw-r--r-- | pex.c | 16 | ||||
| -rw-r--r-- | wg.c | 2 |
5 files changed, 19 insertions, 12 deletions
@@ -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); @@ -23,6 +23,7 @@ struct network_peer { int port; int pex_port; bool dynamic; + bool indirect; struct { int connect_attempt; @@ -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; } @@ -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; @@ -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; |