From 42f7e40545f6721097e44ad9e35e6977b2d4df87 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 8 Aug 2025 11:21:40 -0400 Subject: [PATCH] MT#63317 support extmap-strip for SDP Change-Id: Iaa38fa3c24d69abbfdb8f0e457d406ccf0c6d5bd --- daemon/call.c | 26 +++++++++++++++++++++----- daemon/call_interfaces.c | 16 ++++++++++++++-- daemon/sdp.c | 2 -- docs/ng_control_protocol.md | 15 ++++++++++++++- include/call_interfaces.h | 2 +- 5 files changed, 50 insertions(+), 11 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index a2ca9eb83..fad6f5f77 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2885,6 +2885,17 @@ static void media_init_extmap(struct call_media *media, struct rtp_extension *ex media->extmap_lookup = call_media_ext_lookup_ht; } +__attribute__((nonnull(1, 2))) +static bool media_extmap_strip(const str *name, const struct sdp_ng_flags *flags) { + if (t_hash_table_is_set(flags->rtpext_strip)) { + if (t_hash_table_lookup(flags->rtpext_strip, STR_PTR("all"))) + return false; + if (t_hash_table_lookup(flags->rtpext_strip, name)) + return false; + } + return true; +} + __attribute__((nonnull(1, 2))) static void media_update_extmap(struct call_media *media, struct stream_params *sp) { media_reset_extmap(media); @@ -2901,13 +2912,18 @@ static void media_update_extmap(struct call_media *media, struct stream_params * } } -__attribute__((nonnull(1, 2))) -static void media_set_extmap(struct call_media *media, const extmap_q *emq) { +__attribute__((nonnull(1, 2, 4))) +static void media_set_extmap(struct call_media *media, const extmap_q *emq, + bool (*manip)(const str *, const struct sdp_ng_flags *), const struct sdp_ng_flags *flags) +{ media_reset_extmap(media); // copy entries for (__auto_type ll = emq->head; ll; ll = ll->next) { __auto_type ext_o = ll->data; + if (manip && !manip(&ext_o->name, flags)) + continue; + __auto_type ext = g_new(__typeof(*ext_o), 1); *ext = *ext_o; t_queue_push_tail(&media->extmap, ext); @@ -3154,7 +3170,7 @@ static struct call_media * monologue_add_zero_media(struct call_monologue *sende media_update_attrs(sender_media, sp); media_update_format(sender_media, sp); media_set_ptime(sender_media, sp, flags->rev_ptime, flags->ptime); - media_set_extmap(sender_media, &sp->extmap); + media_set_extmap(sender_media, &sp->extmap, NULL, flags); *num_ports_other = proto_num_ports(sp->num_ports, sender_media, flags, (flags->rtcp_mux_demux || flags->rtcp_mux_accept) ? true : false); __disable_streams(sender_media, *num_ports_other); @@ -3286,7 +3302,7 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q * media_set_ptime(sender_media, sp, flags->rev_ptime, flags->ptime); media_set_ptime(receiver_media, sp, flags->ptime, flags->rev_ptime); media_update_extmap(sender_media, sp); - media_set_extmap(receiver_media, &sender_media->extmap); + media_set_extmap(receiver_media, &sender_media->extmap, media_extmap_strip, flags); if (flags->opmode == OP_OFFER) { ilog(LOG_DEBUG, "Setting media recording slots to %u", flags->media_rec_slot_offer); @@ -3799,7 +3815,7 @@ static int monologue_subscribe_request1(struct call_monologue *src_ml, struct ca media_set_address_family(dst_media, src_media, flags); media_set_ptime(src_media, sp, flags->rev_ptime, flags->ptime); media_set_ptime(dst_media, sp, flags->ptime, flags->rev_ptime); - media_set_extmap(dst_media, &src_media->extmap); + media_set_extmap(dst_media, &src_media->extmap, media_extmap_strip, flags); codec_store_populate(&dst_media->codecs, &src_media->codecs, .allow_asymmetric = !!flags->allow_asymmetric_codecs); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index cc43d08e7..8bfe67d14 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -1308,7 +1308,7 @@ void call_ng_flags_flags(str *s, unsigned int idx, helper_arg arg) { break; case CSH_LOOKUP("strip-extmap"): case CSH_LOOKUP("strip extmap"): - out->strip_extmap = true; + call_ng_flags_str_ht(STR_PTR("all"), 0, &out->rtpext_strip); break; case CSH_LOOKUP("symmetric-codecs"): case CSH_LOOKUP("symmetric codecs"): @@ -1517,6 +1517,16 @@ void call_ng_codec_flags(const ng_parser_t *parser, str *key, parser_arg value, #endif ilog(LOG_WARN, "Unknown 'codec' operation encountered: '" STR_FORMAT "'", STR_FMT(key)); } + +void call_ng_extmap_flags(const ng_parser_t *parser, str *key, parser_arg value, helper_arg arg) { + sdp_ng_flags *out = arg.flags; + switch (__csh_lookup(key)) { + case CSH_LOOKUP("strip"): + call_ng_flags_str_list(parser, value, call_ng_flags_str_ht, &out->rtpext_strip); + break; + } +} + #ifdef WITH_TRANSCODING static void call_ng_parse_block_mode(str *s, enum block_dtmf_mode *output) { switch (__csh_lookup(s)) { @@ -1899,7 +1909,9 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h case CSH_LOOKUP("endpoint learning"): call_ng_flags_str_list(parser, value, ng_el_option, out); break; - + case CSH_LOOKUP("extmap"): + parser->dict_iter(parser, value, call_ng_extmap_flags, out); + break; case CSH_LOOKUP("file"): out->file = s; break; diff --git a/daemon/sdp.c b/daemon/sdp.c index f2d373003..39f740494 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -2255,8 +2255,6 @@ void sdp_insert_all_attributes(GString *s, struct call_media *media, struct sdp_ static void sdp_print_extmap(GString *s, struct call_media *source_media, const sdp_ng_flags *flags) { if (!source_media) return; - if (flags->strip_extmap && !MEDIA_ISSET(source_media, PASSTHRU)) - return; for (__auto_type l = source_media->extmap.head; l; l = l->next) { __auto_type ext = l->data; diff --git a/docs/ng_control_protocol.md b/docs/ng_control_protocol.md index 52f6f73a5..577bdba12 100644 --- a/docs/ng_control_protocol.md +++ b/docs/ng_control_protocol.md @@ -178,6 +178,18 @@ Optionally included keys are: audio player regardless of the global config setting. The option `default` results in the behaviour mandated by the global config setting. +* `extmap` + + Contains a dictionary to allow manipulation of RFC-8285-style RTP header + extensions. + + The contained key `strip` points to a list of header extensions to remove + from the SDP. Header extensions must be named by their full name as they + appear in the SDP, usually an URI or an `ietf:` registered name. The string + `all` can be given to strip all extensions. + + Example in string syntax: `extmap=[strip=[all]]` + * `delay-buffer` Takes an integer as value. When set to non-zero, enables the delay @@ -1213,7 +1225,8 @@ Spaces in each string may be replaced by hyphens. * `strip extmap` - Remove `a=rtpmap` attributes from the outgoing SDP. + Legacy alias for `extmap=[strip=[all]]` to remove all `a=rtpmap` attributes + from the outgoing SDP. * `strict source` diff --git a/include/call_interfaces.h b/include/call_interfaces.h index e7e97b499..f7ea08032 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -45,6 +45,7 @@ struct ng_media { X(all_attributes) /* top-level (not part of an m= section) SDP session attributes */ #define RTPE_NG_FLAGS_STR_CASE_HT_PARAMS \ + X(rtpext_strip) \ X(codec_except) \ X(sdes_no) /* individual crypto suites which are excluded */ \ X(sdes_only) /* individual crypto suites which are only accepted */ @@ -214,7 +215,6 @@ RTPE_NG_FLAGS_STR_CASE_HT_PARAMS generate_rtcp:1, generate_rtcp_off:1, generate_mid:1, - strip_extmap:1, strict_source:1, media_handover:1, dtls_passive:1,