diff options
Diffstat (limited to 'net/dcsctp/rx/data_tracker.h')
-rw-r--r-- | net/dcsctp/rx/data_tracker.h | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/net/dcsctp/rx/data_tracker.h b/net/dcsctp/rx/data_tracker.h index 6146d2a839..167f5a04e7 100644 --- a/net/dcsctp/rx/data_tracker.h +++ b/net/dcsctp/rx/data_tracker.h @@ -16,6 +16,7 @@ #include <cstdint> #include <set> #include <string> +#include <utility> #include <vector> #include "absl/strings/string_view.h" @@ -38,12 +39,17 @@ namespace dcsctp { // 200ms, whatever is smallest). class DataTracker { public: + // The maximum number of duplicate TSNs that will be reported in a SACK. + static constexpr size_t kMaxDuplicateTsnReported = 20; + // The maximum number of gap-ack-blocks that will be reported in a SACK. + static constexpr size_t kMaxGapAckBlocksReported = 20; + // The maximum number of accepted in-flight DATA chunks. This indicates the // maximum difference from this buffer's last cumulative ack TSN, and any // received data. Data received beyond this limit will be dropped, which will // force the transmitter to send data that actually increases the last // cumulative acked TSN. - static constexpr uint32_t kMaxAcceptedOutstandingFragments = 256; + static constexpr uint32_t kMaxAcceptedOutstandingFragments = 100000; explicit DataTracker(absl::string_view log_prefix, Timer* delayed_ack_timer, @@ -111,6 +117,49 @@ class DataTracker { // Send a SACK immediately after handling this packet. kImmediate, }; + + // Represents ranges of TSNs that have been received that are not directly + // following the last cumulative acked TSN. This information is returned to + // the sender in the "gap ack blocks" in the SACK chunk. The blocks are always + // non-overlapping and non-adjacent. + class AdditionalTsnBlocks { + public: + // Represents an inclusive range of received TSNs, i.e. [first, last]. + struct TsnRange { + TsnRange(UnwrappedTSN first, UnwrappedTSN last) + : first(first), last(last) {} + UnwrappedTSN first; + UnwrappedTSN last; + }; + + // Adds a TSN to the set. This will try to expand any existing block and + // might merge blocks to ensure that all blocks are non-adjacent. If a + // current block can't be expanded, a new block is created. + // + // The return value indicates if `tsn` was added. If false is returned, the + // `tsn` was already represented in one of the blocks. + bool Add(UnwrappedTSN tsn); + + // Erases all TSNs up to, and including `tsn`. This will remove all blocks + // that are completely below `tsn` and may truncate a block where `tsn` is + // within that block. In that case, the frontmost block's start TSN will be + // the next following tsn after `tsn`. + void EraseTo(UnwrappedTSN tsn); + + // Removes the first block. Must not be called on an empty set. + void PopFront(); + + const std::vector<TsnRange>& blocks() const { return blocks_; } + + bool empty() const { return blocks_.empty(); } + + const TsnRange& front() const { return blocks_.front(); } + + private: + // A sorted vector of non-overlapping and non-adjacent blocks. + std::vector<TsnRange> blocks_; + }; + std::vector<SackChunk::GapAckBlock> CreateGapAckBlocks() const; void UpdateAckState(AckState new_state, absl::string_view reason); static absl::string_view ToString(AckState ack_state); @@ -125,8 +174,8 @@ class DataTracker { // All TSNs up until (and including) this value have been seen. UnwrappedTSN last_cumulative_acked_tsn_; // Received TSNs that are not directly following `last_cumulative_acked_tsn_`. - std::set<UnwrappedTSN> additional_tsns_; - std::set<UnwrappedTSN> duplicates_; + AdditionalTsnBlocks additional_tsn_blocks_; + std::set<TSN> duplicate_tsns_; }; } // namespace dcsctp |