Browse Source

MT#63317 avoid mismatched extmap IDs

Change-Id: I7489ebaf9dbcb4ebb0c0bf469872433c25a0acb4
rfuchs/dtls-ice
Richard Fuchs 3 months ago
parent
commit
4aa3641cad
3 changed files with 114 additions and 24 deletions
  1. +97
    -21
      daemon/call.c
  2. +13
    -3
      daemon/media_socket.c
  3. +4
    -0
      include/media_socket.h

+ 97
- 21
daemon/call.c View File

@ -2881,12 +2881,35 @@ static void media_set_siprec_label(struct call_media *other_media, struct call_m
}
__attribute__((nonnull(1)))
static unsigned int media_extmap_id(struct call_media *media) {
static unsigned int media_bundle_extmap_id(struct call_media *media) {
__auto_type ml = media->monologue;
// XXX slow search?
for (unsigned int i = 1; i < 255; i++) {
if (!media->extmap_ops->lookup(media, i))
if (media->extmap_ops->lookup(media, i))
continue;
// used by any other media in the bundle?
bool good = true;
// XXX even worse search
for (unsigned int j = 0; j < ml->medias->len; j++) {
__auto_type bundle_media = ml->medias->pdata[j];
if (!bundle_media)
continue;
if (bundle_media == media)
continue;
if (bundle_media->bundle != media->bundle)
continue;
if (bundle_media->extmap_ops->lookup(bundle_media, i)) {
good = false;
break;
}
}
if (good)
return i;
}
return -1u;
}
@ -2958,7 +2981,8 @@ static void media_init_extmap(struct call_media *media, struct rtp_extension *ex
t_hash_table_insert(media->extmap_ht, GUINT_TO_POINTER(ext->id), ext);
ext->handler = rtp_extension_get_handler(&ext->name);
if (!ext->handler.set)
ext->handler = rtp_extension_get_handler(&ext->name);
if (ext->id > 0 && ext->id <= 14)
media->extmap_a[ext->id - 1] = ext;
@ -3531,6 +3555,73 @@ static void monologue_bundle_set_sinks(struct call_monologue *ml) {
}
}
// see if any other media in a bundle has the extension already
static struct rtp_extension *monologue_ext_any_bundle(struct call_media *media, unsigned int id) {
__auto_type ml = media->monologue;
__auto_type bundle = media->bundle;
// XXX bit silly to do this in a loop
for (unsigned int i = 0; i < ml->medias->len; i++) {
__auto_type bundle_media = ml->medias->pdata[i];
if (!bundle_media)
continue;
if (bundle_media->bundle != bundle)
continue;
if (bundle_media->extmap_id[id])
return bundle_media->extmap_id[id];
}
return NULL;
}
__attribute__((nonnull(1)))
static void monologue_bundle_mid(struct call_monologue *ml) {
for (unsigned int i = 0; i < ml->medias->len; i++) {
__auto_type media = ml->medias->pdata[i];
if (!media)
continue;
if (!media->bundle)
continue;
if (media->extmap_id[RTP_EXT_MID])
continue;
struct rtp_extension *new_ext;
__auto_type ext = monologue_ext_any_bundle(media, RTP_EXT_MID);
if (ext) {
__auto_type ext_exist = media->extmap_ops->lookup(media, ext->id);
if (ext_exist) {
// XXX ideally we would support extension renumbering here
ilog(LOG_WARN, "RTP header extension collision for MID (%u vs "
"%u/'" STR_FORMAT "'), removing it in favour of MID",
ext->id, ext_exist->id, STR_FMT(&ext_exist->name));
t_hash_table_remove(media->extmap_ht, GUINT_TO_POINTER(ext_exist->id));
if (ext_exist->id <= 14)
media->extmap_a[ext_exist->id] = NULL;
t_queue_remove(&media->extmap, ext_exist); // XXX also not ideal
rtp_extension_free(ext_exist);
}
new_ext = g_new(struct rtp_extension, 1);
*new_ext = *ext;
}
else {
unsigned int id = media_bundle_extmap_id(media);
if (id == -1u) {
ilog(LOG_WARN, "Out of IDs for RTP header extension");
continue;
}
new_ext = g_new(struct rtp_extension, 1);
*new_ext = media_rtp_ext_mid;
new_ext->id = id;
}
new_ext->synthetic = true;
new_ext->accepted = true;
t_queue_push_tail(&media->extmap, new_ext);
media_init_extmap(media, new_ext);
}
}
__attribute__((nonnull(1, 2)))
static void monologue_bundle_offer(struct call_monologue *ml, sdp_ng_flags *flags) {
if (!flags->bundle_offer || flags->opmode != OP_OFFER)
@ -3570,27 +3661,11 @@ static void monologue_bundle_offer(struct call_monologue *ml, sdp_ng_flags *flag
// set bundle group
media->bundle = bundle;
// offer MID header extension
if (!media->extmap_id[RTP_EXT_MID]) {
unsigned int id = media_extmap_id(media);
if (id == -1u)
ilog(LOG_WARN, "Out of IDs for RTP header extension");
else {
__auto_type ext = g_new0(struct rtp_extension, 1);
// XXX string duplication and duplicate lookup via init_extmap -> get_handler
ext->name = STR("urn:ietf:params:rtp-hdrext:sdes:mid");
ext->id = id;
ext->synthetic = true;
t_queue_push_tail(&media->extmap, ext);
media_init_extmap(media, ext);
}
}
track_bundle_media_pt(media, exclude_pt);
}
monologue_bundle_check_consistency(ml);
monologue_bundle_check_heads(ml);
// make sure MID is offered for all medias in a bundle
monologue_bundle_mid(ml);
}
__attribute__((nonnull(1, 2)))
@ -3885,6 +3960,7 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q *
monologue_bundle_accept(sender_ml, flags);
monologue_bundle_offer(receiver_ml, flags);
monologue_bundle_check_consistency(receiver_ml);
monologue_bundle_check_heads(receiver_ml);
monologue_bundle_set_fds(receiver_ml);
monologue_bundle_set_sinks(sender_ml);
monologue_bundle_set_sinks(receiver_ml);


+ 13
- 3
daemon/media_socket.c View File

@ -2920,16 +2920,24 @@ static const rtp_ext_handler rtp_ext_mid = {
.print = rtp_ext_mid_print,
.kernel = rtp_ext_mid_kernel,
.id = RTP_EXT_MID,
.set = true,
};
rtp_ext_handler rtp_extension_get_handler(const str *name) {
if (!str_cmp(name, "urn:ietf:params:rtp-hdrext:sdes:mid"))
return rtp_ext_mid;
return (rtp_ext_handler) { .id = RTP_EXT_UNKNOWN };
return (rtp_ext_handler) { .id = RTP_EXT_UNKNOWN, .set = true };
}
struct rtp_extension media_rtp_ext_mid = {
.name = STR_CONST("urn:ietf:params:rtp-hdrext:sdes:mid"),
.handler = rtp_ext_mid,
};
static void media_packet_rtp_extension(struct packet_handler_ctx *phc, unsigned int id, const str *data) {
__auto_type ext = phc->mp.media->extmap_ops->lookup(phc->mp.media, id);
__auto_type media = phc->mp.media->bundle ?: phc->mp.media;
__auto_type ext = media->extmap_ops->lookup(phc->mp.media, id);
if (!ext)
return;
@ -2945,7 +2953,9 @@ static void media_packet_rtp_extension(struct packet_handler_ctx *phc, unsigned
}
static void media_packet_rtp_extensions(struct packet_handler_ctx *phc) {
if (!phc->mp.media->extmap.length)
__auto_type media = phc->mp.media->bundle ?: phc->mp.media;
if (!media->extmap.length)
return;
if (!phc->mp.extensions.len)
return;


+ 4
- 0
include/media_socket.h View File

@ -327,6 +327,8 @@ typedef struct {
RTP_EXT_UNKNOWN,
} id;
bool set; // used by rtp_extension_get_handler to detect non-init
} rtp_ext_handler;
struct rtp_extension {
@ -364,6 +366,8 @@ size_t extmap_print_long(void *, unsigned int, const str *);
rtp_ext_handler rtp_extension_get_handler(const str *);
extern struct rtp_extension media_rtp_ext_mid;
extern local_intf_q all_local_interfaces; // read-only during runtime


Loading…
Cancel
Save