What happened?
RFC9002: Appendix B.5 OnPacketAcked, InCongestionRecovery
RFC的 InCongestionRecovery 函数仅检查 sent_time <= congestion_recovery_start_time,从不修改 congestion_recovery_start_time。xquic Reno在确认recovery后发送的包时错误地清除了 reno_recovery_start_time = 0:
if (sent_time > reno->reno_recovery_start_time) {
reno->reno_recovery_start_time = 0; // 错误清除
}
影响: 如果recovery后发送的包先于recovery期间发送的包被确认,recovery_start_time被清除为0。之后recovery期间发送的包被确认时,sent_time <= 0 为false,cwnd会被错误增加。这违反了RFC “During a recovery period, the congestion window does not change” 的要求。
复现场景:
T1: 丢包事件,recovery_start_time = T1
T0 (< T1): 包P1在recovery期间发送
T2 (> T1): 包P2在recovery后发送
P2先被确认 → recovery_start_time = 0
P1后被确认 → sent_time(T0) <= 0 为false → cwnd被错误增加
xquic代码位置: xqc_reno_on_ack() (xqc_new_reno.c:78-80)
ngtcp2参考: ngtcp2不在OnPacketAcked中清除recovery_start_time,recovery状态由CC算法内部管理,InCongestionRecovery 仅做比较不做修改
Steps To Reproduce
Information and Steps to reproduce the behavior.
Relevant log output
What happened?
RFC9002: Appendix B.5 OnPacketAcked, InCongestionRecovery
RFC的 InCongestionRecovery 函数仅检查 sent_time <= congestion_recovery_start_time,从不修改 congestion_recovery_start_time。xquic Reno在确认recovery后发送的包时错误地清除了 reno_recovery_start_time = 0:
if (sent_time > reno->reno_recovery_start_time) {
reno->reno_recovery_start_time = 0; // 错误清除
}
影响: 如果recovery后发送的包先于recovery期间发送的包被确认,recovery_start_time被清除为0。之后recovery期间发送的包被确认时,sent_time <= 0 为false,cwnd会被错误增加。这违反了RFC “During a recovery period, the congestion window does not change” 的要求。
复现场景:
T1: 丢包事件,recovery_start_time = T1
T0 (< T1): 包P1在recovery期间发送
T2 (> T1): 包P2在recovery后发送
P2先被确认 → recovery_start_time = 0
P1后被确认 → sent_time(T0) <= 0 为false → cwnd被错误增加
xquic代码位置: xqc_reno_on_ack() (xqc_new_reno.c:78-80)
ngtcp2参考: ngtcp2不在OnPacketAcked中清除recovery_start_time,recovery状态由CC算法内部管理,InCongestionRecovery 仅做比较不做修改
Steps To Reproduce
Information and Steps to reproduce the behavior.
Relevant log output