webrtc_m130/net/dcsctp/tx/send_queue.h
Victor Boivie a2476e3783 dcsctp: Enable message interleaving
This adds support to enable message interleaving in the stream scheduler
from the socket, proxied by the send queue.

It also adds socket unit tests to ensure that prioritization and
interleaving works. Also, send queue test has been added to validate the
integration of the stream scheduler. But the actual scheduling parts of
it will be tested in the stream scheduler unit tests.

Bug: webrtc:5696
Change-Id: Ic7d3d2dc28405c77a107f0148f0096882961eec7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262248
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37355}
2022-06-28 12:05:23 +00:00

139 lines
6.1 KiB
C++

/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_TX_SEND_QUEUE_H_
#define NET_DCSCTP_TX_SEND_QUEUE_H_
#include <cstdint>
#include <limits>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/data.h"
#include "net/dcsctp/public/types.h"
namespace dcsctp {
class SendQueue {
public:
// Container for a data chunk that is produced by the SendQueue
struct DataToSend {
explicit DataToSend(Data data) : data(std::move(data)) {}
// The data to send, including all parameters.
Data data;
// Partial reliability - RFC3758
MaxRetransmits max_retransmissions = MaxRetransmits::NoLimit();
TimeMs expires_at = TimeMs::InfiniteFuture();
};
virtual ~SendQueue() = default;
// TODO(boivie): This interface is obviously missing an "Add" function, but
// that is postponed a bit until the story around how to model message
// prioritization, which is important for any advanced stream scheduler, is
// further clarified.
// Produce a chunk to be sent.
//
// `max_size` refers to how many payload bytes that may be produced, not
// including any headers.
virtual absl::optional<DataToSend> Produce(TimeMs now, size_t max_size) = 0;
// Discards a partially sent message identified by the parameters `unordered`,
// `stream_id` and `message_id`. The `message_id` comes from the returned
// information when having called `Produce`. A partially sent message means
// that it has had at least one fragment of it returned when `Produce` was
// called prior to calling this method).
//
// This is used when a message has been found to be expired (by the partial
// reliability extension), and the retransmission queue will signal the
// receiver that any partially received message fragments should be skipped.
// This means that any remaining fragments in the Send Queue must be removed
// as well so that they are not sent.
//
// This function returns true if this message had unsent fragments still in
// the queue that were discarded, and false if there were no such fragments.
virtual bool Discard(IsUnordered unordered,
StreamID stream_id,
MID message_id) = 0;
// Prepares the stream to be reset. This is used to close a WebRTC data
// channel and will be signaled to the other side.
//
// Concretely, it discards all whole (not partly sent) messages in the given
// stream and pauses that stream so that future added messages aren't
// produced until `ResumeStreams` is called.
//
// TODO(boivie): Investigate if it really should discard any message at all.
// RFC8831 only mentions that "[RFC6525] also guarantees that all the messages
// are delivered (or abandoned) before the stream is reset."
//
// This method can be called multiple times to add more streams to be
// reset, and paused while they are resetting. This is the first part of the
// two-phase commit protocol to reset streams, where the caller completes the
// procedure by either calling `CommitResetStreams` or `RollbackResetStreams`.
virtual void PrepareResetStream(StreamID stream_id) = 0;
// Indicates if there are any streams that are ready to be reset.
virtual bool HasStreamsReadyToBeReset() const = 0;
// Returns a list of streams that are ready to be included in an outgoing
// stream reset request. Any streams that are returned here must be included
// in an outgoing stream reset request, and there must not be concurrent
// requests. Before calling this method again, you must have called
virtual std::vector<StreamID> GetStreamsReadyToBeReset() = 0;
// Called to commit to reset the streams returned by
// `GetStreamsReadyToBeReset`. It will reset the stream sequence numbers
// (SSNs) and message identifiers (MIDs) and resume the paused streams.
virtual void CommitResetStreams() = 0;
// Called to abort the resetting of streams returned by
// `GetStreamsReadyToBeReset`. Will resume the paused streams without
// resetting the stream sequence numbers (SSNs) or message identifiers (MIDs).
// Note that the non-partial messages that were discarded when calling
// `PrepareResetStreams` will not be recovered, to better match the intention
// from the sender to "close the channel".
virtual void RollbackResetStreams() = 0;
// Resets all message identifier counters (MID, SSN) and makes all partially
// messages be ready to be re-sent in full. This is used when the peer has
// been detected to have restarted and is used to try to minimize the amount
// of data loss. However, data loss cannot be completely guaranteed when a
// peer restarts.
virtual void Reset() = 0;
// Returns the amount of buffered data. This doesn't include packets that are
// e.g. inflight.
virtual size_t buffered_amount(StreamID stream_id) const = 0;
// Returns the total amount of buffer data, for all streams.
virtual size_t total_buffered_amount() const = 0;
// Returns the limit for the `OnBufferedAmountLow` event. Default value is 0.
virtual size_t buffered_amount_low_threshold(StreamID stream_id) const = 0;
// Sets a limit for the `OnBufferedAmountLow` event.
virtual void SetBufferedAmountLowThreshold(StreamID stream_id,
size_t bytes) = 0;
// Configures the send queue to support interleaved message sending as
// described in RFC8260. Every send queue starts with this value set as
// disabled, but can later change it when the capabilities of the connection
// have been negotiated. This affects the behavior of the `Produce` method.
virtual void EnableMessageInterleaving(bool enabled) = 0;
};
} // namespace dcsctp
#endif // NET_DCSCTP_TX_SEND_QUEUE_H_