From 97ef21eacd54a153ca009e6fee26b2caf1ff453d Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Wed, 17 Jun 2026 18:21:44 +0200 Subject: [PATCH] Fix UDP server peer connections. --- core/io/udp_server.cpp | 15 ++++++++++++++- core/io/udp_server.h | 5 ++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/core/io/udp_server.cpp b/core/io/udp_server.cpp index a4a53b397a..81899b2b05 100644 --- a/core/io/udp_server.cpp +++ b/core/io/udp_server.cpp @@ -80,10 +80,20 @@ Error UDPServer::poll() { Peer peer; peer.ip = ip; peer.port = port; - peer.peer = memnew(PacketPeerUDP); + Ref peer_ref = memnew(PacketPeerUDP); + peer.peer = peer_ref.ptr(); peer.peer->connect_shared_socket(_sock, ip, port, this); peer.peer->store_packet(ip, port, recv_buffer, read); pending.push_back(peer); + + // FIXME: peer.peer is intentionally leaked such that it can destruct + // when the client no longer needs it. + // The current system 'abuses' the refcount_init semantics, such + // that the first take_connection call takes ownership. A refactor + // with a better "transfer ownership" semantics is warranted to avoid + // accidental leaks. + peer_ref->reference(); + peer_ref->deinit_ref(); } } return OK; @@ -149,6 +159,7 @@ void UDPServer::set_max_pending_connections(int p_max) { if (!E) { break; } + memdelete(E->get().peer); pending.erase(E); } } @@ -186,11 +197,13 @@ void UDPServer::stop() { List::Element *E = peers.front(); while (E) { E->get().peer->disconnect_shared_socket(); + // Don't delete peer; it's intentionally weakly owned. E = E->next(); } E = pending.front(); while (E) { E->get().peer->disconnect_shared_socket(); + memdelete(E->get().peer); E = E->next(); } peers.clear(); diff --git a/core/io/udp_server.h b/core/io/udp_server.h index f2226b64e9..f850429dbd 100644 --- a/core/io/udp_server.h +++ b/core/io/udp_server.h @@ -42,7 +42,10 @@ protected: }; struct Peer { - Ref peer; + // Weakly owned in peers, strongly owned in pending. + // Peers are weakly owned such that it can self-destruct (and thus unregister itself) + // when the user no longer needs it. + PacketPeerUDP *peer; IPAddress ip; uint16_t port = 0;