From: hishamway Date: Thu, 15 Jan 2026 09:34:08 +0000 (+0530) Subject: res_pjsip_session.c: Prevent INVITE failover when session is cancelled X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3468d032e74d1578dc15e43a068c0745d3eb6f0f;p=thirdparty%2Fasterisk.git res_pjsip_session.c: Prevent INVITE failover when session is cancelled When an outbound INVITE transaction times out (408) or receives a 503 error, check_request_status() attempts to failover to the next available address by restarting the INVITE session. However, the function did not check if the inv_session was already cancelled before attempting the failover. This caused unexpected behavior when a caller hung up during a ring group scenario: after CANCEL was sent but the remote endpoint failed to respond with 487 (e.g., due to network disconnection), the transaction timeout would trigger a NEW outbound INVITE to the next address, even though the session was already terminated. This violates RFC 3261 Section 9.1 which states that if no final response is received after CANCEL within 64*T1 seconds, the client should consider the transaction cancelled and destroy it, not retry to another address. The fix adds a check for both PJSIP_INV_STATE_DISCONNECTED and inv->cancelling at the beginning of check_request_status(). This ensures that: - Failover is blocked when the user explicitly cancelled the call (CANCEL sent) - Failover is still allowed for legitimate timeout/503 scenarios where no CANCEL was initiated (e.g., SRV failover when first server is unreachable) Resolves: #1716 --- diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 135aa19279..a731d3ec65 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -4556,6 +4556,10 @@ static int check_request_status(pjsip_inv_session *inv, pjsip_event *e) struct ast_sip_session *session = inv->mod_data[session_module.id]; pjsip_transaction *tsx = e->body.tsx_state.tsx; + if (inv->state == PJSIP_INV_STATE_DISCONNECTED && inv->cancelling) { + return 0; + } + if (tsx->status_code != 503 && tsx->status_code != 408) { return 0; }