From eb1157d38691689114dec6d327a06ace3bfbe9e0 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 22 Feb 2021 12:00:28 -0500 Subject: [PATCH] TT#112250 don't change ports when endpoint is talking ICE Change-Id: I0e60534d6d3cb62d25b8d865da02c3472cf0994e --- README.md | 7 ++ daemon/call.c | 34 ++++---- daemon/call_interfaces.c | 3 + include/call_interfaces.h | 1 + t/auto-daemon-tests.pl | 174 +++++++++++++++++++++++++++++++++++++- 5 files changed, 202 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 6f479fc90..6fafd1066 100644 --- a/README.md +++ b/README.md @@ -702,6 +702,13 @@ Optionally included keys are: Forces *rtpengine* to retain its local ports during a signalling exchange even when the remote endpoint changes its port. + - `no port latching` + + Port latching is enabled by default for endpoints which speak + ICE. With this option preset, a remote port change will result + in a local port change even for endpoints which speak ICE, + which will imply an ICE restart. + - `record call` Identical to setting `record call` to `on` (see below). diff --git a/daemon/call.c b/daemon/call.c index 05b129f92..4e27a77ad 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -836,6 +836,8 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne 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)) { /* handle zero endpoint address: only compare ports */ if (ep->port != em->endpoint.port) @@ -897,23 +899,22 @@ next_il: } static void __assign_stream_fds(struct call_media *media, GQueue *intf_sfds) { - GList *l, *k; - struct packet_stream *ps; - struct stream_fd *sfd, *intf_sfd; - struct intf_list *il; - int sfd_found; + int reset_ice = 0; + + for (GList *k = media->streams.head; k; k = k->next) { + struct packet_stream *ps = k->data; - for (k = media->streams.head; k; k = k->next) { - ps = k->data; + // use opaque pointer to detect changes + void *old_selected_sfd = ps->selected_sfd; g_queue_clear(&ps->sfds); - sfd_found = 0; - intf_sfd = NULL; + int sfd_found = 0; + struct stream_fd *intf_sfd = NULL; - for (l = intf_sfds->head; l; l = l->next) { - il = l->data; + for (GList *l = intf_sfds->head; l; l = l->next) { + struct intf_list *il = l->data; - sfd = g_queue_peek_nth(&il->list, ps->component - 1); + struct stream_fd *sfd = g_queue_peek_nth(&il->list, ps->component - 1); if (!sfd) return ; sfd->stream = ps; @@ -932,11 +933,12 @@ static void __assign_stream_fds(struct call_media *media, GQueue *intf_sfds) { ps->selected_sfd = g_queue_peek_nth(&ps->sfds, 0); } - /* XXX: - * handle crypto/dtls resets by moving contexts into sfd struct. - * handle ice resets too. - */ + if (old_selected_sfd && ps->selected_sfd && old_selected_sfd != ps->selected_sfd) + reset_ice = 1; } + + if (reset_ice && media->ice_agent) + ice_restart(media->ice_agent); } static int __wildcard_endpoint_map(struct call_media *media, unsigned int num_ports) { diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 040d2d0ea..5556e67c5 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -816,6 +816,9 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { case CSH_LOOKUP("port-latching"): out->port_latching = 1; break; + case CSH_LOOKUP("no-port-latching"): + out->no_port_latching = 1; + break; case CSH_LOOKUP("generate-mid"): out->generate_mid = 1; break; diff --git a/include/call_interfaces.h b/include/call_interfaces.h index a28d90a26..c6c4c1b9c 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -69,6 +69,7 @@ struct sdp_ng_flags { unidirectional:1, trust_address:1, port_latching:1, + no_port_latching:1, replace_origin:1, replace_sess_conn:1, replace_sdp_version:1, diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index cea7cd5ac..712f72cca 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -33,13 +33,185 @@ my $pcma_5 = "\xad\xac\xa2\xa6\xbd\x9a\x06\x3f\x26\x2d\x2c\x2d\x26\x3f\x06\x9a\x my ($sock_a, $sock_b, $sock_c, $sock_d, $port_a, $port_b, $ssrc, $ssrc_b, $resp, $sock_ax, $sock_bx, $port_ax, $port_bx, - $srtp_ctx_a, $srtp_ctx_b, $srtp_ctx_a_rev, $srtp_ctx_b_rev, + $srtp_ctx_a, $srtp_ctx_b, $srtp_ctx_a_rev, $srtp_ctx_b_rev, $ufrag_a, $ufrag_b, @ret1, @ret2, @ret3, @ret4, $srtp_key_a, $srtp_key_b, $ts, $seq); +new_call; + +($port_a, undef, $ufrag_a) = offer('ICE re-invite', + { ICE => 'force', }, < 'force', }, < 'force', }, < 'force', flags => ['no port latching']}, < 'force', flags => ['no port latching']}, < 'force', flags => ['no port latching']}, <