res_pjsip_session.c: Fix unbound srv failover tests.
authorRichard Mudgett <rmudgett@digium.com>
Wed, 17 Aug 2016 19:13:56 +0000 (14:13 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 17 Aug 2016 21:14:11 +0000 (16:14 -0500)
Commit 1b666549f33d69dc080b212bf92126f3bc3a18b2 broke the srv failover
functionality if a TCP connection gets disconnected.  Under these
conditions, session_inv_on_state_changed() gets a
PJSIP_EVENT_TRANSPORT_ERROR and restarts the INVITE transaction on a new
transport.  Unfortunately, session_inv_on_tsx_state_changed() also gets
the same PJSIP_EVENT_TRANSPORT_ERROR event and unconditionally terminates
the session.

* Made session_inv_on_tsx_state_changed() complete terminating the session
on PJSIP_EVENT_TRANSPORT_ERROR only if the session state is still
PJSIP_INV_STATE_DISCONNECTED.

ASTERISK-26305 #close
Reported by: Richard Mudgett

Change-Id: If736e766b5c55b970fa38ca6c8a885caf27b897d

res/res_pjsip_session.c

index 488492f..315393f 100644 (file)
@@ -2773,22 +2773,21 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
                }
                break;
        case PJSIP_EVENT_TRANSPORT_ERROR:
-               /*
-                * Clear the module data now to block session_inv_on_state_changed()
-                * from calling session_end() if it hasn't already done so.
-                */
-               inv->mod_data[id] = NULL;
+               if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
+                       /*
+                        * Clear the module data now to block session_inv_on_state_changed()
+                        * from calling session_end() if it hasn't already done so.
+                        */
+                       inv->mod_data[id] = NULL;
 
-               if (inv->state != PJSIP_INV_STATE_DISCONNECTED) {
-                       session_end(session);
+                       /*
+                        * Pass the session ref held by session->inv_session to
+                        * session_end_completion().
+                        */
+                       session_end_completion(session);
+                       return;
                }
-
-               /*
-                * Pass the session ref held by session->inv_session to
-                * session_end_completion().
-                */
-               session_end_completion(session);
-               return;
+               break;
        case PJSIP_EVENT_TIMER:
                /*
                 * The timer event is run by the pjsip monitor thread and not
@@ -2808,7 +2807,8 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
                         * Pass the session ref held by session->inv_session to
                         * session_end_completion().
                         */
-                       if (ast_sip_push_task(session->serializer, session_end_completion, session)) {
+                       if (session
+                               && ast_sip_push_task(session->serializer, session_end_completion, session)) {
                                /* Do it anyway even though this is not the right thread. */
                                session_end_completion(session);
                        }