pex: after receiving data update req, notify peer of local address/port
authorFelix Fietkau <nbd@nbd.name>
Thu, 17 Aug 2023 14:46:32 +0000 (16:46 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 17 Aug 2023 14:46:33 +0000 (16:46 +0200)
This helps in situations where a server with a public IP is being used as
a gateway for peers behind NAT.

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

diff --git a/pex.c b/pex.c
index 632d016be4b7f5afd4c36315f83147edfb48aede..7db9ab841a2f13a5e142ef08e9d6c7d70c1c8cba 100644 (file)
--- a/pex.c
+++ b/pex.c
@@ -541,6 +541,7 @@ network_pex_recv_update_request(struct network *net, struct network_peer *peer,
                                struct sockaddr_in6 *addr)
 {
        struct pex_update_request *req = (struct pex_update_request *)data;
+       struct pex_endpoint_port_notify *port_data;
        struct pex_msg_update_send_ctx ctx = {};
        uint64_t req_version = be64_to_cpu(req->cur_version);
        int *query_count;
@@ -579,7 +580,7 @@ network_pex_recv_update_request(struct network *net, struct network_peer *peer,
                return;
 
        if (req_version >= net->net_data_version)
-               return;
+               goto out;
 
        pex_msg_update_response_init(&ctx, net->config.pubkey, net->config.auth_key,
                                     peer->key, !!addr, (void *)data,
@@ -588,6 +589,20 @@ network_pex_recv_update_request(struct network *net, struct network_peer *peer,
                pex_msg_send_ext(net, peer, addr);
                done = !pex_msg_update_response_continue(&ctx);
        }
+
+out:
+       if (peer->state.connected || !net->net_config.local_host)
+               return;
+
+       pex_msg_init_ext(net, PEX_MSG_ENDPOINT_PORT_NOTIFY, !!addr);
+
+       port_data = pex_msg_append(sizeof(*port_data));
+       if (net->stun.port_ext)
+               port_data->port = htons(net->stun.port_ext);
+       else
+               port_data->port = htons(net->net_config.local_host->peer.port);
+
+       pex_msg_send_ext(net, peer, addr);
 }
 
 static void