Browse Source

MT#55283 delay SDP parsing until we have a call

For trickle ICE updates that need to be queued up, this requires storing
the unparsed SDP in the fragment object, and then doing the parsing when
actually processing the fragment.

This allows the call's memory arena to be used for parsing.

Change-Id: I28ed192c4443cedfa3095007cc8a555e3aa7a17a
rfuchs/test
Richard Fuchs 1 year ago
parent
commit
2ab7d4f5d5
4 changed files with 50 additions and 25 deletions
  1. +17
    -12
      daemon/call_interfaces.c
  2. +26
    -9
      daemon/ice.c
  3. +6
    -3
      daemon/janus.c
  4. +1
    -1
      include/ice.h

+ 17
- 12
daemon/call_interfaces.c View File

@ -2159,15 +2159,11 @@ static const char *call_offer_answer_ng(ng_command_ctx_t *ctx, enum call_opmode
goto out;
}
errstr = "Incomplete SDP specification";
if (sdp_streams(&parsed, &streams, &flags))
goto out;
/* OP_ANSWER; OP_OFFER && !IS_FOREIGN_CALL */
call = call_get(&flags.call_id);
// SDP fragments for trickle ICE must always operate on an existing call
if (opmode == OP_OFFER && trickle_ice_update(ctx->ngbuf, call, &flags, &streams)) {
if (opmode == OP_OFFER && trickle_ice_update(ctx->ngbuf, call, &flags, NULL, &parsed)) {
errstr = NULL;
// SDP fragments for trickle ICE are consumed with no replacement returned
goto out;
@ -2190,6 +2186,10 @@ static const char *call_offer_answer_ng(ng_command_ctx_t *ctx, enum call_opmode
if (!call)
goto out;
errstr = "Incomplete SDP specification";
if (sdp_streams(&parsed, &streams, &flags))
goto out;
if (flags.debug)
CALL_SET(call, DEBUG);
@ -3695,14 +3695,18 @@ const char *call_publish_ng(ng_command_ctx_t *ctx,
if (sdp_parse(&sdp_in, &parsed, &flags))
return "Failed to parse SDP";
if (sdp_streams(&parsed, &streams, &flags))
return "Incomplete SDP specification";
call = call_get_or_create(&flags.call_id, false);
call = call_get(&flags.call_id);
if (trickle_ice_update(ctx->ngbuf, call, &flags, &streams))
if (trickle_ice_update(ctx->ngbuf, call, &flags, NULL, &parsed))
return NULL;
if (!call)
call = call_get_or_create(&flags.call_id, false);
if (sdp_streams(&parsed, &streams, &flags))
return "Incomplete SDP specification";
updated_created_from(call, addr, sin);
struct call_monologue *ml = call_get_or_create_monologue(call, &flags.from_tag);
@ -3854,7 +3858,10 @@ const char *call_subscribe_answer_ng(ng_command_ctx_t *ctx) {
if (!call)
return "Unknown call-ID";
if (trickle_ice_update(ctx->ngbuf, call, &flags, &streams))
if (sdp_parse(&flags.sdp, &parsed, &flags))
return "Failed to parse SDP";
if (trickle_ice_update(ctx->ngbuf, call, &flags, NULL, &parsed))
return NULL;
if (!flags.to_tag.s)
@ -3867,8 +3874,6 @@ const char *call_subscribe_answer_ng(ng_command_ctx_t *ctx) {
if (!dest_ml)
return "To-tag not found";
if (sdp_parse(&flags.sdp, &parsed, &flags))
return "Failed to parse SDP";
if (sdp_streams(&parsed, &streams, &flags))
return "Incomplete SDP specification";


+ 26
- 9
daemon/ice.c View File

@ -41,6 +41,7 @@ struct sdp_fragment {
ng_buffer *ngbuf;
struct timeval received;
sdp_streams_q streams;
sdp_sessions_q sdp;
sdp_ng_flags flags;
};
@ -101,7 +102,16 @@ static fragments_ht sdp_fragments;
static void ice_update_media_streams(struct call_monologue *ml, sdp_streams_q *streams) {
static void ice_update_media_streams(struct call_monologue *ml, sdp_streams_q *streams, sdp_sessions_q *sdp,
sdp_ng_flags *flags)
{
if (!streams || !streams->head) {
if (sdp_streams(sdp, streams, flags)) {
ilogs(ice, LOG_WARN, "Incomplete SDP specification for tricle ICE");
return;
}
}
for (__auto_type l = streams->head; l; l = l->next) {
struct stream_params *sp = l->data;
struct call_media *media = NULL;
@ -143,6 +153,7 @@ static int frag_key_eq(const struct fragment_key *a, const struct fragment_key *
static void fragment_free(struct sdp_fragment *frag) {
sdp_streams_clear(&frag->streams);
sdp_sessions_clear(&frag->sdp);
call_ng_free_flags(&frag->flags);
obj_put(frag->ngbuf);
g_slice_free1(sizeof(*frag), frag);
@ -152,7 +163,7 @@ static void fragment_key_free(struct fragment_key *k) {
g_free(k->from_tag.s);
g_slice_free1(sizeof(*k), k);
}
static void queue_sdp_fragment(ng_buffer *ngbuf, sdp_streams_q *streams, sdp_ng_flags *flags) {
static void queue_sdp_fragment(ng_buffer *ngbuf, sdp_streams_q *streams, sdp_sessions_q *sdp, sdp_ng_flags *flags) {
ilog(LOG_DEBUG, "Queuing up SDP fragment for " STR_FORMAT_M "/" STR_FORMAT_M,
STR_FMT_M(&flags->call_id), STR_FMT_M(&flags->from_tag));
@ -163,9 +174,15 @@ static void queue_sdp_fragment(ng_buffer *ngbuf, sdp_streams_q *streams, sdp_ng_
struct sdp_fragment *frag = g_slice_alloc0(sizeof(*frag));
frag->received = rtpe_now;
frag->ngbuf = obj_get(ngbuf);
frag->streams = *streams;
if (sdp) {
frag->sdp = *sdp;
t_queue_init(sdp);
}
if (streams) {
frag->streams = *streams;
t_queue_init(streams);
}
frag->flags = *flags;
t_queue_init(streams);
ZERO(*flags);
mutex_lock(&sdp_fragments_lock);
@ -174,22 +191,22 @@ static void queue_sdp_fragment(ng_buffer *ngbuf, sdp_streams_q *streams, sdp_ng_
mutex_unlock(&sdp_fragments_lock);
}
bool trickle_ice_update(ng_buffer *ngbuf, call_t *call, sdp_ng_flags *flags,
sdp_streams_q *streams)
sdp_streams_q *streams, sdp_sessions_q *sdp)
{
if (!flags->fragment)
return false;
if (!call) {
queue_sdp_fragment(ngbuf, streams, flags);
queue_sdp_fragment(ngbuf, streams, sdp, flags);
return true;
}
struct call_monologue *ml = call_get_monologue(call, &flags->from_tag);
if (!ml) {
queue_sdp_fragment(ngbuf, streams, flags);
queue_sdp_fragment(ngbuf, streams, sdp, flags);
return true;
}
ice_update_media_streams(ml, streams);
ice_update_media_streams(ml, streams, sdp, flags);
return true;
}
@ -219,7 +236,7 @@ void dequeue_sdp_fragments(struct call_monologue *monologue) {
ilog(LOG_DEBUG, "Dequeuing SDP fragment for " STR_FORMAT_M "/" STR_FORMAT_M,
STR_FMT_M(&k.call_id), STR_FMT_M(&k.from_tag));
ice_update_media_streams(monologue, &frag->streams);
ice_update_media_streams(monologue, &frag->streams, &frag->sdp, &frag->flags);
next:
fragment_free(frag);


+ 6
- 3
daemon/janus.c View File

@ -965,8 +965,6 @@ static const char *janus_videoroom_start(struct websocket_message *wm, struct ja
*retcode = 512;
if (sdp_parse(&sdp_in, &parsed, &flags))
return "Failed to parse SDP";
if (sdp_streams(&parsed, &streams, &flags))
return "Incomplete SDP specification";
struct janus_room *room = t_hash_table_lookup(janus_rooms, &room_id);
*retcode = 426;
@ -975,6 +973,11 @@ static const char *janus_videoroom_start(struct websocket_message *wm, struct ja
g_autoptr(call_t) call = call_get(&room->call_id);
if (!call)
return "No such room";
*retcode = 512;
if (sdp_streams(&parsed, &streams, &flags))
return "Incomplete SDP specification";
*retcode = 456;
uint64_t *feed_id = t_hash_table_lookup(room->subscribers, &handle->id);
if (!feed_id)
@ -1672,7 +1675,7 @@ static const char *janus_trickle(JsonReader *reader, struct janus_session *sessi
bencode_strdup_str(&ngbuf->buffer, &sp->ice_ufrag, ufrag);
// finally do the update
trickle_ice_update(ngbuf, call, &flags, &streams);
trickle_ice_update(ngbuf, call, &flags, &streams, NULL);
return NULL;
}


+ 1
- 1
include/ice.h View File

@ -167,7 +167,7 @@ int ice_response(stream_fd *, const endpoint_t *src,
void dequeue_sdp_fragments(struct call_monologue *);
bool trickle_ice_update(ng_buffer *ngbuf, call_t *call, sdp_ng_flags *flags,
sdp_streams_q *streams);
sdp_streams_q *streams, sdp_sessions_q *sdp);
enum thread_looper_action ice_slow_timer(void);


Loading…
Cancel
Save