diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 6d0bc83ef..3c9608c22 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -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"; diff --git a/daemon/ice.c b/daemon/ice.c index 56a7d4c0c..4b672c104 100644 --- a/daemon/ice.c +++ b/daemon/ice.c @@ -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); diff --git a/daemon/janus.c b/daemon/janus.c index dc4597fcf..a3334f40f 100644 --- a/daemon/janus.c +++ b/daemon/janus.c @@ -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; } diff --git a/include/ice.h b/include/ice.h index 638391090..c2e3a4fda 100644 --- a/include/ice.h +++ b/include/ice.h @@ -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);