diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 3525cf1529..d87f828451 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -5144,9 +5144,9 @@ typedef struct pjsua_acc_config * 6xx (global failure), and failure caused by transport problem. * For registration retry caused by transport failure, the first retry * will be done after \a reg_first_retry_interval seconds instead. - * Note that the interval will be randomized slightly by some seconds - * (specified in \a reg_retry_random_interval) to avoid all clients - * re-registering at the same time. + * Note that the interval will be randomized by + * \a reg_retry_random_interval to avoid all clients re-registering at + * the same time; see there for the resulting range. * * See also \a reg_first_retry_interval setting. * @@ -5157,9 +5157,9 @@ typedef struct pjsua_acc_config /** * This specifies the interval for the first registration retry. The * registration retry is explained in \a reg_retry_interval. Note that - * the value here will also be randomized by some seconds (specified - * in \a reg_retry_random_interval) to avoid all clients re-registering - * at the same time. + * the value here will also be randomized by + * \a reg_retry_random_interval to avoid all clients re-registering at + * the same time; see there for the resulting range. * * Default: 0 */ @@ -5172,7 +5172,11 @@ typedef struct pjsua_acc_config * This is useful to avoid all clients re-registering at the same time. * For example, if the registration retry interval is set to 100 seconds * and this is set to 10 seconds, the actual registration retry interval - * will be in the range of 90 to 110 seconds. + * will be in the range of 90 to 110 seconds. If the retry interval is + * shorter than this value, it cannot be reduced by that much, and the + * actual interval will be in the range of 0 to the retry interval plus + * this value instead: for example 0 to 15 seconds for a retry interval + * of 5 seconds. * * Default: 10 */ diff --git a/pjsip/include/pjsua2/account.hpp b/pjsip/include/pjsua2/account.hpp index acf974679b..0bab33fc8c 100644 --- a/pjsip/include/pjsua2/account.hpp +++ b/pjsip/include/pjsua2/account.hpp @@ -114,9 +114,9 @@ struct AccountRegConfig : public PersistentObject * disable auto re-registration. Note that if the registration retry * occurs because of transport failure, the first retry will be done * after \a firstRetryIntervalSec seconds instead. Also note that - * the interval will be randomized slightly by some seconds (specified - * in \a reg_retry_random_interval) to avoid all clients re-registering - * at the same time. + * the interval will be randomized by \a randomRetryIntervalSec to + * avoid all clients re-registering at the same time; see there for + * the resulting range. * * See also \a firstRetryIntervalSec and \a randomRetryIntervalSec * settings. @@ -128,9 +128,9 @@ struct AccountRegConfig : public PersistentObject /** * This specifies the interval for the first registration retry. The * registration retry is explained in \a retryIntervalSec. Note that - * the value here will also be randomized by some seconds (specified - * in \a reg_retry_random_interval) to avoid all clients re-registering - * at the same time. + * the value here will also be randomized by \a randomRetryIntervalSec + * to avoid all clients re-registering at the same time; see there for + * the resulting range. * * See also \a retryIntervalSec and \a randomRetryIntervalSec settings. * @@ -141,11 +141,15 @@ struct AccountRegConfig : public PersistentObject /** * This specifies maximum randomized value to be added/substracted * to/from the registration retry interval specified in \a - * reg_retry_interval and \a reg_first_retry_interval, in second. + * retryIntervalSec and \a firstRetryIntervalSec, in second. * This is useful to avoid all clients re-registering at the same time. * For example, if the registration retry interval is set to 100 seconds * and this is set to 10 seconds, the actual registration retry interval - * will be in the range of 90 to 110 seconds. + * will be in the range of 90 to 110 seconds. If the retry interval is + * shorter than \a randomRetryIntervalSec, it cannot be reduced by that + * much, and the actual interval will be in the range of 0 to the retry + * interval plus \a randomRetryIntervalSec instead: for example 0 to 15 + * seconds for a retry interval of 5 seconds. * * See also \a retryIntervalSec and \a firstRetryIntervalSec settings. * diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index 6d6e8f4552..8bb163d8ed 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -5467,8 +5467,9 @@ static void auto_rereg_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te) } -/* Schedule reregistration for specified account. Note that the first - * re-registration after a registration failure will be done immediately. +/* Schedule reregistration for specified account. Until a registration + * succeeds again, the first retry waits reg_first_retry_interval and later + * ones reg_retry_interval, both randomized by reg_retry_random_interval. * Also note that this function should be called within PJSUA mutex. */ static void schedule_reregistration(pjsua_acc *acc) @@ -5516,19 +5517,27 @@ static void schedule_reregistration(pjsua_acc *acc) acc->auto_rereg.timer.cb = &auto_rereg_timer_cb; acc->auto_rereg.timer.user_data = acc; - /* Reregistration attempt. The first attempt will be done immediately. */ + /* Reregistration attempt. The first one since the last successful + * registration waits reg_first_retry_interval. + */ delay.sec = acc->auto_rereg.attempt_cnt? acc->cfg.reg_retry_interval : acc->cfg.reg_first_retry_interval; delay.msec = 0; - /* Randomize interval by +/- reg_retry_random_interval, if configured */ + /* Randomize interval by +/- reg_retry_random_interval, if configured. + * The lower bound is clamped at 0: an interval shorter than that gives + * a delay between 0 and the interval plus reg_retry_random_interval. + */ if (acc->cfg.reg_retry_random_interval) { long rand_ms = acc->cfg.reg_retry_random_interval * 1000; if (delay.sec >= (long)acc->cfg.reg_retry_random_interval) { delay.msec = -rand_ms + (pj_rand() % (rand_ms * 2)); } else { - delay.sec = 0; + /* A huge unsigned interval may not fit in a long */ + if (delay.sec < 0) + delay.sec = 0; delay.msec = (pj_rand() % (delay.sec * 1000 + rand_ms)); + delay.sec = 0; } } pj_time_val_normalize(&delay);