[dcsctp] Ignore nacks for already acked packets To avoid leaving 'OutstandingData' in inconsistent state when such specially crafted SACK packet arrives Bug: chromium:502356094 Change-Id: Ie0e5d89b5ba769f337f62637b6812d9a83305494 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/466940 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Victor Boivie <boivie@webrtc.org> Cr-Commit-Position: refs/heads/main@{#47567}
diff --git a/net/dcsctp/tx/outstanding_data.cc b/net/dcsctp/tx/outstanding_data.cc index b996dbd..e033e04 100644 --- a/net/dcsctp/tx/outstanding_data.cc +++ b/net/dcsctp/tx/outstanding_data.cc
@@ -276,6 +276,10 @@ bool retransmit_now, bool do_fast_retransmit) { Item& item = GetItem(tsn); + // Ignore NACKs for chunks that have already been acknowledged. + if (item.is_acked()) { + return false; + } bool was_outstanding = item.is_outstanding(); Item::NackAction action = item.Nack(retransmit_now);
diff --git a/net/dcsctp/tx/outstanding_data_test.cc b/net/dcsctp/tx/outstanding_data_test.cc index 7818d9b..658802e 100644 --- a/net/dcsctp/tx/outstanding_data_test.cc +++ b/net/dcsctp/tx/outstanding_data_test.cc
@@ -747,5 +747,30 @@ /*is_in_fast_recovery=*/false); } +TEST_F(OutstandingDataTest, HandlesSacksWithOutOfBoundsTsns) { + // Send chunks with TSNs 10, 11, 12, 13, 14, 15, 16 + for (int i = 0; i < 7; ++i) { + buf_.Insert(kMessageId, gen_.Ordered({1}, ""), kNow); + } + + // This NACKs TSN 11, 13, 15 (1st miss indication) + SackChunk::GapAckBlock sack1[] = {{2, 2}, // TSN 12 + {4, 4}, // TSN 14 + {6, 6}}; // TSN 16 + buf_.HandleSack(unwrapper_.Unwrap(TSN(10)), sack1, + /*is_in_fast_recovery=*/false); + EXPECT_EQ(buf_.unacked_items(), 3u); // 11, 13, 15 + + // The gap between block1-end (12) and block2-start (1011) causes + // NackBetweenAckBlocks to loop TSN 13..1010, but only TSN 13..16 are valid. + SackChunk::GapAckBlock sack2[] = {{1, 1}, // TSN 12 + {1000, 60000}}; // TSN 1011..60011 + + buf_.HandleSack(unwrapper_.Unwrap(TSN(11)), sack2, + /*is_in_fast_recovery=*/true); + // Packet 11 has been acknowledged. + EXPECT_EQ(buf_.unacked_items(), 2u); // 13, 15 +} + } // namespace } // namespace dcsctp