summaryrefslogtreecommitdiff
path: root/third-party/pjproject/patches/0050-dont_terminate_session_early.patch
blob: 718968c79d6db661f1f632b202a178193e9ee897 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
commit ca0b723e92bd76bbda1bbd14477a829eaeeb675e
Author: Joshua Colp <jcolp@digium.com>
Date:   Wed Dec 13 10:58:57 2017 +0000

    Ignore transport error on completed transaction.
    Don't disconnect call if transport error happens on transaction that is not initial INVITE transaction.
    
    Scenario:
    
    DNS lookup returning two servers.
    Sending INVITE to first server over TCP.
    Response received with code 503 (Service Unavailable).
    Failover to second server, sending second INVITE after restarting the session.
    TCP connection for the first INVITE getting disconnected and causing call disconnection (while second INVITE is still outstanding).
    
    This is a backport of 5714 from upstream PJSIP.

diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index ac4d1949..0173cb4c 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -4254,8 +4254,7 @@ static void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e)
 	if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST &&
 		tsx->method.id != PJSIP_CANCEL_METHOD) ||
 	    tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||
-	    tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||
-	    tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR)
+	    tsx->status_code == PJSIP_SC_TSX_TIMEOUT)
 	{
 	    inv_set_cause(inv, tsx->status_code, &tsx->status_text);
 	    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 7ac3d1b7..d52b12a7 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -2044,9 +2044,14 @@ static void transport_callback(void *token, pjsip_tx_data *tdata,
 	 */
 	lock_timer(tsx);
 	tsx->transport_err = (pj_status_t)-sent;
-	tsx_cancel_timer(tsx, &tsx->timeout_timer);
-	tsx_schedule_timer(tsx, &tsx->timeout_timer, &delay,
-	                   TRANSPORT_ERR_TIMER);
+	/* Don't cancel timeout timer if tsx state is already
+	 * PJSIP_TSX_STATE_COMPLETED (see #2076).
+	 */
+	if (tsx->state < PJSIP_TSX_STATE_COMPLETED) {
+	    tsx_cancel_timer(tsx, &tsx->timeout_timer);
+	    tsx_schedule_timer(tsx, &tsx->timeout_timer, &delay,
+			       TRANSPORT_ERR_TIMER);
+	}
 	unlock_timer(tsx);
    }
 
@@ -2077,9 +2082,14 @@ static void tsx_tp_state_callback( pjsip_transport *tp,
 	 */
 	lock_timer(tsx);
 	tsx->transport_err = info->status;
-	tsx_cancel_timer(tsx, &tsx->timeout_timer);
-	tsx_schedule_timer(tsx, &tsx->timeout_timer, &delay,
-	                   TRANSPORT_ERR_TIMER);
+	/* Don't cancel timeout timer if tsx state is already
+	 * PJSIP_TSX_STATE_COMPLETED (see #2076).
+	 */
+	if (tsx->state < PJSIP_TSX_STATE_COMPLETED) {
+	    tsx_cancel_timer(tsx, &tsx->timeout_timer);
+	    tsx_schedule_timer(tsx, &tsx->timeout_timer, &delay,
+			       TRANSPORT_ERR_TIMER);
+	}
 	unlock_timer(tsx);
     }
 }