1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker #ifndef NET_DCSCTP_TX_SEND_QUEUE_H_ 11*d9f75844SAndroid Build Coastguard Worker #define NET_DCSCTP_TX_SEND_QUEUE_H_ 12*d9f75844SAndroid Build Coastguard Worker 13*d9f75844SAndroid Build Coastguard Worker #include <cstdint> 14*d9f75844SAndroid Build Coastguard Worker #include <limits> 15*d9f75844SAndroid Build Coastguard Worker #include <utility> 16*d9f75844SAndroid Build Coastguard Worker #include <vector> 17*d9f75844SAndroid Build Coastguard Worker 18*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 19*d9f75844SAndroid Build Coastguard Worker #include "api/array_view.h" 20*d9f75844SAndroid Build Coastguard Worker #include "net/dcsctp/common/internal_types.h" 21*d9f75844SAndroid Build Coastguard Worker #include "net/dcsctp/packet/data.h" 22*d9f75844SAndroid Build Coastguard Worker #include "net/dcsctp/public/types.h" 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Worker namespace dcsctp { 25*d9f75844SAndroid Build Coastguard Worker 26*d9f75844SAndroid Build Coastguard Worker class SendQueue { 27*d9f75844SAndroid Build Coastguard Worker public: 28*d9f75844SAndroid Build Coastguard Worker // Container for a data chunk that is produced by the SendQueue 29*d9f75844SAndroid Build Coastguard Worker struct DataToSend { DataToSendDataToSend30*d9f75844SAndroid Build Coastguard Worker explicit DataToSend(Data data) : data(std::move(data)) {} 31*d9f75844SAndroid Build Coastguard Worker // The data to send, including all parameters. 32*d9f75844SAndroid Build Coastguard Worker Data data; 33*d9f75844SAndroid Build Coastguard Worker 34*d9f75844SAndroid Build Coastguard Worker // Partial reliability - RFC3758 35*d9f75844SAndroid Build Coastguard Worker MaxRetransmits max_retransmissions = MaxRetransmits::NoLimit(); 36*d9f75844SAndroid Build Coastguard Worker TimeMs expires_at = TimeMs::InfiniteFuture(); 37*d9f75844SAndroid Build Coastguard Worker 38*d9f75844SAndroid Build Coastguard Worker // Lifecycle - set for the last fragment, and `LifecycleId::NotSet()` for 39*d9f75844SAndroid Build Coastguard Worker // all other fragments. 40*d9f75844SAndroid Build Coastguard Worker LifecycleId lifecycle_id = LifecycleId::NotSet(); 41*d9f75844SAndroid Build Coastguard Worker }; 42*d9f75844SAndroid Build Coastguard Worker 43*d9f75844SAndroid Build Coastguard Worker virtual ~SendQueue() = default; 44*d9f75844SAndroid Build Coastguard Worker 45*d9f75844SAndroid Build Coastguard Worker // TODO(boivie): This interface is obviously missing an "Add" function, but 46*d9f75844SAndroid Build Coastguard Worker // that is postponed a bit until the story around how to model message 47*d9f75844SAndroid Build Coastguard Worker // prioritization, which is important for any advanced stream scheduler, is 48*d9f75844SAndroid Build Coastguard Worker // further clarified. 49*d9f75844SAndroid Build Coastguard Worker 50*d9f75844SAndroid Build Coastguard Worker // Produce a chunk to be sent. 51*d9f75844SAndroid Build Coastguard Worker // 52*d9f75844SAndroid Build Coastguard Worker // `max_size` refers to how many payload bytes that may be produced, not 53*d9f75844SAndroid Build Coastguard Worker // including any headers. 54*d9f75844SAndroid Build Coastguard Worker virtual absl::optional<DataToSend> Produce(TimeMs now, size_t max_size) = 0; 55*d9f75844SAndroid Build Coastguard Worker 56*d9f75844SAndroid Build Coastguard Worker // Discards a partially sent message identified by the parameters `unordered`, 57*d9f75844SAndroid Build Coastguard Worker // `stream_id` and `message_id`. The `message_id` comes from the returned 58*d9f75844SAndroid Build Coastguard Worker // information when having called `Produce`. A partially sent message means 59*d9f75844SAndroid Build Coastguard Worker // that it has had at least one fragment of it returned when `Produce` was 60*d9f75844SAndroid Build Coastguard Worker // called prior to calling this method). 61*d9f75844SAndroid Build Coastguard Worker // 62*d9f75844SAndroid Build Coastguard Worker // This is used when a message has been found to be expired (by the partial 63*d9f75844SAndroid Build Coastguard Worker // reliability extension), and the retransmission queue will signal the 64*d9f75844SAndroid Build Coastguard Worker // receiver that any partially received message fragments should be skipped. 65*d9f75844SAndroid Build Coastguard Worker // This means that any remaining fragments in the Send Queue must be removed 66*d9f75844SAndroid Build Coastguard Worker // as well so that they are not sent. 67*d9f75844SAndroid Build Coastguard Worker // 68*d9f75844SAndroid Build Coastguard Worker // This function returns true if this message had unsent fragments still in 69*d9f75844SAndroid Build Coastguard Worker // the queue that were discarded, and false if there were no such fragments. 70*d9f75844SAndroid Build Coastguard Worker virtual bool Discard(IsUnordered unordered, 71*d9f75844SAndroid Build Coastguard Worker StreamID stream_id, 72*d9f75844SAndroid Build Coastguard Worker MID message_id) = 0; 73*d9f75844SAndroid Build Coastguard Worker 74*d9f75844SAndroid Build Coastguard Worker // Prepares the stream to be reset. This is used to close a WebRTC data 75*d9f75844SAndroid Build Coastguard Worker // channel and will be signaled to the other side. 76*d9f75844SAndroid Build Coastguard Worker // 77*d9f75844SAndroid Build Coastguard Worker // Concretely, it discards all whole (not partly sent) messages in the given 78*d9f75844SAndroid Build Coastguard Worker // stream and pauses that stream so that future added messages aren't 79*d9f75844SAndroid Build Coastguard Worker // produced until `ResumeStreams` is called. 80*d9f75844SAndroid Build Coastguard Worker // 81*d9f75844SAndroid Build Coastguard Worker // TODO(boivie): Investigate if it really should discard any message at all. 82*d9f75844SAndroid Build Coastguard Worker // RFC8831 only mentions that "[RFC6525] also guarantees that all the messages 83*d9f75844SAndroid Build Coastguard Worker // are delivered (or abandoned) before the stream is reset." 84*d9f75844SAndroid Build Coastguard Worker // 85*d9f75844SAndroid Build Coastguard Worker // This method can be called multiple times to add more streams to be 86*d9f75844SAndroid Build Coastguard Worker // reset, and paused while they are resetting. This is the first part of the 87*d9f75844SAndroid Build Coastguard Worker // two-phase commit protocol to reset streams, where the caller completes the 88*d9f75844SAndroid Build Coastguard Worker // procedure by either calling `CommitResetStreams` or `RollbackResetStreams`. 89*d9f75844SAndroid Build Coastguard Worker virtual void PrepareResetStream(StreamID stream_id) = 0; 90*d9f75844SAndroid Build Coastguard Worker 91*d9f75844SAndroid Build Coastguard Worker // Indicates if there are any streams that are ready to be reset. 92*d9f75844SAndroid Build Coastguard Worker virtual bool HasStreamsReadyToBeReset() const = 0; 93*d9f75844SAndroid Build Coastguard Worker 94*d9f75844SAndroid Build Coastguard Worker // Returns a list of streams that are ready to be included in an outgoing 95*d9f75844SAndroid Build Coastguard Worker // stream reset request. Any streams that are returned here must be included 96*d9f75844SAndroid Build Coastguard Worker // in an outgoing stream reset request, and there must not be concurrent 97*d9f75844SAndroid Build Coastguard Worker // requests. Before calling this method again, you must have called 98*d9f75844SAndroid Build Coastguard Worker virtual std::vector<StreamID> GetStreamsReadyToBeReset() = 0; 99*d9f75844SAndroid Build Coastguard Worker 100*d9f75844SAndroid Build Coastguard Worker // Called to commit to reset the streams returned by 101*d9f75844SAndroid Build Coastguard Worker // `GetStreamsReadyToBeReset`. It will reset the stream sequence numbers 102*d9f75844SAndroid Build Coastguard Worker // (SSNs) and message identifiers (MIDs) and resume the paused streams. 103*d9f75844SAndroid Build Coastguard Worker virtual void CommitResetStreams() = 0; 104*d9f75844SAndroid Build Coastguard Worker 105*d9f75844SAndroid Build Coastguard Worker // Called to abort the resetting of streams returned by 106*d9f75844SAndroid Build Coastguard Worker // `GetStreamsReadyToBeReset`. Will resume the paused streams without 107*d9f75844SAndroid Build Coastguard Worker // resetting the stream sequence numbers (SSNs) or message identifiers (MIDs). 108*d9f75844SAndroid Build Coastguard Worker // Note that the non-partial messages that were discarded when calling 109*d9f75844SAndroid Build Coastguard Worker // `PrepareResetStreams` will not be recovered, to better match the intention 110*d9f75844SAndroid Build Coastguard Worker // from the sender to "close the channel". 111*d9f75844SAndroid Build Coastguard Worker virtual void RollbackResetStreams() = 0; 112*d9f75844SAndroid Build Coastguard Worker 113*d9f75844SAndroid Build Coastguard Worker // Resets all message identifier counters (MID, SSN) and makes all partially 114*d9f75844SAndroid Build Coastguard Worker // messages be ready to be re-sent in full. This is used when the peer has 115*d9f75844SAndroid Build Coastguard Worker // been detected to have restarted and is used to try to minimize the amount 116*d9f75844SAndroid Build Coastguard Worker // of data loss. However, data loss cannot be completely guaranteed when a 117*d9f75844SAndroid Build Coastguard Worker // peer restarts. 118*d9f75844SAndroid Build Coastguard Worker virtual void Reset() = 0; 119*d9f75844SAndroid Build Coastguard Worker 120*d9f75844SAndroid Build Coastguard Worker // Returns the amount of buffered data. This doesn't include packets that are 121*d9f75844SAndroid Build Coastguard Worker // e.g. inflight. 122*d9f75844SAndroid Build Coastguard Worker virtual size_t buffered_amount(StreamID stream_id) const = 0; 123*d9f75844SAndroid Build Coastguard Worker 124*d9f75844SAndroid Build Coastguard Worker // Returns the total amount of buffer data, for all streams. 125*d9f75844SAndroid Build Coastguard Worker virtual size_t total_buffered_amount() const = 0; 126*d9f75844SAndroid Build Coastguard Worker 127*d9f75844SAndroid Build Coastguard Worker // Returns the limit for the `OnBufferedAmountLow` event. Default value is 0. 128*d9f75844SAndroid Build Coastguard Worker virtual size_t buffered_amount_low_threshold(StreamID stream_id) const = 0; 129*d9f75844SAndroid Build Coastguard Worker 130*d9f75844SAndroid Build Coastguard Worker // Sets a limit for the `OnBufferedAmountLow` event. 131*d9f75844SAndroid Build Coastguard Worker virtual void SetBufferedAmountLowThreshold(StreamID stream_id, 132*d9f75844SAndroid Build Coastguard Worker size_t bytes) = 0; 133*d9f75844SAndroid Build Coastguard Worker 134*d9f75844SAndroid Build Coastguard Worker // Configures the send queue to support interleaved message sending as 135*d9f75844SAndroid Build Coastguard Worker // described in RFC8260. Every send queue starts with this value set as 136*d9f75844SAndroid Build Coastguard Worker // disabled, but can later change it when the capabilities of the connection 137*d9f75844SAndroid Build Coastguard Worker // have been negotiated. This affects the behavior of the `Produce` method. 138*d9f75844SAndroid Build Coastguard Worker virtual void EnableMessageInterleaving(bool enabled) = 0; 139*d9f75844SAndroid Build Coastguard Worker }; 140*d9f75844SAndroid Build Coastguard Worker } // namespace dcsctp 141*d9f75844SAndroid Build Coastguard Worker 142*d9f75844SAndroid Build Coastguard Worker #endif // NET_DCSCTP_TX_SEND_QUEUE_H_ 143