@@ -1527,6 +1527,74 @@ enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
15271527 return RPS_ERROR ;
15281528}
15291529
1530+ void process_reply_and_timer (struct cell * t ,int branch ,int msg_status ,
1531+ struct sip_msg * p_msg ,int last_uac_status , struct ua_client * uac )
1532+ {
1533+ int reply_status ;
1534+ branch_bm_t cancel_bitmap = 0 ;
1535+ utime_t timer ;
1536+
1537+ /* we fire a cancel on spot if (a) branch is marked "to be canceled" or (b)
1538+ * the whole transaction was canceled (received cancel) and no cancel sent
1539+ * yet on this branch; and of course, only if a provisional reply :) */
1540+ if (t -> uac [branch ].flags & T_UAC_TO_CANCEL_FLAG ||
1541+ ((t -> flags & T_WAS_CANCELLED_FLAG ) && !t -> uac [branch ].local_cancel .buffer .s )) {
1542+ if ( msg_status < 200 )
1543+ /* reply for an UAC with a pending cancel -> do cancel now */
1544+ cancel_branch (t , branch );
1545+ /* reset flag */
1546+ t -> uac [branch ].flags &= ~(T_UAC_TO_CANCEL_FLAG );
1547+ }
1548+
1549+ if (is_local (t )) {
1550+ reply_status = local_reply (t ,p_msg , branch ,msg_status ,& cancel_bitmap );
1551+ if (reply_status == RPS_COMPLETED ) {
1552+ cleanup_uac_timers (t );
1553+ if (is_invite (t )) cancel_uacs (t , cancel_bitmap );
1554+ /* There is no need to call set_final_timer because we know
1555+ * that the transaction is local */
1556+ put_on_wait (t );
1557+ }
1558+ } else {
1559+ reply_status = relay_reply (t ,p_msg ,branch ,msg_status ,& cancel_bitmap );
1560+ /* clean-up the transaction when transaction completed */
1561+ if (reply_status == RPS_COMPLETED ) {
1562+ /* no more UAC FR/RETR (if I received a 2xx, there may
1563+ * be still pending branches ...
1564+ */
1565+ cleanup_uac_timers (t );
1566+ if (is_invite (t )) cancel_uacs (t , cancel_bitmap );
1567+ /* FR for negative INVITES, WAIT anything else */
1568+ /* set_final_timer(t); */
1569+ }
1570+ }
1571+
1572+ if (reply_status != RPS_PROVISIONAL )
1573+ return ;
1574+
1575+ /* update FR/RETR timers on provisional replies */
1576+ if (msg_status < 200 && (restart_fr_on_each_reply ||
1577+ ((last_uac_status < msg_status ) &&
1578+ ((msg_status >= 180 ) || (last_uac_status == 0 )))
1579+ ) ) { /* provisional now */
1580+ if (is_invite (t )) {
1581+ /* invite: change FR to longer FR_INV, do not
1582+ * attempt to restart retransmission any more
1583+ */
1584+ timer = is_timeout_set (t -> fr_inv_timeout ) ?
1585+ t -> fr_inv_timeout :
1586+ timer_id2timeout [FR_INV_TIMER_LIST ];
1587+
1588+ LM_DBG ("FR_INV_TIMER = %lld\n" , timer );
1589+ set_timer (& uac -> request .fr_timer , FR_INV_TIMER_LIST , & timer );
1590+ } else {
1591+ /* non-invite: restart retransmissions (slow now) */
1592+ uac -> request .retr_list = RT_T2 ;
1593+ set_timer (& uac -> request .retr_timer , RT_T2 , 0 );
1594+ }
1595+ } /* provisional replies */
1596+
1597+ }
15301598
15311599/* This function is called whenever a reply for our module is received;
15321600 * we need to register this function on module initialization;
@@ -1538,10 +1606,7 @@ int reply_received( struct sip_msg *p_msg )
15381606 int msg_status ;
15391607 int last_uac_status ;
15401608 int branch ;
1541- int reply_status ;
1542- utime_t timer ;
15431609 /* has the transaction completed now and we need to clean-up? */
1544- branch_bm_t cancel_bitmap ;
15451610 struct ua_client * uac ;
15461611 struct cell * t ;
15471612 struct usr_avp * * backup_list ;
@@ -1561,7 +1626,6 @@ int reply_received( struct sip_msg *p_msg )
15611626 t = get_t ();
15621627 if ((t == 0 ) || (t == T_UNDEFINED )) goto not_found ;
15631628
1564- cancel_bitmap = 0 ;
15651629 msg_status = p_msg -> REPLY_STATUS ;
15661630
15671631 uac = & t -> uac [branch ];
@@ -1696,65 +1760,7 @@ int reply_received( struct sip_msg *p_msg )
16961760 /* mark that the UAC received replies */
16971761 uac -> flags |= T_UAC_HAS_RECV_REPLY ;
16981762
1699- /* we fire a cancel on spot if (a) branch is marked "to be canceled" or (b)
1700- * the whole transaction was canceled (received cancel) and no cancel sent
1701- * yet on this branch; and of course, only if a provisional reply :) */
1702- if (t -> uac [branch ].flags & T_UAC_TO_CANCEL_FLAG ||
1703- ((t -> flags & T_WAS_CANCELLED_FLAG ) && !t -> uac [branch ].local_cancel .buffer .s )) {
1704- if ( msg_status < 200 )
1705- /* reply for an UAC with a pending cancel -> do cancel now */
1706- cancel_branch (t , branch );
1707- /* reset flag */
1708- t -> uac [branch ].flags &= ~(T_UAC_TO_CANCEL_FLAG );
1709- }
1710-
1711- if (is_local (t )) {
1712- reply_status = local_reply (t ,p_msg , branch ,msg_status ,& cancel_bitmap );
1713- if (reply_status == RPS_COMPLETED ) {
1714- cleanup_uac_timers (t );
1715- if (is_invite (t )) cancel_uacs (t , cancel_bitmap );
1716- /* There is no need to call set_final_timer because we know
1717- * that the transaction is local */
1718- put_on_wait (t );
1719- }
1720- } else {
1721- reply_status = relay_reply (t ,p_msg ,branch ,msg_status ,& cancel_bitmap );
1722- /* clean-up the transaction when transaction completed */
1723- if (reply_status == RPS_COMPLETED ) {
1724- /* no more UAC FR/RETR (if I received a 2xx, there may
1725- * be still pending branches ...
1726- */
1727- cleanup_uac_timers (t );
1728- if (is_invite (t )) cancel_uacs (t , cancel_bitmap );
1729- /* FR for negative INVITES, WAIT anything else */
1730- /* set_final_timer(t); */
1731- }
1732- }
1733-
1734- if (reply_status != RPS_PROVISIONAL )
1735- goto done ;
1736-
1737- /* update FR/RETR timers on provisional replies */
1738- if (msg_status < 200 && (restart_fr_on_each_reply ||
1739- ((last_uac_status < msg_status ) &&
1740- ((msg_status >= 180 ) || (last_uac_status == 0 )))
1741- ) ) { /* provisional now */
1742- if (is_invite (t )) {
1743- /* invite: change FR to longer FR_INV, do not
1744- * attempt to restart retransmission any more
1745- */
1746- timer = is_timeout_set (t -> fr_inv_timeout ) ?
1747- t -> fr_inv_timeout :
1748- timer_id2timeout [FR_INV_TIMER_LIST ];
1749-
1750- LM_DBG ("FR_INV_TIMER = %lld\n" , timer );
1751- set_timer (& uac -> request .fr_timer , FR_INV_TIMER_LIST , & timer );
1752- } else {
1753- /* non-invite: restart retransmissions (slow now) */
1754- uac -> request .retr_list = RT_T2 ;
1755- set_timer (& uac -> request .retr_timer , RT_T2 , 0 );
1756- }
1757- } /* provisional replies */
1763+ process_reply_and_timer (t ,branch ,msg_status ,p_msg ,last_uac_status ,uac );
17581764
17591765done :
17601766 /* we are done with the transaction, so unref it - the reference
0 commit comments