From a26601a37a5fcbaabeb1f6802988d5a8d6de9cb0 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 17 Feb 2022 15:55:46 -0500 Subject: [PATCH] TT#14008 add new `reject-ICE` flag Change-Id: I47db832d3a2abce8794e893f2fb8d681010a0d16 --- README.md | 12 ++++++++++-- daemon/call.c | 24 ++++++++++++++++++++---- daemon/call_interfaces.c | 6 ++++++ daemon/media_socket.c | 4 ++++ include/call_interfaces.h | 1 + include/media_socket.h | 2 ++ utils/rtpengine-ng-client | 4 +++- 7 files changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 66f60ec66..712c40575 100644 --- a/README.md +++ b/README.md @@ -887,9 +887,15 @@ Optionally included keys are: - `trickle ICE` - Useful for `offer` messages when ICE as advertised to also advertise + Useful for `offer` messages when ICE is advertised to also advertise support for trickle ICE. + - `reject ICE` + + Useful for `offer` messages that advertise support for ICE. + Instructs *rtpengine* to reject the offered ICE. This is + similar to using `ICE=remove` in the respective `answer`. + * `generate RTCP` Contains a string, either `on` or `off`. If enabled for a call, @@ -993,7 +999,9 @@ Optionally included keys are: Contains a string which must be one of the following values: - With `remove`, any ICE attributes are stripped from the SDP body. + With `remove`, any ICE attributes are stripped from the SDP body. Also + see the flag `reject ICE` to effect an early removal of ICE support + during an `offer`. With `force`, ICE attributes are first stripped, then new attributes are generated and inserted, which leaves the media proxy as the only ICE candidate. diff --git a/daemon/call.c b/daemon/call.c index dada14e42..fb58dab7b 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -888,16 +888,27 @@ static struct call_media *__get_media(struct call_monologue *ml, GList **it, con return med; } + + +static int __media_want_interfaces(struct call_media *media) { + unsigned int want_interfaces = media->logical_intf->list.length; + if (rtpe_config.save_interface_ports || !MEDIA_ISSET(media, ICE)) + want_interfaces = 1; + return want_interfaces; +} +static void __endpoint_map_truncate(struct endpoint_map *em, unsigned int num_intfs) { + while (em->intf_sfds.length > num_intfs) { + struct intf_list *il = g_queue_pop_tail(&em->intf_sfds); + free_release_intf_list(il); + } +} 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) { struct endpoint_map *em; struct stream_fd *sfd; GQueue intf_sockets = G_QUEUE_INIT; - unsigned int want_interfaces = media->logical_intf->list.length; - - if (rtpe_config.save_interface_ports || !MEDIA_ISSET(media, ICE)) - want_interfaces = 1; + unsigned int want_interfaces = __media_want_interfaces(media); for (GList *l = media->endpoint_maps.tail; l; l = l->prev) { em = l->data; @@ -922,6 +933,7 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne em->endpoint = *ep; em->wildcard = 0; } + __endpoint_map_truncate(em, want_interfaces); return em; } if (!ep) /* creating wildcard map */ @@ -942,6 +954,7 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne if (em->num_ports >= num_ports && em->intf_sfds.length >= want_interfaces) { if (is_addr_unspecified(&em->endpoint.address)) em->endpoint.address = ep->address; + __endpoint_map_truncate(em, want_interfaces); return em; } /* endpoint matches, but not enough ports. flush existing ports @@ -1487,6 +1500,9 @@ static void __ice_offer(const struct sdp_ng_flags *flags, struct call_media *thi else if (flags->ice_option != ICE_DEFAULT) MEDIA_SET(this, ICE); + if (flags->ice_reject) + MEDIA_CLEAR(other, ICE); + if (flags->passthrough_on) { ilog(LOG_DEBUG, "enabling passthrough mode"); MEDIA_SET(this, PASSTHRU); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index e4512305d..44bf7518f 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -839,6 +839,12 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { case CSH_LOOKUP("trickle-ice"): out->trickle_ice = 1; break; + case CSH_LOOKUP("ICE-reject"): + case CSH_LOOKUP("reject-ICE"): + case CSH_LOOKUP("ice-reject"): + case CSH_LOOKUP("reject-ice"): + out->ice_reject = 1; + break; case CSH_LOOKUP("loop-protect"): out->loop_protect = 1; break; diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 7152a9080..574257d41 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -990,6 +990,10 @@ void free_intf_list(struct intf_list *il) { g_queue_clear(&il->list); g_slice_free1(sizeof(*il), il); } +void free_release_intf_list(struct intf_list *il) { + g_queue_clear_full(&il->list, (GDestroyNotify) stream_fd_release); + g_slice_free1(sizeof(*il), il); +} diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 235c0d110..ca4d5dec1 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -106,6 +106,7 @@ struct sdp_ng_flags { rtcp_mux_demux:1, rtcp_mux_accept:1, rtcp_mux_reject:1, + ice_reject:1, trickle_ice:1, no_rtcp_attr:1, full_rtcp_attr:1, diff --git a/include/media_socket.h b/include/media_socket.h index f3f6687ad..dd27f0046 100644 --- a/include/media_socket.h +++ b/include/media_socket.h @@ -179,6 +179,8 @@ struct stream_fd *stream_fd_lookup(const endpoint_t *); void stream_fd_release(struct stream_fd *); void free_intf_list(struct intf_list *il); +void free_release_intf_list(struct intf_list *il); +void free_release_intf_list(struct intf_list *il); void free_socket_intf_list(struct intf_list *il); INLINE int open_intf_socket(socket_t *r, unsigned int port, const struct local_intf *lif) { diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index c0d18be67..00e9841d1 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -99,6 +99,8 @@ GetOptions( 'no-codec-renegotiation' => \$options{'no codec renegotiation'}, 'media-echo=s' => \$options{'media echo'}, 'pierce-NAT' => \$options{'pierce NAT'}, + 'trickle-ICE' => \$options{'trickle ICE'}, + 'reject-ICE' => \$options{'reject ICE'}, 'label=s' => \$options{'label'}, 'set-label=s' => \$options{'set-label'}, 'from-label=s' => \$options{'from-label'}, @@ -135,7 +137,7 @@ for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address, for my $x (split(/,/, 'TOS,delete-delay,delay-buffer,volume,frequency,trigger-end-time,trigger-end-digits,DTMF-delay')) { defined($options{$x}) and $packet{$x} = $options{$x}; } -for my $x (split(/,/, 'trust address,symmetric,asymmetric,unidirectional,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,all,SIPREC,pad crypto,generate mid,fragment,original sendrecv,symmetric codecs,asymmetric codecs,inject DTMF,detect DTMF,generate RTCP,single codec,no codec renegotiation,pierce NAT,SIP-source-address,allow transcoding')) { +for my $x (split(/,/, 'trust address,symmetric,asymmetric,unidirectional,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,all,SIPREC,pad crypto,generate mid,fragment,original sendrecv,symmetric codecs,asymmetric codecs,inject DTMF,detect DTMF,generate RTCP,single codec,no codec renegotiation,pierce NAT,SIP-source-address,allow transcoding,trickle ICE,reject ICE')) { defined($options{$x}) and push(@{$packet{flags}}, $x); } for my $x (split(/,/, 'origin,session connection,sdp version,username,session-name,zero-address')) {