Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API to limit retransmission count for outgoing requests in transaction layer #3631

Merged
merged 1 commit into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions pjsip/include/pjsip/sip_transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,23 +454,49 @@ PJ_DECL(pj_status_t) pjsip_tsx_stop_retransmit(pjsip_transaction *tsx);
PJ_DECL(pj_status_t) pjsip_tsx_set_timeout(pjsip_transaction *tsx,
unsigned millisec);


/**
* Change timer values used by transaction layer. Currently scheduled
* timers will not be changed. Any value set to 0 will be left
* unchanged.
*
* @param t1 - Transaction T1 timeout, in msec
* @param t2 - Transaction T2 timeout, in msec
* @param t4 - Transaction completed timer for non-INVITE, in msec
* @param td - Transaction completed timer for INVITE, in msec
* @param t1 Transaction T1 timeout, in msec
* @param t2 Transaction T2 timeout, in msec
* @param t4 Transaction completed timer for non-INVITE, in msec
* @param td Transaction completed timer for INVITE, in msec
*/
PJ_DECL(void) pjsip_tsx_set_timers(unsigned t1, unsigned t2, unsigned t4, unsigned td);
PJ_DECL(void) pjsip_tsx_set_timers(unsigned t1, unsigned t2, unsigned t4,
unsigned td);


/**
* (Re)Initializes timer values from pjsip_cfg().
*/
PJ_DECL(void) pjsip_tsx_initialize_timer_values(void);


/**
* Set maximum retransmission count in transaction layer for outgoing
* requests. When retransmission counter reaches the specified number,
* the transaction will be considered timeout. This will affect any
* ongoing transactions immediately.
*
* By default (or when this is set to -1), retransmission number will
* not cause a transaction to be timeout, only the timer settings will
* cause transaction timeout. Also, this will not override the timer
* settings, i.e: if the timeout timer occurs before the maximum
* retransmission is reached, the transaction will still gets timeout.
*
* When this is set to zero or possitive number P, a transaction timeout
* will occur right before the retransmission number (P+1). For example,
* if this is set to 1 there will be two transmissions: the initial
* transmission and one retransmission, before the transaction gets timeout.
*
* @param max Maximum retransmission count.
*/
PJ_DECL(void) pjsip_tsx_set_max_retransmit_count(int max);


/**
* Get the transaction instance in the incoming message. If the message
* has a corresponding transaction, this function will return non NULL
Expand Down
31 changes: 31 additions & 0 deletions pjsip/src/pjsip/sip_transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ static pj_time_val td_timer_val = { PJSIP_TD_TIMEOUT/1000,
PJSIP_TD_TIMEOUT%1000 };
static pj_time_val timeout_timer_val = { (64*PJSIP_T1_TIMEOUT)/1000,
(64*PJSIP_T1_TIMEOUT)%1000 };
static int max_retrans_count = -1;

#define TIMER_INACTIVE 0
#define RETRANSMIT_TIMER 1
Expand Down Expand Up @@ -479,6 +480,13 @@ PJ_DEF(void) pjsip_tsx_initialize_timer_values(void)
timeout_timer_val = td_timer_val;
}


PJ_DEF(void) pjsip_tsx_set_max_retransmit_count(int max)
{
max_retrans_count = max;
}


/*****************************************************************************
**
** Transaction layer module
Expand All @@ -499,6 +507,9 @@ PJ_DEF(pj_status_t) pjsip_tsx_layer_init_module(pjsip_endpoint *endpt)
/* Initialize timer values */
pjsip_tsx_initialize_timer_values();

/* Reset max retrans count (for library restart scenario) */
max_retrans_count = -1;

/*
* Initialize transaction layer structure.
*/
Expand Down Expand Up @@ -2562,6 +2573,26 @@ static pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched)

PJ_ASSERT_RETURN(tsx->last_tx!=NULL, PJ_EBUG);

/* If max retransmission count is reached, put it as timeout */
if (max_retrans_count >= 0 &&
tsx->retransmit_count >= max_retrans_count &&
tsx->last_tx->msg->type == PJSIP_REQUEST_MSG)
{
pj_time_val timeout = { 0, 0 };

PJ_LOG(3,(tsx->obj_name,
"Stop retransmiting %s, max retrans %d reached, "
"tsx set as timeout",
pjsip_tx_data_get_info(tsx->last_tx),
tsx->retransmit_count));

lock_timer(tsx);
tsx_cancel_timer( tsx, &tsx->timeout_timer );
tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout, TIMEOUT_TIMER);
unlock_timer(tsx);
return PJ_SUCCESS;
}

PJ_LOG(5,(tsx->obj_name, "Retransmiting %s, count=%d, restart?=%d",
pjsip_tx_data_get_info(tsx->last_tx),
tsx->retransmit_count, resched));
Expand Down
Loading