summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h')
-rw-r--r--third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h67
1 files changed, 38 insertions, 29 deletions
diff --git a/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h b/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h
index f8e939661d..2a214975e6 100644
--- a/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h
+++ b/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h
@@ -10,12 +10,14 @@
#ifndef NET_DCSCTP_TX_OUTSTANDING_DATA_H_
#define NET_DCSCTP_TX_OUTSTANDING_DATA_H_
+#include <deque>
#include <map>
#include <set>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
+#include "api/units/timestamp.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/common/sequence_numbers.h"
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
@@ -29,6 +31,9 @@ namespace dcsctp {
// This class keeps track of outstanding data chunks (sent, not yet acked) and
// handles acking, nacking, rescheduling and abandoning.
+//
+// Items are added to this queue as they are sent and will be removed when the
+// peer acks them using the cumulative TSN ack.
class OutstandingData {
public:
// State for DATA chunks (message fragments) in the queue - used in tests.
@@ -74,11 +79,9 @@ class OutstandingData {
OutstandingData(
size_t data_chunk_header_size,
- UnwrappedTSN next_tsn,
UnwrappedTSN last_cumulative_tsn_ack,
std::function<bool(StreamID, OutgoingMessageId)> discard_from_send_queue)
: data_chunk_header_size_(data_chunk_header_size),
- next_tsn_(next_tsn),
last_cumulative_tsn_ack_(last_cumulative_tsn_ack),
discard_from_send_queue_(std::move(discard_from_send_queue)) {}
@@ -98,14 +101,14 @@ class OutstandingData {
// it?
std::vector<std::pair<TSN, Data>> GetChunksToBeRetransmitted(size_t max_size);
- size_t outstanding_bytes() const { return outstanding_bytes_; }
+ size_t unacked_bytes() const { return unacked_bytes_; }
- // Returns the number of DATA chunks that are in-flight.
- size_t outstanding_items() const { return outstanding_items_; }
+ // Returns the number of DATA chunks that are in-flight (not acked or nacked).
+ size_t unacked_items() const { return unacked_items_; }
// Given the current time `now_ms`, expire and abandon outstanding (sent at
// least once) chunks that have a limited lifetime.
- void ExpireOutstandingChunks(TimeMs now);
+ void ExpireOutstandingChunks(webrtc::Timestamp now);
bool empty() const { return outstanding_data_.empty(); }
@@ -121,7 +124,9 @@ class OutstandingData {
return last_cumulative_tsn_ack_;
}
- UnwrappedTSN next_tsn() const { return next_tsn_; }
+ UnwrappedTSN next_tsn() const {
+ return highest_outstanding_tsn().next_value();
+ }
UnwrappedTSN highest_outstanding_tsn() const;
@@ -131,9 +136,9 @@ class OutstandingData {
absl::optional<UnwrappedTSN> Insert(
OutgoingMessageId message_id,
const Data& data,
- TimeMs time_sent,
+ webrtc::Timestamp time_sent,
MaxRetransmits max_retransmissions = MaxRetransmits::NoLimit(),
- TimeMs expires_at = TimeMs::InfiniteFuture(),
+ webrtc::Timestamp expires_at = webrtc::Timestamp::PlusInfinity(),
LifecycleId lifecycle_id = LifecycleId::NotSet());
// Nacks all outstanding data.
@@ -147,8 +152,8 @@ class OutstandingData {
// Given the current time and a TSN, it returns the measured RTT between when
// the chunk was sent and now. It takes into acccount Karn's algorithm, so if
- // the chunk has ever been retransmitted, it will return absl::nullopt.
- absl::optional<DurationMs> MeasureRTT(TimeMs now, UnwrappedTSN tsn) const;
+ // the chunk has ever been retransmitted, it will return `PlusInfinity()`.
+ webrtc::TimeDelta MeasureRTT(webrtc::Timestamp now, UnwrappedTSN tsn) const;
// Returns the internal state of all queued chunks. This is only used in
// unit-tests.
@@ -159,8 +164,7 @@ class OutstandingData {
bool ShouldSendForwardTsn() const;
// Sets the next TSN to be used. This is used in handover.
- void ResetSequenceNumbers(UnwrappedTSN next_tsn,
- UnwrappedTSN last_cumulative_tsn);
+ void ResetSequenceNumbers(UnwrappedTSN last_cumulative_tsn);
// Called when an outgoing stream reset is sent, marking the last assigned TSN
// as a breakpoint that a FORWARD-TSN shouldn't cross.
@@ -179,9 +183,9 @@ class OutstandingData {
Item(OutgoingMessageId message_id,
Data data,
- TimeMs time_sent,
+ webrtc::Timestamp time_sent,
MaxRetransmits max_retransmissions,
- TimeMs expires_at,
+ webrtc::Timestamp expires_at,
LifecycleId lifecycle_id)
: message_id_(message_id),
time_sent_(time_sent),
@@ -195,7 +199,7 @@ class OutstandingData {
OutgoingMessageId message_id() const { return message_id_; }
- TimeMs time_sent() const { return time_sent_; }
+ webrtc::Timestamp time_sent() const { return time_sent_; }
const Data& data() const { return data_; }
@@ -229,7 +233,7 @@ class OutstandingData {
// Given the current time, and the current state of this DATA chunk, it will
// indicate if it has expired (SCTP Partial Reliability Extension).
- bool has_expired(TimeMs now) const;
+ bool has_expired(webrtc::Timestamp now) const;
LifecycleId lifecycle_id() const { return lifecycle_id_; }
@@ -258,7 +262,7 @@ class OutstandingData {
const OutgoingMessageId message_id_;
// When the packet was sent, and placed in this queue.
- const TimeMs time_sent_;
+ const webrtc::Timestamp time_sent_;
// If the message was sent with a maximum number of retransmissions, this is
// set to that number. The value zero (0) means that it will never be
// retransmitted.
@@ -278,7 +282,7 @@ class OutstandingData {
// At this exact millisecond, the item is considered expired. If the message
// is not to be expired, this is set to the infinite future.
- const TimeMs expires_at_;
+ const webrtc::Timestamp expires_at_;
// An optional lifecycle id, which may only be set for the last fragment.
const LifecycleId lifecycle_id_;
@@ -290,6 +294,9 @@ class OutstandingData {
// Returns how large a chunk will be, serialized, carrying the data
size_t GetSerializedChunkSize(const Data& data) const;
+ Item& GetItem(UnwrappedTSN tsn);
+ const Item& GetItem(UnwrappedTSN tsn) const;
+
// Given a `cumulative_tsn_ack` from an incoming SACK, will remove those items
// in the retransmission queue up until this value and will update `ack_info`
// by setting `bytes_acked_by_cumulative_tsn_ack`.
@@ -313,7 +320,7 @@ class OutstandingData {
// Process the acknowledgement of the chunk referenced by `iter` and updates
// state in `ack_info` and the object's state.
- void AckChunk(AckInfo& ack_info, std::map<UnwrappedTSN, Item>::iterator iter);
+ void AckChunk(AckInfo& ack_info, UnwrappedTSN tsn, Item& item);
// Helper method to process an incoming nack of an item and perform the
// correct operations given the action indicated when nacking an item (e.g.
@@ -323,10 +330,11 @@ class OutstandingData {
// many times so that it should be retransmitted, this will schedule it to be
// "fast retransmitted". This is only done just before going into fast
// recovery.
- bool NackItem(UnwrappedTSN tsn,
- Item& item,
- bool retransmit_now,
- bool do_fast_retransmit);
+ //
+ // Note that since nacking an item may result in it becoming abandoned, which
+ // in turn could alter `outstanding_data_`, any iterators are invalidated
+ // after having called this method.
+ bool NackItem(UnwrappedTSN tsn, bool retransmit_now, bool do_fast_retransmit);
// Given that a message fragment, `item` has been abandoned, abandon all other
// fragments that share the same message - both never-before-sent fragments
@@ -341,19 +349,20 @@ class OutstandingData {
// The size of the data chunk (DATA/I-DATA) header that is used.
const size_t data_chunk_header_size_;
- // Next TSN to used.
- UnwrappedTSN next_tsn_;
// The last cumulative TSN ack number.
UnwrappedTSN last_cumulative_tsn_ack_;
// Callback when to discard items from the send queue.
std::function<bool(StreamID, OutgoingMessageId)> discard_from_send_queue_;
- std::map<UnwrappedTSN, Item> outstanding_data_;
+ // Outstanding items. If non-empty, the first element has
+ // `TSN=last_cumulative_tsn_ack_ + 1` and the following items are in strict
+ // increasing TSN order. The last item has `TSN=highest_outstanding_tsn()`.
+ std::deque<Item> outstanding_data_;
// The number of bytes that are in-flight (sent but not yet acked or nacked).
- size_t outstanding_bytes_ = 0;
+ size_t unacked_bytes_ = 0;
// The number of DATA chunks that are in-flight (sent but not yet acked or
// nacked).
- size_t outstanding_items_ = 0;
+ size_t unacked_items_ = 0;
// Data chunks that are eligible for fast retransmission.
std::set<UnwrappedTSN> to_be_fast_retransmitted_;
// Data chunks that are to be retransmitted.