Skip to content

pjsua: auto re-registration ignores the retry interval when it is below the jitter #5318

Closed

Description

@laconicman

Summary

schedule_reregistration() randomises the registration retry delay by reg_retry_random_interval (10 s by default). When the retry interval is below that value, the code clears delay.sec before using it:

/* Randomize interval by +/- reg_retry_random_interval, if configured */
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;
delay.msec = (pj_rand() % (delay.sec * 1000 + rand_ms));
}
}

so delay.sec * 1000 is always 0 and the delay is a uniform 0 to reg_retry_random_interval, whatever the interval is. A reg_retry_interval or reg_first_retry_interval of 1 and one of 9 behave alike, and the mean delay is 5 s for every value below 10 but 10 s at 10, so a longer interval can retry sooner on average.

This was pointed out in the review of #5306, which makes it reachable from pjsua through --rereg-delay. It affects any application that sets these fields through the C or pjsua2 API.

History

The 2011 code (#1375) was flat: if (delay.sec >= 10) { ±10 s } else { delay.sec = 0; delay.msec = rand % 10000; }. e9268d2 (#1802) made the 10 configurable and wrote delay.sec * 1000 + rand_ms in the modulo, but cleared delay.sec on the line before, so that term has been 0 ever since. The behaviour is the one the code has had since 2011, not a regression.

Steps to reproduce

With #5306 applied, so that --rereg-delay reaches the account, run pjsua against a TCP registrar port with nothing listening on it:

pjsua --null-audio --no-udp --id sip:test@127.0.0.1 --registrar 'sip:127.0.0.1:5999;transport=tcp' --realm '*' --username test --password test --rereg-delay=9

Expected: retries about 9 s apart, spread by reg_retry_random_interval (0 to 19 s). Actual: retries 0 to 10 s apart, the same as for --rereg-delay=1.

Fix

PR to follow. It computes the delay before clearing delay.sec, so the delay is uniform in 0 to the interval plus reg_retry_random_interval. An interval of 0 (the default reg_first_retry_interval) and intervals of reg_retry_random_interval or more are unchanged. It also adds a sentence to the reg_retry_random_interval documentation, because the documented "interval ± reg_retry_random_interval" cannot apply below the jitter, where the lower end would be negative.

Suggested labels

component: pjsua-lib, type: bug.

Version and context

master 9192b71b6. macOS 26 on arm64, default configure; the code path is platform-independent.

Log

The "Scheduling re-registration retry for acc 1 in N seconds" values after the first retry, over 155 s with --rereg-delay=9: 25 retries, none longer than 9 s.

6 2 0 1 4 0 7 2 8 4 7 4 9 2 5 9 6 1 3 0 1 1 0 3 8

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions