Fix spurious SACKs by respecting delayed ACK timer#94
Merged
boivie merged 1 commit intowebrtc:mainfrom Feb 16, 2026
Merged
Conversation
DanilChapovalov
requested changes
Feb 16, 2026
cd8f7f6 to
461ee30
Compare
SCTP employs a "Delayed Acknowledgement" algorithm (RFC 9260, section 6.2) to reduce network traffic. Instead of immediately acknowledging every received DATA chunk, the protocol allows the receiver to delay sending a Selective Acknowledgement (SACK) for up to 200ms (or until a second packet arrives). This allows the SACK to be "piggybacked" onto outgoing user data or bundled with other control chunks, reducing the number of small packets sent. Before this change, the `Socket::advance_time` method broke this by unconditionally flushing pending packets. Whenever `advance_time` was called (which the application is allowed to do at any time), it would trigger packet transmission logic that forced any pending SACK to be sent immediately. This broke the delayed SACK optimization, resulting in spurious, standalone SACK transmissions whenever the socket clock advanced (when there was a pending and delayed SACK). This commit fixes the issue by ensuring `advance_time` only attempts to send packets if a timer (such as the delayed ACK timer) has actually expired. And it also modifies the packet builder to only include a pending SACK if it can be bundled with outgoing data/retransmissions, or if the delayed ACK timer has explicitly expired.
461ee30 to
27ad433
Compare
DanilChapovalov
approved these changes
Feb 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SCTP employs a "Delayed Acknowledgement" algorithm (RFC 9260, section 6.2) to reduce network traffic. Instead of immediately acknowledging every received DATA chunk, the protocol allows the receiver to delay sending a Selective Acknowledgement (SACK) for up to 200ms (or until a second packet arrives). This allows the SACK to be "piggybacked" onto outgoing user data or bundled with other control chunks, reducing the number of small packets sent.
Before this change, the
Socket::advance_timemethod broke this by unconditionally flushing pending packets. Wheneveradvance_timewas called (which the application is allowed to do at any time), it would trigger packet transmission logic that forced any pending SACK to be sent immediately. This broke the delayed SACK optimization, resulting in spurious, standalone SACK transmissions whenever the socket clock advanced (when there was a pending and delayed SACK).This commit fixes the issue by ensuring
advance_timeonly attempts to send packets if a timer (such as the delayed ACK timer) has actually expired. And it also modifies the packet builder to only include a pending SACK if it can be bundled with outgoing data/retransmissions, or if the delayed ACK timer has explicitly expired.