mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	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
		
			
				
	
	
		
			72 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| 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);
 | |
|      }
 | |
|  }
 |