Fix Retransmission Timeout calculation according to RFC6298#34
Fix Retransmission Timeout calculation according to RFC6298#34danielinux wants to merge 3 commits intowolfSSL:masterfrom
Conversation
- Fixed bug in smooth average RTT calculation - Actually assign calculated RTO value (previously fixed to 1s) - Enforce min/max RTO according to RFC - Enforce Karn to only account for new ACK in RTO calculation
There was a problem hiding this comment.
Pull request overview
This PR implements RFC 6298-compliant retransmission timeout (RTO) calculation for TCP, fixing several bugs in the existing implementation.
Changes:
- Corrected the smooth RTT (SRTT) calculation formula to properly implement RFC 6298's exponential weighted moving average
- Enabled actual assignment of calculated RTO values (previously hardcoded to 1 second) with min/max clamping
- Implemented Karn's algorithm to exclude retransmitted segments from RTT measurements
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/wolfip.c | Implements RFC 6298 RTO calculation, adds control RTO timer for connection management states, fixes SRTT formula, enforces RTO bounds, and applies Karn's algorithm |
| src/test/unit/unit.c | Adds comprehensive test coverage for new RTO calculation logic and control state RTO behavior |
| README.md | Documents RFC 6298 and RFC 5681 compliance for RTO computation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| else | ||
| err_ms = sample_ms - srtt_ms; | ||
| t->sock.tcp.rttvar = (3U * t->sock.tcp.rttvar + (err_ms << 2)) >> 2; | ||
| t->sock.tcp.srtt = (7U * t->sock.tcp.srtt + (sample_ms << 3)) >> 3; |
There was a problem hiding this comment.
The SRTT update formula does not match RFC 6298. According to RFC 6298 section 2.3, SRTT should be updated as SRTT = (7/8) * SRTT + (1/8) * R'. The current implementation shifts the sample by 3 (<< 3), but SRTT is already scaled by 8. This double-scales the new sample. The correct formula should be t->sock.tcp.srtt = (7U * t->sock.tcp.srtt + sample_ms) >> 3; to properly compute the weighted average.
| t->sock.tcp.srtt = (7U * t->sock.tcp.srtt + (sample_ms << 3)) >> 3; | |
| t->sock.tcp.srtt = (7U * t->sock.tcp.srtt + sample_ms) >> 3; |
| err_ms = srtt_ms - sample_ms; | ||
| else | ||
| err_ms = sample_ms - srtt_ms; | ||
| t->sock.tcp.rttvar = (3U * t->sock.tcp.rttvar + (err_ms << 2)) >> 2; |
There was a problem hiding this comment.
The RTTVAR update does not follow RFC 6298. According to RFC 6298 section 2.3, RTTVAR should be updated as RTTVAR = (3/4) * RTTVAR + (1/4) * |SRTT - R'|. Here RTTVAR is scaled by 4, and err_ms is the absolute difference. However, the formula shifts err_ms by 2 (<< 2), which scales it by 4 instead of just adding it. The correct formula should be t->sock.tcp.rttvar = (3U * t->sock.tcp.rttvar + err_ms) >> 2;.
| t->sock.tcp.rttvar = (3U * t->sock.tcp.rttvar + (err_ms << 2)) >> 2; | |
| t->sock.tcp.rttvar = (3U * t->sock.tcp.rttvar + err_ms) >> 2; |
Fixed RTO calculation according to RFC6298
Depends on merging #33 first.