Skip to content

recovery: don't let receiver traffic refresh a link awaiting REG3 - #19

Merged
datagutt merged 1 commit into
irlserver:mainfrom
ziggy6792:recovery-limbo-standalone
Sep 24, 2026
Merged

datagutt merged 1 commit into
irlserver:mainfrom
ziggy6792:recovery-limbo-standalone

Conversation

@ziggy6792

@ziggy6792 ziggy6792 commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Why this matters to you

This is the same symptom as #18 (fast reconnect retry): a sub-second tether or modem blip becomes a full SRT
session drop and many seconds of black at the receiver. This time the retry timing is not
the cause, so it happens even when the interface is back in under half a second. The link just
sits there carrying nothing for 15–20 s. Because it depends on timing, it looks intermittent:
"sometimes a tiny blip kills the stream".

The cause: while a link is in recovery, traffic arriving from the receiver makes it look alive
again. srtla_send therefore never re-registers it, even though it is not being used for data.

With this PR, a recovering link keeps going through rebind + REG2 until REG3 re-admits it. The
link is back within about 1–3 s of the interface returning. Nothing changes for connected links
or for initial registration.

Problem

Here is the sequence:

  1. A send fails (flush_connection → recover_connection), or a socket rebuild fails.
  2. mark_for_recovery clears connected and last_received. Housekeeping should then rebuild
    the socket and re-send REG2 until REG3.
  3. If the interface comes straight back, the receiver's SRT ACK/NAKs for that address arrive on
    the still-open socket.
  4. process_uplink_packet sets last_received = now for every non-registration packet, so the
    link no longer counts as timed out.
  5. Housekeeping stops rebuilding it and sends it keepalives instead. The replies keep refreshing
    the link, while connected == false keeps the scheduler off it.
  6. The limbo lasts until the receiver drops the link.

Change

In uplink_recv.rs, non-registration traffic refreshes last_received only when the link is
connected or has never been established. Initial registration keeps its existing handling.
REG3 still sets connected and last_received as before.

Tests

src/tests/recovery_limbo_tests.rs:

  • An established link that was put into recovery stays is_timed_out after receiving an SRT ACK,
    and after receiving a keepalive reply. Both of these fail without the change.
  • A connected link is still refreshed by traffic.

Field evidence

Same setup as #18. With #18 alone, 3 of 6 cuts still ended the session. On those cuts macOS
had the tether's link and address back at +0.38 s, but the next reconnect attempt on the tether
came at +18–23 s. With both #18 and this PR, all 30 cuts were hitless, and the tether went from link back to
connection established in 1.0–3.0 s.

Independent of #18: this branch is v4.0.1 plus this one commit and applies on its own.

A link that was established and is put into recovery (send failure,
failed socket rebuild) has `connected = false` until REG3 re-admits it,
and relies on `is_timed_out` to drive housekeeping's socket rebuild and
REG2. If the interface returns quickly, the receiver's SRT ACK/NAKs for
that address arrive on the still-open socket and refresh
`last_received`; housekeeping then treats the link as alive, sends it
keepalives whose replies keep refreshing it, and never re-registers it.
The link carries no data (not connected) until the receiver gives up on
it, which on a macOS USB tether replugged for 500 ms took 15-20 s — far
past the SRT peer-idle timeout.

Only refresh `last_received` on non-registration traffic for a link that
is connected or has never been established, so a recovering link stays
on the timeout-driven reconnect path until REG3.
@coderabbitai

coderabbitai Bot commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: irlserver/srtla_send/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 22027b06-2143-46ad-9d7c-05205a658091

📥 Commits

Reviewing files that changed from the base of the PR and between df0b393 and 334793f.

📒 Files selected for processing (3)
  • src/sender/uplink_recv.rs
  • src/tests/mod.rs
  • src/tests/recovery_limbo_tests.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@datagutt
datagutt merged commit 4802637 into irlserver:main Sep 24, 2026
@datagutt

Copy link
Copy Markdown
Member

Thanks! Will also look into your other commit, but it may take longer to review as it is more code to look at

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants