]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip_t38.c: Fix crash by ignoring 1xx messages.
authorRichard Mudgett <rmudgett@digium.com>
Fri, 29 Jun 2018 23:28:26 +0000 (18:28 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Mon, 2 Jul 2018 16:41:05 +0000 (11:41 -0500)
If we initiated a T.38 reINVITE, we would crash if we received any other
1xx response message except 100 if it were followed by a 200 response.

* Made ignore any 1xx response so we do not close out the T.38 negotiation
too early.  For good measure we'll now accept any 2xx response as
acceptance of the reINVITE T.38 offer.

NOTE: In v13 we don't actually crash but we should deal with the non-final
response messages and not switch to rejected and then to enabled when the
200 comes in.

ASTERISK-27944

Change-Id: I0ca88aae708d091db7335af73f41035a212adff4

res/res_pjsip_t38.c

index a3cdc57f7703bcda0f64a35f2765549299506f96..757c66711c9ed18faff8e6fae4fdd8974d47d205 100644 (file)
@@ -245,8 +245,6 @@ static struct t38_state *t38_state_get_or_alloc(struct ast_sip_session *session)
        /* This will get bumped up before scheduling */
        pj_timer_entry_init(&state->timer, 0, session, t38_automatic_reject_timer_cb);
 
-       datastore->data = state;
-
        return state;
 }
 
@@ -296,18 +294,22 @@ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_da
        struct t38_state *state;
        struct ast_sip_session_media *session_media = NULL;
 
-       if (status.code == 100) {
+       if (status.code / 100 <= 1) {
+               /* Ignore any non-final responses (1xx) */
                return 0;
        }
 
        if (!session->channel || !(state = t38_state_get_or_alloc(session)) ||
                !(session_media = ao2_find(session->media, "image", OBJ_KEY))) {
-               ast_log(LOG_WARNING, "Received response to T.38 re-invite on '%s' but state unavailable\n",
+               ast_log(LOG_WARNING, "Received %d response to T.38 re-invite on '%s' but state unavailable\n",
+                       status.code,
                        session->channel ? ast_channel_name(session->channel) : "unknown channel");
                return 0;
        }
 
-       t38_change_state(session, session_media, state, (status.code == 200) ? T38_ENABLED : T38_REJECTED);
+       /* Accept any 2xx response as successfully negotiated */
+       t38_change_state(session, session_media, state,
+               (status.code / 100 == 2) ? T38_ENABLED : T38_REJECTED);
 
        ao2_cleanup(session_media);
        return 0;