mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 06:10:40 +01:00

The Retransmission Queue contain all message fragments (DATA chunks) that have once been sent, but not yet ACKed by the receiver. It will process incoming SACK chunks, which informs it which chunks that the receiver has seen (ACKed) and which that are lost (NACKed), and will retransmit chunks when it's time. If a message has been sent with partial reliability, e.g. to have a limited number of retransmissions or a limited lifetime, the Retransmission Queue may discard a partially sent and expired message and will instruct the receiver that "don't expect this message - it's expired" by sending a FORWARD-TSN chunk. This currently also includes the congestion control algorithm as it's tightly coupled with the state of the retransmission queue. This is a fairly complicated piece of logic which decides how much data that can be in-flight, depending on the available bandwidth. This is not done by any bandwidth estimation, but similar to TCP, where data is sent until it's lost, and then "we dial down a knob" and take it more carefully from here on. Future refactoring will try to separate the logic regarding fragment retransmission and the congestion control algorithm. Bug: webrtc:12614 Change-Id: I8678250abb766e567c3450634686919936ea077b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/214046 Commit-Queue: Victor Boivie <boivie@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33833}
103 lines
3.5 KiB
C++
103 lines
3.5 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_PACKET_DATA_H_
|
|
#define NET_DCSCTP_PACKET_DATA_H_
|
|
|
|
#include <cstdint>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "net/dcsctp/common/internal_types.h"
|
|
#include "net/dcsctp/public/types.h"
|
|
|
|
namespace dcsctp {
|
|
|
|
// Represents data that is either received and extracted from a DATA/I-DATA
|
|
// chunk, or data that is supposed to be sent, and wrapped in a DATA/I-DATA
|
|
// chunk (depending on peer capabilities).
|
|
//
|
|
// The data wrapped in this structure is actually the same as the DATA/I-DATA
|
|
// chunk (actually the union of them), but to avoid having all components be
|
|
// aware of the implementation details of the different chunks, this abstraction
|
|
// is used instead. A notable difference is also that it doesn't carry a
|
|
// Transmission Sequence Number (TSN), as that is not known when a chunk is
|
|
// created (assigned late, just when sending), and that the TSNs in DATA/I-DATA
|
|
// are wrapped numbers, and within the library, unwrapped sequence numbers are
|
|
// preferably used.
|
|
struct Data {
|
|
// Indicates if a chunk is the first in a fragmented message and maps to the
|
|
// "beginning" flag in DATA/I-DATA chunk.
|
|
using IsBeginning = StrongAlias<class IsBeginningTag, bool>;
|
|
|
|
// Indicates if a chunk is the last in a fragmented message and maps to the
|
|
// "end" flag in DATA/I-DATA chunk.
|
|
using IsEnd = StrongAlias<class IsEndTag, bool>;
|
|
|
|
Data(StreamID stream_id,
|
|
SSN ssn,
|
|
MID message_id,
|
|
FSN fsn,
|
|
PPID ppid,
|
|
std::vector<uint8_t> payload,
|
|
IsBeginning is_beginning,
|
|
IsEnd is_end,
|
|
IsUnordered is_unordered)
|
|
: stream_id(stream_id),
|
|
ssn(ssn),
|
|
message_id(message_id),
|
|
fsn(fsn),
|
|
ppid(ppid),
|
|
payload(std::move(payload)),
|
|
is_beginning(is_beginning),
|
|
is_end(is_end),
|
|
is_unordered(is_unordered) {}
|
|
|
|
// Move-only, to avoid accidental copies.
|
|
Data(Data&& other) = default;
|
|
Data& operator=(Data&& other) = default;
|
|
|
|
// Creates a copy of this `Data` object.
|
|
Data Clone() const {
|
|
return Data(stream_id, ssn, message_id, fsn, ppid, payload, is_beginning,
|
|
is_end, is_unordered);
|
|
}
|
|
|
|
// The size of this data, which translates to the size of its payload.
|
|
size_t size() const { return payload.size(); }
|
|
|
|
// Stream Identifier.
|
|
StreamID stream_id;
|
|
|
|
// Stream Sequence Number (SSN), per stream, for ordered chunks. Defined by
|
|
// RFC4960 and used only in DATA chunks (not I-DATA).
|
|
SSN ssn;
|
|
|
|
// Message Identifier (MID) per stream and ordered/unordered. Defined by
|
|
// RFC8260, and used together with options.is_unordered and stream_id to
|
|
// uniquely identify a message. Used only in I-DATA chunks (not DATA).
|
|
MID message_id;
|
|
// Fragment Sequence Number (FSN) per stream and ordered/unordered, as above.
|
|
FSN fsn;
|
|
|
|
// Payload Protocol Identifier (PPID).
|
|
PPID ppid;
|
|
|
|
// The actual data payload.
|
|
std::vector<uint8_t> payload;
|
|
|
|
// If this data represents the first, last or a middle chunk.
|
|
IsBeginning is_beginning;
|
|
IsEnd is_end;
|
|
// If this data is sent/received unordered.
|
|
IsUnordered is_unordered;
|
|
};
|
|
} // namespace dcsctp
|
|
|
|
#endif // NET_DCSCTP_PACKET_DATA_H_
|