]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
fax: Fix crashes in PJSIP re-negotiation scenarios.
authorJoshua C. Colp <jcolp@sangoma.com>
Mon, 20 Apr 2020 15:18:24 +0000 (12:18 -0300)
committerGeorge Joseph <gjoseph@digium.com>
Thu, 30 Apr 2020 15:50:47 +0000 (10:50 -0500)
This change fixes a few re-negotiation issues
uncovered with fax.

1. The fax support uses its own mechanism for
re-negotiation by conveying T.38 information in
its own frames. The new support for re-negotiating
when adding/removing/changing streams was also
being triggered for this causing multiple re-INVITEs.
The new support will no longer trigger when
transitioning between fax.

2. In off-nominal re-negotiation cases it was
possible for some state information to be left
over and used by the next re-negotiation. This
is now cleared.

ASTERISK-28811
ASTERISK-28839

Change-Id: I8ed5924b53be9fe06a385c58817e5584b0f25cc2
(cherry picked from commit f3ac42b9bd0d436ce2128e5bbb0502ddb587f98a)

res/res_pjsip_session.c

index 9cc62ce5752b9dc3d5b995f964a85e2ff08abc15..1bbc6fa0bc539ec5dd793d05dc0dfb3c1936e3af 100644 (file)
@@ -1066,11 +1066,14 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
        if (topology) {
                ast_channel_set_stream_topology(session->channel, topology);
                /* If this is a remotely done renegotiation that has changed the stream topology notify what is
-                * currently handling this channel.
+                * currently handling this channel. Note that fax uses its own process, so if we are transitioning
+                * between audio and fax or vice versa we don't notify.
                 */
                if (pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE &&
                        session->active_media_state && session->active_media_state->topology &&
-                       !ast_stream_topology_equal(session->active_media_state->topology, topology)) {
+                       !ast_stream_topology_equal(session->active_media_state->topology, topology) &&
+                       !session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE] &&
+                       !session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE]) {
                        changed = 2;
                }
        }
@@ -2046,6 +2049,7 @@ static pj_bool_t session_reinvite_on_rx_request(pjsip_rx_data *rdata)
        pjsip_dialog *dlg;
        RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
        pjsip_rdata_sdp_info *sdp_info;
+       int deferred;
 
        if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD ||
                !(dlg = pjsip_ua_find_dialog(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag, PJ_FALSE)) ||
@@ -2135,7 +2139,11 @@ static pj_bool_t session_reinvite_on_rx_request(pjsip_rx_data *rdata)
                return PJ_FALSE;
        }
 
-       if (!sdp_requires_deferral(session, sdp_info->sdp)) {
+       deferred = sdp_requires_deferral(session, sdp_info->sdp);
+       if (deferred == -1) {
+               ast_sip_session_media_state_reset(session->pending_media_state);
+               return PJ_FALSE;
+       } else if (!deferred) {
                return PJ_FALSE;
        }
 
@@ -4251,6 +4259,7 @@ static void session_inv_on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_se
 
        session = inv->mod_data[session_module.id];
        if (handle_incoming_sdp(session, offer)) {
+               ast_sip_session_media_state_reset(session->pending_media_state);
                return;
        }
 
@@ -4329,7 +4338,9 @@ static void session_inv_on_media_update(pjsip_inv_session *inv, pj_status_t stat
                return;
        }
 
-       handle_negotiated_sdp(session, local, remote);
+       if (handle_negotiated_sdp(session, local, remote)) {
+               ast_sip_session_media_state_reset(session->pending_media_state);
+       }
 }
 
 static pjsip_redirect_op session_inv_on_redirected(pjsip_inv_session *inv, const pjsip_uri *target, const pjsip_event *e)