[asterisk-bugs] [JIRA] (ASTERISK-27441) PJSIP: Need ignoresdpversion option that chan_sip has for parity.

lvl (JIRA) noreply at issues.asterisk.org
Tue Nov 28 10:43:07 CST 2017


    [ https://issues.asterisk.org/jira/browse/ASTERISK-27441?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=240313#comment-240313 ] 

lvl commented on ASTERISK-27441:
--------------------------------

I can now 100% confirm that this has nothing to do with SDP versioning. The Asterisk 15 architecture simply doesn't account for a scenario where SDP is re-negotiated between a 183 and 200.

The 183 is processed as a regular negotiation. This means that if the negotiation is succesful, _pending_media_state_ will become _active_media_state_, and the actual _pending_media_state_ is cleared:

{code}
handle_negotiated_sdp:

	SWAP(session->active_media_state, session->pending_media_state);
	ast_sip_session_media_state_reset(session->pending_media_state);
{code}

When the 200 is received, Pjsip will map it onto the existing session:

{code}
sip_ua_layer.c ...Unhandled forked Response msg 200/INVITE/cseq=15621 (rdata0x7f492001f4d8), response will be handed over to the first dialog
{code}

... and correctly trigger a _on_media_update_ for that session, which is relayed to asterisk as _session_inv_on_media_update_ -> _handle_negotiated_sdp_.

There, the negotiation will be blocked by this code:

{code}
handle_negotiated_sdp:

	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;
	}
{code}

... because - remember? - we cleared the session's _session->pending_media_state->topology_ after processing the 183.

I think the fix is for _handle_negotiated_sdp_ to 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 & active media are empty, should _handle_negotiated_sdp_ break.

Coming up is a proof of concept patch, which is verified to fix the scenario described in this issue.

> PJSIP: Need ignoresdpversion option that chan_sip has for parity.
> -----------------------------------------------------------------
>
>                 Key: ASTERISK-27441
>                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-27441
>             Project: Asterisk
>          Issue Type: Bug
>      Security Level: None
>          Components: Channels/chan_pjsip
>    Affects Versions: 15.1.2
>            Reporter: lvl
>            Assignee: Unassigned
>         Attachments: asterisk-sdpversion-log.txt
>
>
> The scenario:
> 1. Asterisk dials outbound using chan_pjsip
> 2. The remote party sends an 183, with IP address 1.2.3.4 in the SDP *1
> 3. RTP is now flowing between Asterisk and 1.2.3.4
> 4. The remote party sends a 200, with a *new* IP address 5.6.7.8 in the SDP *2
> 5. Asterisk is not applying the new SDP details. 5.6.7.8 will start sending RTP to Asterisk, which is rejected:
> {code}
> [Nov 22 14:29:48] DEBUG[8280][C-00000001]: res_rtp_asterisk.c:5743 ast_rtp_read: 0x7f021c0286e0 -- Received RTP packet from 5.6.7.8:9898, dropping due to strict RTP protection.
> {code}
> The following log lines hint at the root cause:
> {code}
> [Nov 22 14:29:46] DEBUG[8237]: res_pjsip_session.c:3187 handle_incoming: Received response
> [Nov 22 14:29:46] DEBUG[8237]: res_pjsip_session.c:3171 handle_incoming_response: Response is 200 OK
> [Nov 22 14:29:46] DEBUG[8237]: res_pjsip_session.c:798 handle_negotiated_sdp: Pending topology was NULL for channel 'PJSIP/proxy-00000001'
> {code}
> The message is triggered by the code in https://github.com/asterisk/asterisk/blob/15.1/res/res_pjsip_session.c#L796. Because there is no "session->pending_media_state->topology" at this point, the *handle_negotiated_sdp* function is aborted and RTP from the new IP address is ignored as the session is not moved to the STRICT_RTP_LEARN state.
> This behavior was introduced in commit https://github.com/asterisk/asterisk/commit/40de3a12e0caddec0be31aa4ad996c22fc716be5. Reverting that code will however cause Asterisk to segfault on the scenario as described.
> It's not clear to me yet why *session->pending_media_state->topology* is null in this scenario, as opposed to all other scenarios where SDP is updated for an existing session.
> *1
> {code}
> SIP/2.0 183 Session Progress
> v=0
> o=root 1910284739 1910284739 IN IP4 1.2.3.4
> c=IN IP4 1.2.3.4
> {code}
> *2
> {code}
> SIP/2.0 200 OK
> v=0
> o=root 4067 4067 IN IP4 5.6.7.8
> c=IN IP4 5.6.7.8
> {code}



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list