From 135d648d9c2cc08d92460e139d867e90d389df06 Mon Sep 17 00:00:00 2001 From: Alexander Bakker Date: Sat, 27 Jun 2026 13:05:13 +0200 Subject: [PATCH] MT#55283 Unref ports after re-subscribe Previously, the ports used for a monologue subscription would leak upon re-subscribe. ``__assign_stream_fds`` cleared the stream fd queue without decrementing the ref count. This prevented ``monologue_destroy`` from releasing the ports on unsubscribe. Closes #2125 Change-Id: Ib86290d6a35e2388e34098f2847f1e34b3db2c5d (cherry picked from commit 250df2af5e1d56315c86339460438528afdb0102) --- daemon/call.c | 8 +++++--- perl/NGCP/Rtpengine/AutoTest.pm | 6 +++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index ef8c5bb25..c9cc25e21 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -910,7 +910,7 @@ static void __assign_stream_fds(struct call_media *media, sfd_intf_list_q *intf_ // use opaque pointer to detect changes void *old_selected_sfd = ps->selected_sfd; - t_queue_clear(&ps->sfds); + t_queue_clear_full(&ps->sfds, stream_fd_dec); bool sfd_found = false; stream_fd *intf_sfd = NULL; @@ -3511,10 +3511,12 @@ static void monologue_bundle_set_fds(struct call_monologue *ml) { dtls_shutdown(ms); // XXX close sockets that are not needed? - t_queue_clear(&ms->sfds); + t_queue_clear_full(&ms->sfds, stream_fd_dec); - for (__auto_type sl = bs->sfds.head; sl; sl = sl->next) + for (__auto_type sl = bs->sfds.head; sl; sl = sl->next) { + stream_fd_inc(sl->data); t_queue_push_tail(&ms->sfds, sl->data); + } ms->selected_sfd = bs->selected_sfd; diff --git a/perl/NGCP/Rtpengine/AutoTest.pm b/perl/NGCP/Rtpengine/AutoTest.pm index 38fee3bdf..19076f31d 100644 --- a/perl/NGCP/Rtpengine/AutoTest.pm +++ b/perl/NGCP/Rtpengine/AutoTest.pm @@ -23,7 +23,7 @@ our $port; BEGIN { require Exporter; @ISA = qw(Exporter); - our @EXPORT = qw(autotest_start new_call new_call_nc offer answer ft tt cid snd srtp_snd rtp rcv srtp_rcv rcv_no rcv_maybe + our @EXPORT = qw(autotest_start new_call new_call_nc offer answer ft tt cid snd snd_no srtp_snd rtp rcv srtp_rcv rcv_no rcv_maybe srtp_dec escape rtpm rtpmre reverse_tags new_ft new_tt crlf sdp_split rtpe_req offer_answer autotest_init subscribe_request subscribe_answer publish use_json rtpe_raw_req); }; @@ -211,6 +211,10 @@ sub snd { my ($sock, $dest, $packet, $addr) = @_; $sock->send($packet, 0, pack_sockaddr_in($dest, inet_aton($addr // '203.0.113.1'))) or die; } +sub snd_no { + my ($sock, $dest, $packet, $addr) = @_; + ok(!$sock->send($packet, 0, pack_sockaddr_in($dest, inet_aton($addr // '203.0.113.1'))), "send to closed port fails"); +} sub srtp_snd { my ($sock, $dest, $packet, $srtp_ctx, $addr) = @_; if (!$srtp_ctx->{skey}) {