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