Skip to content
Snippets Groups Projects
Commit 0b532367 authored by Joshua Colp's avatar Joshua Colp
Browse files

pjsip: Ignore state changes from old transactions.

When we fail over to a new target we create a new transaction
and it becomes the current INVITE transaction. This does not
prevent the previous transaction from raising state changes
and causing the session to be prematurely disconnected if a
transport error occurs immediately.

This change backports a fix from PJSIP that eliminates the
incorrect state change and reduces when they would be raised
in the first place.

ASTERISK-27408

Change-Id: Id22d087591782eee31311753d11e7eca4b95ef34
parent c2ec82bf
No related branches found
No related tags found
No related merge requests found
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);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment