Ignore:
Timestamp:
Apr 11, 2007 6:30:31 PM (12 years ago)
Author:
bennylp
Message:

Fixed ticket #220: Bug in retransmission of non-INVITE SIP requests in UAC transaction (thanks Martin Peterzon)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/pjproject-0.5-stable/pjsip/src/pjsip/sip_transaction.c

    r1077 r1189  
    133133static const pj_time_val t1_timer_val = { PJSIP_T1_TIMEOUT/1000,  
    134134                                          PJSIP_T1_TIMEOUT%1000 }; 
     135static const pj_time_val t2_timer_val = { PJSIP_T2_TIMEOUT/1000,  
     136                                          PJSIP_T2_TIMEOUT%1000 }; 
    135137static const pj_time_val t4_timer_val = { PJSIP_T4_TIMEOUT/1000,  
    136138                                          PJSIP_T4_TIMEOUT%1000 }; 
     
    13971399 
    13981400/* 
    1399  * Set the UAC absolute transaction timeout. 
    1400  */ 
    1401 PJ_DEF(pj_status_t) pjsip_tsx_set_uac_timeout(pjsip_transaction *tsx, 
    1402                                               unsigned msec_time, 
    1403                                               pjsip_tsx_timeout_policy policy) 
    1404 { 
    1405     PJ_ASSERT_RETURN(tsx && tsx->role==PJSIP_ROLE_UAC && 
    1406                      tsx->state==PJSIP_TSX_STATE_NULL, PJ_EINVALIDOP); 
    1407  
    1408     tsx->msec_timeout = msec_time; 
    1409     tsx->timeout_policy = policy; 
    1410  
    1411     return PJ_SUCCESS; 
    1412 } 
    1413  
    1414  
    1415 /* 
    14161401 * Set transaction status code and reason. 
    14171402 */ 
     
    18101795    pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0); 
    18111796 
    1812     msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT; 
     1797    pj_assert(tsx->status_code < 200); 
     1798 
     1799    if (tsx->status_code >= 100) 
     1800        msec_time = PJSIP_T2_TIMEOUT; 
     1801    else 
     1802        msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT; 
    18131803 
    18141804    if (tsx->role == PJSIP_ROLE_UAC) { 
     
    19141904 
    19151905        /* Start Timer B (or called timer F for non-INVITE) for transaction  
    1916          * timeout. If user has configured the timeout value with  
    1917          * pjsip_tsx_set_uac_timeout(), use the timeout value there. 
     1906         * timeout. 
    19181907         */ 
    1919         if (tsx->msec_timeout > 0) { 
    1920             pj_time_val timeout; 
    1921  
    1922             timeout.sec = tsx->msec_timeout / 1000; 
    1923             timeout.msec = tsx->msec_timeout % 1000; 
    1924  
    1925             pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,  
    1926                                         &timeout); 
    1927  
    1928         } else { 
    1929             pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,  
    1930                                         &timeout_timer_val); 
    1931         } 
     1908        pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,  
     1909                                    &timeout_timer_val); 
    19321910 
    19331911        /* Start Timer A (or timer E) for retransmission only if unreliable  
     
    20061984            return PJSIP_ENOTRESPONSEMSG; 
    20071985 
    2008         /* Cancel retransmission timer A. */ 
    2009         if (tsx->retransmit_timer._timer_id != -1) { 
    2010             pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); 
    2011             tsx->retransmit_timer._timer_id = -1; 
    2012         } 
     1986        code = msg->line.status.code; 
     1987 
     1988        /* If the response is final, cancel both retransmission and timeout 
     1989         * timer. 
     1990         */ 
     1991        if (code >= 200) { 
     1992            if (tsx->retransmit_timer._timer_id != -1) { 
     1993                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); 
     1994                tsx->retransmit_timer._timer_id = -1; 
     1995            } 
     1996 
     1997            if (tsx->timeout_timer._timer_id != -1) { 
     1998                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 
     1999                tsx->timeout_timer._timer_id = -1; 
     2000            } 
     2001 
     2002        } else { 
     2003            /* Cancel retransmit timer (for non-INVITE transaction, the 
     2004             * retransmit timer will be rescheduled at T2. 
     2005             */ 
     2006            if (tsx->retransmit_timer._timer_id != -1) { 
     2007                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); 
     2008                tsx->retransmit_timer._timer_id = -1; 
     2009            } 
     2010 
     2011            /* For provisional response, only cancel retransmit when this 
     2012             * is an INVITE transaction. For non-INVITE, section 17.1.2.1 
     2013             * of RFC 3261 says that: 
     2014             *  - retransmit timer is set to T2 
     2015             *  - timeout timer F is not deleted. 
     2016             */ 
     2017            if (tsx->method.id == PJSIP_INVITE_METHOD) { 
     2018 
     2019                /* Cancel timeout timer */ 
     2020                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 
     2021 
     2022            } else { 
     2023                if (!tsx->is_reliable) { 
     2024                    pjsip_endpt_schedule_timer(tsx->endpt,  
     2025                                               &tsx->retransmit_timer, 
     2026                                               &t2_timer_val); 
     2027                } 
     2028            } 
     2029        } 
     2030          
    20132031        tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED); 
    20142032 
    2015  
    2016         /* Cancel timer B (transaction timeout) but look at the timeout policy 
    2017          * as set by pjsip_tsx_set_uac_timeout(). 
    2018          */ 
    2019         code = msg->line.status.code; 
    2020         if ((code==100 && tsx->timeout_policy==PJSIP_TSX_IGNORE_100) || 
    2021             (code<200 && tsx->timeout_policy==PJSIP_TSX_IGNORE_1xx)) 
    2022         { 
    2023             /* Don't cancel the timeout timer */ 
    2024         } 
    2025         else { 
    2026             pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 
    2027         } 
    20282033 
    20292034        /* Discard retransmission message if it is not INVITE. 
     
    23682373 
    23692374    } else { 
    2370         tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL); 
     2375        if (event->body.timer.entry == &tsx->retransmit_timer) { 
     2376            /* Retransmit message. */ 
     2377            pj_status_t status; 
     2378 
     2379            status = tsx_retransmit( tsx, 1 ); 
     2380             
     2381            return status; 
     2382 
     2383        } else { 
     2384            tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL); 
     2385        } 
    23712386    } 
    23722387 
Note: See TracChangeset for help on using the changeset viewer.