From 7d8834c244330f2d34b0156e49224f5b6f71916f Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 14 Feb 2023 10:32:00 -0500 Subject: [PATCH] MT#56420 add new port latching logic The old port latching logic was simply to use the last (newest) allocated endpoint_map. This turned out to be wrong, because the last used socket on the monologue could have been one that was allocated earlier (and older endpoint_map), as it can happen during repeated re-invites. Add a new function to actually look for the correct endpoint_map, matching the currently used socket, to make sure the port doesn't change. Change-Id: Iae768fe48539264575aed67cbbb6b08ac745130f --- daemon/call.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index e9d63e58c..ebec67090 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -958,11 +958,7 @@ static struct endpoint_map *__hunt_endpoint_map(struct call_media *media, unsign if (!ep) /* creating wildcard map */ break; - if (flags && flags->port_latching) - /* do nothing - ignore endpoint addresses */ ; - else if (MEDIA_ISSET(media, ICE) && (!flags || !flags->no_port_latching)) - ; // don't change endpoint address if we're talking ICE - else if (is_addr_unspecified(&ep->address) || is_addr_unspecified(&em->endpoint.address)) { + if (is_addr_unspecified(&ep->address) || is_addr_unspecified(&em->endpoint.address)) { /* handle zero endpoint address: only compare ports */ if (ep->port != em->endpoint.port) continue; @@ -985,6 +981,29 @@ static struct endpoint_map *__hunt_endpoint_map(struct call_media *media, unsign return NULL; } +static struct endpoint_map *__latch_endpoint_map(struct call_media *media) +{ + // simply look for the endpoint map matching the current port + if (!media->streams.length) + return NULL; + struct packet_stream *first_ps = media->streams.head->data; + if (!first_ps->sfds.length) + return NULL; + struct stream_fd *matcher = first_ps->sfds.head->data; + + for (GList *l = media->endpoint_maps.tail; l; l = l->prev) { + struct endpoint_map *em = l->data; + if (!em->intf_sfds.length) + continue; + struct intf_list *em_il = em->intf_sfds.head->data; + if (!em_il->list.length) + continue; + struct stream_fd *first = em_il->list.head->data; + if (first == matcher) + return em; + } + return NULL; +} static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigned int num_ports, const struct endpoint *ep, const struct sdp_ng_flags *flags, bool always_reuse) { @@ -992,7 +1011,17 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne GQueue intf_sockets = G_QUEUE_INIT; unsigned int want_interfaces = __media_want_interfaces(media); - struct endpoint_map *em = __hunt_endpoint_map(media, num_ports, ep, flags, always_reuse, want_interfaces); + bool port_latching = false; + if (flags && flags->port_latching) + port_latching = true; + else if (MEDIA_ISSET(media, ICE) && (!flags || !flags->no_port_latching)) + port_latching = true; + + struct endpoint_map *em = NULL; + if (port_latching) + em = __latch_endpoint_map(media); + if (!em) + em = __hunt_endpoint_map(media, num_ports, ep, flags, always_reuse, want_interfaces); if (em) { if (em->intf_sfds.length)