From: lvl Date: Tue, 20 Feb 2018 17:48:50 +0000 (+0100) Subject: res_pjsip_session: properly handle SDP from a forked call with early media X-Git-Tag: 16.0.0-rc1~280^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3fb26df4acd712fbbac78dd9e88235d37024b2fa;p=thirdparty%2Fasterisk.git res_pjsip_session: properly handle SDP from a forked call with early media In handle_negotiated_sdp(), use session->active_media_state when session->pending_media_state is empty. The 200's SDP should be fed into handle_negotiated_sdp_session_media() together with the already negotiated state, which is now in session->active_media_state instead. Only if both the session's pending and active media are empty should handle_negotiated_sdp() abort. ASTERISK-27441 Change-Id: If0d5150ffe6f38d8a854831fef37942258d4629c --- diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index fcd190bcbb..f252017310 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -876,15 +876,30 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_ struct ast_stream_topology *topology; unsigned int changed = 0; - /* This situation can legitimately happen when an SDP is received in a - * 183 Session Progress message. In that case, everything's been done - * by the time this function is called and there are no more pending - * streams. - */ if (!session->pending_media_state->topology) { - ast_debug(1, "Pending topology was NULL for channel '%s'\n", - session->channel ? ast_channel_name(session->channel) : "unknown"); - return 0; + if (session->active_media_state->topology) { + /* + * This happens when we have negotiated media after receiving a 183, + * and we're now receiving a 200 with a new SDP. In this case, there + * is active_media_state, but the pending_media_state has been reset. + */ + struct ast_sip_session_media_state *active_media_state_clone; + + active_media_state_clone = + ast_sip_session_media_state_clone(session->active_media_state); + if (!active_media_state_clone) { + ast_log(LOG_WARNING, "Unable to clone active media state for channel '%s'\n", + session->channel ? ast_channel_name(session->channel) : "unknown"); + return -1; + } + + ast_sip_session_media_state_free(session->pending_media_state); + session->pending_media_state = active_media_state_clone; + } else { + ast_log(LOG_WARNING, "No pending or active media state for channel '%s'\n", + session->channel ? ast_channel_name(session->channel) : "unknown"); + return -1; + } } /* If we're handling negotiated streams, then we should already have set