Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include "net/dcsctp/public/dcsctp_handover_state.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
constexpr absl::string_view HandoverUnreadinessReasonToString(
|
||||
HandoverUnreadinessReason reason) {
|
||||
switch (reason) {
|
||||
case HandoverUnreadinessReason::kWrongConnectionState:
|
||||
return "WRONG_CONNECTION_STATE";
|
||||
case HandoverUnreadinessReason::kSendQueueNotEmpty:
|
||||
return "SEND_QUEUE_NOT_EMPTY";
|
||||
case HandoverUnreadinessReason::kDataTrackerTsnBlocksPending:
|
||||
return "DATA_TRACKER_TSN_BLOCKS_PENDING";
|
||||
case HandoverUnreadinessReason::kReassemblyQueueDeliveredTSNsGap:
|
||||
return "REASSEMBLY_QUEUE_DELIVERED_TSN_GAP";
|
||||
case HandoverUnreadinessReason::kStreamResetDeferred:
|
||||
return "STREAM_RESET_DEFERRED";
|
||||
case HandoverUnreadinessReason::kOrderedStreamHasUnassembledChunks:
|
||||
return "ORDERED_STREAM_HAS_UNASSEMBLED_CHUNKS";
|
||||
case HandoverUnreadinessReason::kUnorderedStreamHasUnassembledChunks:
|
||||
return "UNORDERED_STREAM_HAS_UNASSEMBLED_CHUNKS";
|
||||
case HandoverUnreadinessReason::kRetransmissionQueueOutstandingData:
|
||||
return "RETRANSMISSION_QUEUE_OUTSTANDING_DATA";
|
||||
case HandoverUnreadinessReason::kRetransmissionQueueFastRecovery:
|
||||
return "RETRANSMISSION_QUEUE_FAST_RECOVERY";
|
||||
case HandoverUnreadinessReason::kRetransmissionQueueNotEmpty:
|
||||
return "RETRANSMISSION_QUEUE_NOT_EMPTY";
|
||||
case HandoverUnreadinessReason::kPendingStreamReset:
|
||||
return "PENDING_STREAM_RESET";
|
||||
case HandoverUnreadinessReason::kPendingStreamResetRequest:
|
||||
return "PENDING_STREAM_RESET_REQUEST";
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string HandoverReadinessStatus::ToString() const {
|
||||
std::string result;
|
||||
for (uint32_t bit = 1;
|
||||
bit <= static_cast<uint32_t>(HandoverUnreadinessReason::kMax);
|
||||
bit *= 2) {
|
||||
auto flag = static_cast<HandoverUnreadinessReason>(bit);
|
||||
if (Contains(flag)) {
|
||||
if (!result.empty()) {
|
||||
result.append(",");
|
||||
}
|
||||
absl::string_view s = HandoverUnreadinessReasonToString(flag);
|
||||
result.append(s.data(), s.size());
|
||||
}
|
||||
}
|
||||
if (result.empty()) {
|
||||
result = "READY";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace dcsctp
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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_PUBLIC_DCSCTP_HANDOVER_STATE_H_
|
||||
#define NET_DCSCTP_PUBLIC_DCSCTP_HANDOVER_STATE_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "rtc_base/strong_alias.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// Stores state snapshot of a dcSCTP socket. The snapshot can be used to
|
||||
// recreate the socket - possibly in another process. This state should be
|
||||
// treaded as opaque - the calling client should not inspect or alter it except
|
||||
// for serialization. Serialization is not provided by dcSCTP. If needed it has
|
||||
// to be implemented in the calling client.
|
||||
struct DcSctpSocketHandoverState {
|
||||
enum class SocketState {
|
||||
kClosed,
|
||||
kConnected,
|
||||
};
|
||||
SocketState socket_state = SocketState::kClosed;
|
||||
|
||||
uint32_t my_verification_tag = 0;
|
||||
uint32_t my_initial_tsn = 0;
|
||||
uint32_t peer_verification_tag = 0;
|
||||
uint32_t peer_initial_tsn = 0;
|
||||
uint64_t tie_tag = 0;
|
||||
|
||||
struct Capabilities {
|
||||
bool partial_reliability = false;
|
||||
bool message_interleaving = false;
|
||||
bool reconfig = false;
|
||||
bool zero_checksum = false;
|
||||
uint16_t negotiated_maximum_incoming_streams = 0;
|
||||
uint16_t negotiated_maximum_outgoing_streams = 0;
|
||||
};
|
||||
Capabilities capabilities;
|
||||
|
||||
struct OutgoingStream {
|
||||
uint32_t id = 0;
|
||||
uint32_t next_ssn = 0;
|
||||
uint32_t next_unordered_mid = 0;
|
||||
uint32_t next_ordered_mid = 0;
|
||||
uint16_t priority = 0;
|
||||
};
|
||||
struct Transmission {
|
||||
uint32_t next_tsn = 0;
|
||||
uint32_t next_reset_req_sn = 0;
|
||||
uint32_t cwnd = 0;
|
||||
uint32_t rwnd = 0;
|
||||
uint32_t ssthresh = 0;
|
||||
uint32_t partial_bytes_acked = 0;
|
||||
std::vector<OutgoingStream> streams;
|
||||
};
|
||||
Transmission tx;
|
||||
|
||||
struct OrderedStream {
|
||||
uint32_t id = 0;
|
||||
uint32_t next_ssn = 0;
|
||||
};
|
||||
struct UnorderedStream {
|
||||
uint32_t id = 0;
|
||||
};
|
||||
struct Receive {
|
||||
bool seen_packet = false;
|
||||
uint32_t last_cumulative_acked_tsn = 0;
|
||||
uint32_t last_assembled_tsn = 0;
|
||||
uint32_t last_completed_deferred_reset_req_sn = 0;
|
||||
uint32_t last_completed_reset_req_sn = 0;
|
||||
std::vector<OrderedStream> ordered_streams;
|
||||
std::vector<UnorderedStream> unordered_streams;
|
||||
};
|
||||
Receive rx;
|
||||
};
|
||||
|
||||
// A list of possible reasons for a socket to be not ready for handover.
|
||||
enum class HandoverUnreadinessReason : uint32_t {
|
||||
kWrongConnectionState = 1,
|
||||
kSendQueueNotEmpty = 2,
|
||||
kPendingStreamResetRequest = 4,
|
||||
kDataTrackerTsnBlocksPending = 8,
|
||||
kPendingStreamReset = 16,
|
||||
kReassemblyQueueDeliveredTSNsGap = 32,
|
||||
kStreamResetDeferred = 64,
|
||||
kOrderedStreamHasUnassembledChunks = 128,
|
||||
kUnorderedStreamHasUnassembledChunks = 256,
|
||||
kRetransmissionQueueOutstandingData = 512,
|
||||
kRetransmissionQueueFastRecovery = 1024,
|
||||
kRetransmissionQueueNotEmpty = 2048,
|
||||
kMax = kRetransmissionQueueNotEmpty,
|
||||
};
|
||||
|
||||
// Return value of `DcSctpSocketInterface::GetHandoverReadiness`. Set of
|
||||
// `HandoverUnreadinessReason` bits. When no bit is set, the socket is in the
|
||||
// state in which a snapshot of the state can be made by
|
||||
// `GetHandoverStateAndClose()`.
|
||||
class HandoverReadinessStatus
|
||||
: public webrtc::StrongAlias<class HandoverReadinessStatusTag, uint32_t> {
|
||||
public:
|
||||
// Constructs an empty `HandoverReadinessStatus` which represents ready state.
|
||||
constexpr HandoverReadinessStatus()
|
||||
: webrtc::StrongAlias<class HandoverReadinessStatusTag, uint32_t>(0) {}
|
||||
// Constructs status object that contains a single reason for not being
|
||||
// handover ready.
|
||||
constexpr explicit HandoverReadinessStatus(HandoverUnreadinessReason reason)
|
||||
: webrtc::StrongAlias<class HandoverReadinessStatusTag, uint32_t>(
|
||||
static_cast<uint32_t>(reason)) {}
|
||||
|
||||
// Convenience methods
|
||||
constexpr bool IsReady() const { return value() == 0; }
|
||||
constexpr bool Contains(HandoverUnreadinessReason reason) const {
|
||||
return value() & static_cast<uint32_t>(reason);
|
||||
}
|
||||
HandoverReadinessStatus& Add(HandoverUnreadinessReason reason) {
|
||||
return Add(HandoverReadinessStatus(reason));
|
||||
}
|
||||
HandoverReadinessStatus& Add(HandoverReadinessStatus status) {
|
||||
value() |= status.value();
|
||||
return *this;
|
||||
}
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_DCSCTP_HANDOVER_STATE_H_
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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_PUBLIC_DCSCTP_MESSAGE_H_
|
||||
#define NET_DCSCTP_PUBLIC_DCSCTP_MESSAGE_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/public/types.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// An SCTP message is a group of bytes sent and received as a whole on a
|
||||
// specified stream identifier (`stream_id`), and with a payload protocol
|
||||
// identifier (`ppid`).
|
||||
class DcSctpMessage {
|
||||
public:
|
||||
DcSctpMessage(StreamID stream_id, PPID ppid, std::vector<uint8_t> payload)
|
||||
: stream_id_(stream_id), ppid_(ppid), payload_(std::move(payload)) {}
|
||||
|
||||
DcSctpMessage(DcSctpMessage&& other) = default;
|
||||
DcSctpMessage& operator=(DcSctpMessage&& other) = default;
|
||||
DcSctpMessage(const DcSctpMessage&) = delete;
|
||||
DcSctpMessage& operator=(const DcSctpMessage&) = delete;
|
||||
|
||||
// The stream identifier to which the message is sent.
|
||||
StreamID stream_id() const { return stream_id_; }
|
||||
|
||||
// The payload protocol identifier (ppid) associated with the message.
|
||||
PPID ppid() const { return ppid_; }
|
||||
|
||||
// The payload of the message.
|
||||
rtc::ArrayView<const uint8_t> payload() const { return payload_; }
|
||||
|
||||
// When destructing the message, extracts the payload.
|
||||
std::vector<uint8_t> ReleasePayload() && { return std::move(payload_); }
|
||||
|
||||
private:
|
||||
StreamID stream_id_;
|
||||
PPID ppid_;
|
||||
std::vector<uint8_t> payload_;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_DCSCTP_MESSAGE_H_
|
||||
209
TMessagesProj/jni/voip/webrtc/net/dcsctp/public/dcsctp_options.h
Normal file
209
TMessagesProj/jni/voip/webrtc/net/dcsctp/public/dcsctp_options.h
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* 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_PUBLIC_DCSCTP_OPTIONS_H_
|
||||
#define NET_DCSCTP_PUBLIC_DCSCTP_OPTIONS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "net/dcsctp/public/types.h"
|
||||
|
||||
namespace dcsctp {
|
||||
struct DcSctpOptions {
|
||||
// The largest safe SCTP packet. Starting from the minimum guaranteed MTU
|
||||
// value of 1280 for IPv6 (which may not support fragmentation), take off 85
|
||||
// bytes for DTLS/TURN/TCP/IP and ciphertext overhead.
|
||||
//
|
||||
// Additionally, it's possible that TURN adds an additional 4 bytes of
|
||||
// overhead after a channel has been established, so an additional 4 bytes is
|
||||
// subtracted
|
||||
//
|
||||
// 1280 IPV6 MTU
|
||||
// -40 IPV6 header
|
||||
// -8 UDP
|
||||
// -24 GCM Cipher
|
||||
// -13 DTLS record header
|
||||
// -4 TURN ChannelData
|
||||
// = 1191 bytes.
|
||||
static constexpr size_t kMaxSafeMTUSize = 1191;
|
||||
|
||||
// The local port for which the socket is supposed to be bound to. Incoming
|
||||
// packets will be verified that they are sent to this port number and all
|
||||
// outgoing packets will have this port number as source port.
|
||||
int local_port = 5000;
|
||||
|
||||
// The remote port to send packets to. All outgoing packets will have this
|
||||
// port number as destination port.
|
||||
int remote_port = 5000;
|
||||
|
||||
// The announced maximum number of incoming streams. Note that this value is
|
||||
// constant and can't be currently increased in run-time as "Add Incoming
|
||||
// Streams Request" in RFC6525 isn't supported.
|
||||
//
|
||||
// The socket implementation doesn't have any per-stream fixed costs, which is
|
||||
// why the default value is set to be the maximum value.
|
||||
uint16_t announced_maximum_incoming_streams = 65535;
|
||||
|
||||
// The announced maximum number of outgoing streams. Note that this value is
|
||||
// constant and can't be currently increased in run-time as "Add Outgoing
|
||||
// Streams Request" in RFC6525 isn't supported.
|
||||
//
|
||||
// The socket implementation doesn't have any per-stream fixed costs, which is
|
||||
// why the default value is set to be the maximum value.
|
||||
uint16_t announced_maximum_outgoing_streams = 65535;
|
||||
|
||||
// Maximum SCTP packet size. The library will limit the size of generated
|
||||
// packets to be less than or equal to this number. This does not include any
|
||||
// overhead of DTLS, TURN, UDP or IP headers.
|
||||
size_t mtu = kMaxSafeMTUSize;
|
||||
|
||||
// The largest allowed message payload to be sent. Messages will be rejected
|
||||
// if their payload is larger than this value. Note that this doesn't affect
|
||||
// incoming messages, which may larger than this value (but smaller than
|
||||
// `max_receiver_window_buffer_size`).
|
||||
size_t max_message_size = 256 * 1024;
|
||||
|
||||
// The default stream priority, if not overridden by
|
||||
// `SctpSocket::SetStreamPriority`. The default value is selected to be
|
||||
// compatible with https://www.w3.org/TR/webrtc-priority/, section 4.2-4.3.
|
||||
StreamPriority default_stream_priority = StreamPriority(256);
|
||||
|
||||
// Maximum received window buffer size. This should be a bit larger than the
|
||||
// largest sized message you want to be able to receive. This essentially
|
||||
// limits the memory usage on the receive side. Note that memory is allocated
|
||||
// dynamically, and this represents the maximum amount of buffered data. The
|
||||
// actual memory usage of the library will be smaller in normal operation, and
|
||||
// will be larger than this due to other allocations and overhead if the
|
||||
// buffer is fully utilized.
|
||||
size_t max_receiver_window_buffer_size = 5 * 1024 * 1024;
|
||||
|
||||
// Maximum send buffer size. It will not be possible to queue more data than
|
||||
// this before sending it.
|
||||
size_t max_send_buffer_size = 2'000'000;
|
||||
|
||||
// A threshold that, when the amount of data in the send buffer goes below
|
||||
// this value, will trigger `DcSctpCallbacks::OnTotalBufferedAmountLow`.
|
||||
size_t total_buffered_amount_low_threshold = 1'800'000;
|
||||
|
||||
// Max allowed RTT value. When the RTT is measured and it's found to be larger
|
||||
// than this value, it will be discarded and not used for e.g. any RTO
|
||||
// calculation. The default value is an extreme maximum but can be adapted
|
||||
// to better match the environment.
|
||||
DurationMs rtt_max = DurationMs(60'000);
|
||||
|
||||
// Initial RTO value.
|
||||
DurationMs rto_initial = DurationMs(500);
|
||||
|
||||
// Maximum RTO value.
|
||||
DurationMs rto_max = DurationMs(60'000);
|
||||
|
||||
// Minimum RTO value. This must be larger than an expected peer delayed ack
|
||||
// timeout.
|
||||
DurationMs rto_min = DurationMs(400);
|
||||
|
||||
// T1-init timeout.
|
||||
DurationMs t1_init_timeout = DurationMs(1000);
|
||||
|
||||
// T1-cookie timeout.
|
||||
DurationMs t1_cookie_timeout = DurationMs(1000);
|
||||
|
||||
// T2-shutdown timeout.
|
||||
DurationMs t2_shutdown_timeout = DurationMs(1000);
|
||||
|
||||
// For t1-init, t1-cookie, t2-shutdown, t3-rtx, this value - if set - will be
|
||||
// the upper bound on how large the exponentially backed off timeout can
|
||||
// become. The lower the duration, the faster the connection can recover on
|
||||
// transient network issues. Setting this value may require changing
|
||||
// `max_retransmissions` and `max_init_retransmits` to ensure that the
|
||||
// connection is not closed too quickly.
|
||||
absl::optional<DurationMs> max_timer_backoff_duration = absl::nullopt;
|
||||
|
||||
// Hearbeat interval (on idle connections only). Set to zero to disable.
|
||||
DurationMs heartbeat_interval = DurationMs(30000);
|
||||
|
||||
// The maximum time when a SACK will be sent from the arrival of an
|
||||
// unacknowledged packet. Whatever is smallest of RTO/2 and this will be used.
|
||||
DurationMs delayed_ack_max_timeout = DurationMs(200);
|
||||
|
||||
// The minimum limit for the measured RTT variance
|
||||
//
|
||||
// Setting this below the expected delayed ack timeout (+ margin) of the peer
|
||||
// might result in unnecessary retransmissions, as the maximum time it takes
|
||||
// to ACK a DATA chunk is typically RTT + ATO (delayed ack timeout), and when
|
||||
// the SCTP channel is quite idle, and heartbeats dominate the source of RTT
|
||||
// measurement, the RTO would converge with the smoothed RTT (SRTT). The
|
||||
// default ATO is 200ms in usrsctp, and a 20ms (10%) margin would include the
|
||||
// processing time of received packets and the clock granularity when setting
|
||||
// the delayed ack timer on the peer.
|
||||
//
|
||||
// This is described for TCP in
|
||||
// https://datatracker.ietf.org/doc/html/rfc6298#section-4.
|
||||
DurationMs min_rtt_variance = DurationMs(220);
|
||||
|
||||
// The initial congestion window size, in number of MTUs.
|
||||
// See https://tools.ietf.org/html/rfc4960#section-7.2.1 which defaults at ~3
|
||||
// and https://research.google/pubs/pub36640/ which argues for at least ten
|
||||
// segments.
|
||||
size_t cwnd_mtus_initial = 10;
|
||||
|
||||
// The minimum congestion window size, in number of MTUs, upon detection of
|
||||
// packet loss by SACK. Note that if the retransmission timer expires, the
|
||||
// congestion window will be as small as one MTU. See
|
||||
// https://tools.ietf.org/html/rfc4960#section-7.2.3.
|
||||
size_t cwnd_mtus_min = 4;
|
||||
|
||||
// When the congestion window is at or above this number of MTUs, the
|
||||
// congestion control algorithm will avoid filling the congestion window
|
||||
// fully, if that results in fragmenting large messages into quite small
|
||||
// packets. When the congestion window is smaller than this option, it will
|
||||
// aim to fill the congestion window as much as it can, even if it results in
|
||||
// creating small fragmented packets.
|
||||
size_t avoid_fragmentation_cwnd_mtus = 6;
|
||||
|
||||
// The number of packets that may be sent at once. This is limited to avoid
|
||||
// bursts that too quickly fill the send buffer. Typically in a a socket in
|
||||
// its "slow start" phase (when it sends as much as it can), it will send
|
||||
// up to three packets for every SACK received, so the default limit is set
|
||||
// just above that, and then mostly applicable for (but not limited to) fast
|
||||
// retransmission scenarios.
|
||||
int max_burst = 4;
|
||||
|
||||
// Maximum Data Retransmit Attempts (per DATA chunk). Set to absl::nullopt for
|
||||
// no limit.
|
||||
absl::optional<int> max_retransmissions = 10;
|
||||
|
||||
// Max.Init.Retransmits (https://tools.ietf.org/html/rfc4960#section-15). Set
|
||||
// to absl::nullopt for no limit.
|
||||
absl::optional<int> max_init_retransmits = 8;
|
||||
|
||||
// RFC3758 Partial Reliability Extension
|
||||
bool enable_partial_reliability = true;
|
||||
|
||||
// RFC8260 Stream Schedulers and User Message Interleaving
|
||||
bool enable_message_interleaving = false;
|
||||
|
||||
// If RTO should be added to heartbeat_interval
|
||||
bool heartbeat_interval_include_rtt = true;
|
||||
|
||||
// Disables SCTP packet crc32 verification. For fuzzers only!
|
||||
bool disable_checksum_verification = false;
|
||||
|
||||
// Controls the "zero checksum option" feature, as defined in
|
||||
// https://www.ietf.org/archive/id/draft-ietf-tsvwg-sctp-zero-checksum-06.html.
|
||||
// To have this feature enabled, both peers must be configured to use the
|
||||
// same (defined, not "none") alternate error detection method.
|
||||
ZeroChecksumAlternateErrorDetectionMethod
|
||||
zero_checksum_alternate_error_detection_method =
|
||||
ZeroChecksumAlternateErrorDetectionMethod::None();
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_DCSCTP_OPTIONS_H_
|
||||
657
TMessagesProj/jni/voip/webrtc/net/dcsctp/public/dcsctp_socket.h
Normal file
657
TMessagesProj/jni/voip/webrtc/net/dcsctp/public/dcsctp_socket.h
Normal file
|
|
@ -0,0 +1,657 @@
|
|||
/*
|
||||
* 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_PUBLIC_DCSCTP_SOCKET_H_
|
||||
#define NET_DCSCTP_PUBLIC_DCSCTP_SOCKET_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/task_queue/task_queue_base.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "net/dcsctp/public/dcsctp_handover_state.h"
|
||||
#include "net/dcsctp/public/dcsctp_message.h"
|
||||
#include "net/dcsctp/public/dcsctp_options.h"
|
||||
#include "net/dcsctp/public/packet_observer.h"
|
||||
#include "net/dcsctp/public/timeout.h"
|
||||
#include "net/dcsctp/public/types.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// The socket/association state
|
||||
enum class SocketState {
|
||||
// The socket is closed.
|
||||
kClosed,
|
||||
// The socket has initiated a connection, which is not yet established. Note
|
||||
// that for incoming connections and for reconnections when the socket is
|
||||
// already connected, the socket will not transition to this state.
|
||||
kConnecting,
|
||||
// The socket is connected, and the connection is established.
|
||||
kConnected,
|
||||
// The socket is shutting down, and the connection is not yet closed.
|
||||
kShuttingDown,
|
||||
};
|
||||
|
||||
// Send options for sending messages
|
||||
struct SendOptions {
|
||||
// If the message should be sent with unordered message delivery.
|
||||
IsUnordered unordered = IsUnordered(false);
|
||||
|
||||
// If set, will discard messages that haven't been correctly sent and
|
||||
// received before the lifetime has expired. This is only available if the
|
||||
// peer supports Partial Reliability Extension (RFC3758).
|
||||
absl::optional<DurationMs> lifetime = absl::nullopt;
|
||||
|
||||
// If set, limits the number of retransmissions. This is only available
|
||||
// if the peer supports Partial Reliability Extension (RFC3758).
|
||||
absl::optional<size_t> max_retransmissions = absl::nullopt;
|
||||
|
||||
// If set, will generate lifecycle events for this message. See e.g.
|
||||
// `DcSctpSocketCallbacks::OnLifecycleMessageFullySent`. This value is decided
|
||||
// by the client and the library will provide it to all lifecycle callbacks.
|
||||
LifecycleId lifecycle_id = LifecycleId::NotSet();
|
||||
};
|
||||
|
||||
enum class ErrorKind {
|
||||
// Indicates that no error has occurred. This will never be the case when
|
||||
// `OnError` or `OnAborted` is called.
|
||||
kNoError,
|
||||
// There have been too many retries or timeouts, and the library has given up.
|
||||
kTooManyRetries,
|
||||
// A command was received that is only possible to execute when the socket is
|
||||
// connected, which it is not.
|
||||
kNotConnected,
|
||||
// Parsing of the command or its parameters failed.
|
||||
kParseFailed,
|
||||
// Commands are received in the wrong sequence, which indicates a
|
||||
// synchronisation mismatch between the peers.
|
||||
kWrongSequence,
|
||||
// The peer has reported an issue using ERROR or ABORT command.
|
||||
kPeerReported,
|
||||
// The peer has performed a protocol violation.
|
||||
kProtocolViolation,
|
||||
// The receive or send buffers have been exhausted.
|
||||
kResourceExhaustion,
|
||||
// The client has performed an invalid operation.
|
||||
kUnsupportedOperation,
|
||||
};
|
||||
|
||||
inline constexpr absl::string_view ToString(ErrorKind error) {
|
||||
switch (error) {
|
||||
case ErrorKind::kNoError:
|
||||
return "NO_ERROR";
|
||||
case ErrorKind::kTooManyRetries:
|
||||
return "TOO_MANY_RETRIES";
|
||||
case ErrorKind::kNotConnected:
|
||||
return "NOT_CONNECTED";
|
||||
case ErrorKind::kParseFailed:
|
||||
return "PARSE_FAILED";
|
||||
case ErrorKind::kWrongSequence:
|
||||
return "WRONG_SEQUENCE";
|
||||
case ErrorKind::kPeerReported:
|
||||
return "PEER_REPORTED";
|
||||
case ErrorKind::kProtocolViolation:
|
||||
return "PROTOCOL_VIOLATION";
|
||||
case ErrorKind::kResourceExhaustion:
|
||||
return "RESOURCE_EXHAUSTION";
|
||||
case ErrorKind::kUnsupportedOperation:
|
||||
return "UNSUPPORTED_OPERATION";
|
||||
}
|
||||
}
|
||||
|
||||
enum class SendStatus {
|
||||
// The message was enqueued successfully. As sending the message is done
|
||||
// asynchronously, this is no guarantee that the message has been actually
|
||||
// sent.
|
||||
kSuccess,
|
||||
// The message was rejected as the payload was empty (which is not allowed in
|
||||
// SCTP).
|
||||
kErrorMessageEmpty,
|
||||
// The message was rejected as the payload was larger than what has been set
|
||||
// as `DcSctpOptions.max_message_size`.
|
||||
kErrorMessageTooLarge,
|
||||
// The message could not be enqueued as the socket is out of resources. This
|
||||
// mainly indicates that the send queue is full.
|
||||
kErrorResourceExhaustion,
|
||||
// The message could not be sent as the socket is shutting down.
|
||||
kErrorShuttingDown,
|
||||
};
|
||||
|
||||
inline constexpr absl::string_view ToString(SendStatus error) {
|
||||
switch (error) {
|
||||
case SendStatus::kSuccess:
|
||||
return "SUCCESS";
|
||||
case SendStatus::kErrorMessageEmpty:
|
||||
return "ERROR_MESSAGE_EMPTY";
|
||||
case SendStatus::kErrorMessageTooLarge:
|
||||
return "ERROR_MESSAGE_TOO_LARGE";
|
||||
case SendStatus::kErrorResourceExhaustion:
|
||||
return "ERROR_RESOURCE_EXHAUSTION";
|
||||
case SendStatus::kErrorShuttingDown:
|
||||
return "ERROR_SHUTTING_DOWN";
|
||||
}
|
||||
}
|
||||
|
||||
// Return value of ResetStreams.
|
||||
enum class ResetStreamsStatus {
|
||||
// If the connection is not yet established, this will be returned.
|
||||
kNotConnected,
|
||||
// Indicates that ResetStreams operation has been successfully initiated.
|
||||
kPerformed,
|
||||
// Indicates that ResetStreams has failed as it's not supported by the peer.
|
||||
kNotSupported,
|
||||
};
|
||||
|
||||
inline constexpr absl::string_view ToString(ResetStreamsStatus error) {
|
||||
switch (error) {
|
||||
case ResetStreamsStatus::kNotConnected:
|
||||
return "NOT_CONNECTED";
|
||||
case ResetStreamsStatus::kPerformed:
|
||||
return "PERFORMED";
|
||||
case ResetStreamsStatus::kNotSupported:
|
||||
return "NOT_SUPPORTED";
|
||||
}
|
||||
}
|
||||
|
||||
// Return value of DcSctpSocketCallbacks::SendPacketWithStatus.
|
||||
enum class SendPacketStatus {
|
||||
// Indicates that the packet was successfully sent. As sending is unreliable,
|
||||
// there are no guarantees that the packet was actually delivered.
|
||||
kSuccess,
|
||||
// The packet was not sent due to a temporary failure, such as the local send
|
||||
// buffer becoming exhausted. This return value indicates that the socket will
|
||||
// recover and sending that packet can be retried at a later time.
|
||||
kTemporaryFailure,
|
||||
// The packet was not sent due to other reasons.
|
||||
kError,
|
||||
};
|
||||
|
||||
// Represent known SCTP implementations.
|
||||
enum class SctpImplementation {
|
||||
// There is not enough information toto determine any SCTP implementation.
|
||||
kUnknown,
|
||||
// This implementation.
|
||||
kDcsctp,
|
||||
// https://github.com/sctplab/usrsctp.
|
||||
kUsrSctp,
|
||||
// Any other implementation.
|
||||
kOther,
|
||||
};
|
||||
|
||||
inline constexpr absl::string_view ToString(SctpImplementation implementation) {
|
||||
switch (implementation) {
|
||||
case SctpImplementation::kUnknown:
|
||||
return "unknown";
|
||||
case SctpImplementation::kDcsctp:
|
||||
return "dcsctp";
|
||||
case SctpImplementation::kUsrSctp:
|
||||
return "usrsctp";
|
||||
case SctpImplementation::kOther:
|
||||
return "other";
|
||||
}
|
||||
}
|
||||
|
||||
// Tracked metrics, which is the return value of GetMetrics. Optional members
|
||||
// will be unset when they are not yet known.
|
||||
struct Metrics {
|
||||
// Transmission stats and metrics.
|
||||
|
||||
// Number of packets sent.
|
||||
size_t tx_packets_count = 0;
|
||||
|
||||
// Number of messages requested to be sent.
|
||||
size_t tx_messages_count = 0;
|
||||
|
||||
// Number of packets retransmitted. Since SCTP packets can contain both
|
||||
// retransmitted DATA chunks and DATA chunks that are transmitted for the
|
||||
// first time, this represents an upper bound as it's incremented every time a
|
||||
// packet contains a retransmitted DATA chunk.
|
||||
size_t rtx_packets_count = 0;
|
||||
|
||||
// Total number of bytes retransmitted. This includes the payload and
|
||||
// DATA/I-DATA headers, but not SCTP packet headers.
|
||||
uint64_t rtx_bytes_count = 0;
|
||||
|
||||
// The current congestion window (cwnd) in bytes, corresponding to spinfo_cwnd
|
||||
// defined in RFC6458.
|
||||
size_t cwnd_bytes = 0;
|
||||
|
||||
// Smoothed round trip time, corresponding to spinfo_srtt defined in RFC6458.
|
||||
int srtt_ms = 0;
|
||||
|
||||
// Number of data items in the retransmission queue that haven’t been
|
||||
// acked/nacked yet and are in-flight. Corresponding to sstat_unackdata
|
||||
// defined in RFC6458. This may be an approximation when there are messages in
|
||||
// the send queue that haven't been fragmented/packetized yet.
|
||||
size_t unack_data_count = 0;
|
||||
|
||||
// Receive stats and metrics.
|
||||
|
||||
// Number of packets received.
|
||||
size_t rx_packets_count = 0;
|
||||
|
||||
// Number of messages received.
|
||||
size_t rx_messages_count = 0;
|
||||
|
||||
// The peer’s last announced receiver window size, corresponding to
|
||||
// sstat_rwnd defined in RFC6458.
|
||||
uint32_t peer_rwnd_bytes = 0;
|
||||
|
||||
// Returns the detected SCTP implementation of the peer. As this is not
|
||||
// explicitly signalled during the connection establishment, heuristics is
|
||||
// used to analyze e.g. the state cookie in the INIT-ACK chunk.
|
||||
SctpImplementation peer_implementation = SctpImplementation::kUnknown;
|
||||
|
||||
// Indicates if RFC8260 User Message Interleaving has been negotiated by both
|
||||
// peers.
|
||||
bool uses_message_interleaving = false;
|
||||
|
||||
// Indicates if draft-tuexen-tsvwg-sctp-zero-checksum-00 has been negotiated
|
||||
// by both peers.
|
||||
bool uses_zero_checksum = false;
|
||||
|
||||
// The number of negotiated incoming and outgoing streams, which is configured
|
||||
// locally as `DcSctpOptions::announced_maximum_incoming_streams` and
|
||||
// `DcSctpOptions::announced_maximum_outgoing_streams`, and which will be
|
||||
// signaled by the peer during connection.
|
||||
uint16_t negotiated_maximum_incoming_streams = 0;
|
||||
uint16_t negotiated_maximum_outgoing_streams = 0;
|
||||
};
|
||||
|
||||
// Callbacks that the DcSctpSocket will call synchronously to the owning
|
||||
// client. It is allowed to call back into the library from callbacks that start
|
||||
// with "On". It has been explicitly documented when it's not allowed to call
|
||||
// back into this library from within a callback.
|
||||
//
|
||||
// Theses callbacks are only synchronously triggered as a result of the client
|
||||
// calling a public method in `DcSctpSocketInterface`.
|
||||
class DcSctpSocketCallbacks {
|
||||
public:
|
||||
virtual ~DcSctpSocketCallbacks() = default;
|
||||
|
||||
// Called when the library wants the packet serialized as `data` to be sent.
|
||||
//
|
||||
// TODO(bugs.webrtc.org/12943): This method is deprecated, see
|
||||
// `SendPacketWithStatus`.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual void SendPacket(rtc::ArrayView<const uint8_t> data) {}
|
||||
|
||||
// Called when the library wants the packet serialized as `data` to be sent.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual SendPacketStatus SendPacketWithStatus(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
SendPacket(data);
|
||||
return SendPacketStatus::kSuccess;
|
||||
}
|
||||
|
||||
// Called when the library wants to create a Timeout. The callback must return
|
||||
// an object that implements that interface.
|
||||
//
|
||||
// Low precision tasks are scheduled more efficiently by using leeway to
|
||||
// reduce Idle Wake Ups and is the preferred precision whenever possible. High
|
||||
// precision timeouts do not have this leeway, but is still limited by OS
|
||||
// timer precision. At the time of writing, kLow's additional leeway may be up
|
||||
// to 17 ms, but please see webrtc::TaskQueueBase::DelayPrecision for
|
||||
// up-to-date information.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual std::unique_ptr<Timeout> CreateTimeout(
|
||||
webrtc::TaskQueueBase::DelayPrecision precision) {
|
||||
// TODO(hbos): When dependencies have migrated to this new signature, make
|
||||
// this pure virtual and delete the other version.
|
||||
return CreateTimeout();
|
||||
}
|
||||
// TODO(hbos): When dependencies have migrated to the other signature, delete
|
||||
// this version.
|
||||
virtual std::unique_ptr<Timeout> CreateTimeout() {
|
||||
return CreateTimeout(webrtc::TaskQueueBase::DelayPrecision::kLow);
|
||||
}
|
||||
|
||||
// Returns the current time in milliseconds (from any epoch).
|
||||
//
|
||||
// TODO(bugs.webrtc.org/15593): This method is deprecated, see `Now`.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual TimeMs TimeMillis() { return TimeMs(0); }
|
||||
|
||||
// Returns the current time (from any epoch).
|
||||
//
|
||||
// This callback will eventually replace `TimeMillis()`.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual webrtc::Timestamp Now() {
|
||||
return webrtc::Timestamp::Millis(*TimeMillis());
|
||||
}
|
||||
|
||||
// Called when the library needs a random number uniformly distributed between
|
||||
// `low` (inclusive) and `high` (exclusive). The random numbers used by the
|
||||
// library are not used for cryptographic purposes. There are no requirements
|
||||
// that the random number generator must be secure.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual uint32_t GetRandomInt(uint32_t low, uint32_t high) = 0;
|
||||
|
||||
// Triggered when the outgoing message buffer is empty, meaning that there are
|
||||
// no more queued messages, but there can still be packets in-flight or to be
|
||||
// retransmitted. (in contrast to SCTP_SENDER_DRY_EVENT).
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
ABSL_DEPRECATED("Use OnTotalBufferedAmountLow instead")
|
||||
virtual void NotifyOutgoingMessageBufferEmpty() {}
|
||||
|
||||
// Called when the library has received an SCTP message in full and delivers
|
||||
// it to the upper layer.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnMessageReceived(DcSctpMessage message) = 0;
|
||||
|
||||
// Triggered when an non-fatal error is reported by either this library or
|
||||
// from the other peer (by sending an ERROR command). These should be logged,
|
||||
// but no other action need to be taken as the association is still viable.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnError(ErrorKind error, absl::string_view message) = 0;
|
||||
|
||||
// Triggered when the socket has aborted - either as decided by this socket
|
||||
// due to e.g. too many retransmission attempts, or by the peer when
|
||||
// receiving an ABORT command. No other callbacks will be done after this
|
||||
// callback, unless reconnecting.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnAborted(ErrorKind error, absl::string_view message) = 0;
|
||||
|
||||
// Called when calling `Connect` succeeds, but also for incoming successful
|
||||
// connection attempts.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnConnected() = 0;
|
||||
|
||||
// Called when the socket is closed in a controlled way. No other
|
||||
// callbacks will be done after this callback, unless reconnecting.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnClosed() = 0;
|
||||
|
||||
// On connection restarted (by peer). This is just a notification, and the
|
||||
// association is expected to work fine after this call, but there could have
|
||||
// been packet loss as a result of restarting the association.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnConnectionRestarted() = 0;
|
||||
|
||||
// Indicates that a stream reset request has failed.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnStreamsResetFailed(
|
||||
rtc::ArrayView<const StreamID> outgoing_streams,
|
||||
absl::string_view reason) = 0;
|
||||
|
||||
// Indicates that a stream reset request has been performed.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnStreamsResetPerformed(
|
||||
rtc::ArrayView<const StreamID> outgoing_streams) = 0;
|
||||
|
||||
// When a peer has reset some of its outgoing streams, this will be called. An
|
||||
// empty list indicates that all streams have been reset.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnIncomingStreamsReset(
|
||||
rtc::ArrayView<const StreamID> incoming_streams) = 0;
|
||||
|
||||
// Will be called when the amount of data buffered to be sent falls to or
|
||||
// below the threshold set when calling `SetBufferedAmountLowThreshold`.
|
||||
//
|
||||
// It is allowed to call into this library from within this callback.
|
||||
virtual void OnBufferedAmountLow(StreamID stream_id) {}
|
||||
|
||||
// Will be called when the total amount of data buffered (in the entire send
|
||||
// buffer, for all streams) falls to or below the threshold specified in
|
||||
// `DcSctpOptions::total_buffered_amount_low_threshold`.
|
||||
virtual void OnTotalBufferedAmountLow() {}
|
||||
|
||||
// == Lifecycle Events ==
|
||||
//
|
||||
// If a `lifecycle_id` is provided as `SendOptions`, lifecycle callbacks will
|
||||
// be triggered as the message is processed by the library.
|
||||
//
|
||||
// The possible transitions are shown in the graph below:
|
||||
//
|
||||
// DcSctpSocket::Send ────────────────────────┐
|
||||
// │ │
|
||||
// │ │
|
||||
// v v
|
||||
// OnLifecycleMessageFullySent ───────> OnLifecycleMessageExpired
|
||||
// │ │
|
||||
// │ │
|
||||
// v v
|
||||
// OnLifeCycleMessageDelivered ────────────> OnLifecycleEnd
|
||||
|
||||
// OnLifecycleMessageFullySent will be called when a message has been fully
|
||||
// sent, meaning that the last fragment has been produced from the send queue
|
||||
// and sent on the network. Note that this will trigger at most once per
|
||||
// message even if the message was retransmitted due to packet loss.
|
||||
//
|
||||
// This is a lifecycle event.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual void OnLifecycleMessageFullySent(LifecycleId lifecycle_id) {}
|
||||
|
||||
// OnLifecycleMessageExpired will be called when a message has expired. If it
|
||||
// was expired with data remaining in the send queue that had not been sent
|
||||
// ever, `maybe_delivered` will be set to false. If `maybe_delivered` is true,
|
||||
// the message has at least once been sent and may have been correctly
|
||||
// received by the peer, but it has expired before the receiver managed to
|
||||
// acknowledge it. This means that if `maybe_delivered` is true, it's unknown
|
||||
// if the message was lost or was delivered, and if `maybe_delivered` is
|
||||
// false, it's guaranteed to not be delivered.
|
||||
//
|
||||
// It's guaranteed that `OnLifecycleMessageDelivered` is not called if this
|
||||
// callback has triggered.
|
||||
//
|
||||
// This is a lifecycle event.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual void OnLifecycleMessageExpired(LifecycleId lifecycle_id,
|
||||
bool maybe_delivered) {}
|
||||
|
||||
// OnLifecycleMessageDelivered will be called when a non-expired message has
|
||||
// been acknowledged by the peer as delivered.
|
||||
//
|
||||
// Note that this will trigger only when the peer moves its cumulative TSN ack
|
||||
// beyond this message, and will not fire for messages acked using
|
||||
// gap-ack-blocks as those are renegable. This means that this may fire a bit
|
||||
// later than the message was actually first "acked" by the peer, as -
|
||||
// according to the protocol - those acks may be unacked later by the client.
|
||||
//
|
||||
// It's guaranteed that `OnLifecycleMessageExpired` is not called if this
|
||||
// callback has triggered.
|
||||
//
|
||||
// This is a lifecycle event.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual void OnLifecycleMessageDelivered(LifecycleId lifecycle_id) {}
|
||||
|
||||
// OnLifecycleEnd will be called when a lifecycle event has reached its end.
|
||||
// It will be called when processing of a message is complete, no matter how
|
||||
// it completed. It will be called after all other lifecycle events, if any.
|
||||
//
|
||||
// Note that it's possible that this callback triggers without any other
|
||||
// lifecycle callbacks having been called before in case of errors, such as
|
||||
// attempting to send an empty message or failing to enqueue a message if the
|
||||
// send queue is full.
|
||||
//
|
||||
// NOTE: When the socket is deallocated, there will be no `OnLifecycleEnd`
|
||||
// callbacks sent for messages that were enqueued. But as long as the socket
|
||||
// is alive, `OnLifecycleEnd` callbacks are guaranteed to be sent as messages
|
||||
// are either expired or successfully acknowledged.
|
||||
//
|
||||
// This is a lifecycle event.
|
||||
//
|
||||
// Note that it's NOT ALLOWED to call into this library from within this
|
||||
// callback.
|
||||
virtual void OnLifecycleEnd(LifecycleId lifecycle_id) {}
|
||||
};
|
||||
|
||||
// The DcSctpSocket implementation implements the following interface.
|
||||
// This class is thread-compatible.
|
||||
class DcSctpSocketInterface {
|
||||
public:
|
||||
virtual ~DcSctpSocketInterface() = default;
|
||||
|
||||
// To be called when an incoming SCTP packet is to be processed.
|
||||
virtual void ReceivePacket(rtc::ArrayView<const uint8_t> data) = 0;
|
||||
|
||||
// To be called when a timeout has expired. The `timeout_id` is provided
|
||||
// when the timeout was initiated.
|
||||
virtual void HandleTimeout(TimeoutID timeout_id) = 0;
|
||||
|
||||
// Connects the socket. This is an asynchronous operation, and
|
||||
// `DcSctpSocketCallbacks::OnConnected` will be called on success.
|
||||
virtual void Connect() = 0;
|
||||
|
||||
// Puts this socket to the state in which the original socket was when its
|
||||
// `DcSctpSocketHandoverState` was captured by `GetHandoverStateAndClose`.
|
||||
// `RestoreFromState` is allowed only on the closed socket.
|
||||
// `DcSctpSocketCallbacks::OnConnected` will be called if a connected socket
|
||||
// state is restored.
|
||||
// `DcSctpSocketCallbacks::OnError` will be called on error.
|
||||
virtual void RestoreFromState(const DcSctpSocketHandoverState& state) = 0;
|
||||
|
||||
// Gracefully shutdowns the socket and sends all outstanding data. This is an
|
||||
// asynchronous operation and `DcSctpSocketCallbacks::OnClosed` will be called
|
||||
// on success.
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
// Closes the connection non-gracefully. Will send ABORT if the connection is
|
||||
// not already closed. No callbacks will be made after Close() has returned.
|
||||
virtual void Close() = 0;
|
||||
|
||||
// The socket state.
|
||||
virtual SocketState state() const = 0;
|
||||
|
||||
// The options it was created with.
|
||||
virtual const DcSctpOptions& options() const = 0;
|
||||
|
||||
// Update the options max_message_size.
|
||||
virtual void SetMaxMessageSize(size_t max_message_size) = 0;
|
||||
|
||||
// Sets the priority of an outgoing stream. The initial value, when not set,
|
||||
// is `DcSctpOptions::default_stream_priority`.
|
||||
virtual void SetStreamPriority(StreamID stream_id,
|
||||
StreamPriority priority) = 0;
|
||||
|
||||
// Returns the currently set priority for an outgoing stream. The initial
|
||||
// value, when not set, is `DcSctpOptions::default_stream_priority`.
|
||||
virtual StreamPriority GetStreamPriority(StreamID stream_id) const = 0;
|
||||
|
||||
// Sends the message `message` using the provided send options.
|
||||
// Sending a message is an asynchronous operation, and the `OnError` callback
|
||||
// may be invoked to indicate any errors in sending the message.
|
||||
//
|
||||
// The association does not have to be established before calling this method.
|
||||
// If it's called before there is an established association, the message will
|
||||
// be queued.
|
||||
virtual SendStatus Send(DcSctpMessage message,
|
||||
const SendOptions& send_options) = 0;
|
||||
|
||||
// Sends the messages `messages` using the provided send options.
|
||||
// Sending a message is an asynchronous operation, and the `OnError` callback
|
||||
// may be invoked to indicate any errors in sending the message.
|
||||
//
|
||||
// This has identical semantics to Send, except that it may coalesce many
|
||||
// messages into a single SCTP packet if they would fit.
|
||||
virtual std::vector<SendStatus> SendMany(
|
||||
rtc::ArrayView<DcSctpMessage> messages,
|
||||
const SendOptions& send_options) = 0;
|
||||
|
||||
// Resetting streams is an asynchronous operation and the results will
|
||||
// be notified using `DcSctpSocketCallbacks::OnStreamsResetDone()` on success
|
||||
// and `DcSctpSocketCallbacks::OnStreamsResetFailed()` on failure. Note that
|
||||
// only outgoing streams can be reset.
|
||||
//
|
||||
// When it's known that the peer has reset its own outgoing streams,
|
||||
// `DcSctpSocketCallbacks::OnIncomingStreamReset` is called.
|
||||
//
|
||||
// Note that resetting a stream will also remove all queued messages on those
|
||||
// streams, but will ensure that the currently sent message (if any) is fully
|
||||
// sent before closing the stream.
|
||||
//
|
||||
// Resetting streams can only be done on an established association that
|
||||
// supports stream resetting. Calling this method on e.g. a closed association
|
||||
// or streams that don't support resetting will not perform any operation.
|
||||
virtual ResetStreamsStatus ResetStreams(
|
||||
rtc::ArrayView<const StreamID> outgoing_streams) = 0;
|
||||
|
||||
// Returns the number of bytes of data currently queued to be sent on a given
|
||||
// stream.
|
||||
virtual size_t buffered_amount(StreamID stream_id) const = 0;
|
||||
|
||||
// Returns the number of buffered outgoing bytes that is considered "low" for
|
||||
// a given stream. See `SetBufferedAmountLowThreshold`.
|
||||
virtual size_t buffered_amount_low_threshold(StreamID stream_id) const = 0;
|
||||
|
||||
// Used to specify the number of bytes of buffered outgoing data that is
|
||||
// considered "low" for a given stream, which will trigger an
|
||||
// OnBufferedAmountLow event. The default value is zero (0).
|
||||
virtual void SetBufferedAmountLowThreshold(StreamID stream_id,
|
||||
size_t bytes) = 0;
|
||||
|
||||
// Retrieves the latest metrics. If the socket is not fully connected,
|
||||
// `absl::nullopt` will be returned. Note that metrics are not guaranteed to
|
||||
// be carried over if this socket is handed over by calling
|
||||
// `GetHandoverStateAndClose`.
|
||||
virtual absl::optional<Metrics> GetMetrics() const = 0;
|
||||
|
||||
// Returns empty bitmask if the socket is in the state in which a snapshot of
|
||||
// the state can be made by `GetHandoverStateAndClose()`. Return value is
|
||||
// invalidated by a call to any non-const method.
|
||||
virtual HandoverReadinessStatus GetHandoverReadiness() const = 0;
|
||||
|
||||
// Collects a snapshot of the socket state that can be used to reconstruct
|
||||
// this socket in another process. On success this socket object is closed
|
||||
// synchronously and no callbacks will be made after the method has returned.
|
||||
// The method fails if the socket is not in a state ready for handover.
|
||||
// nullopt indicates the failure. `DcSctpSocketCallbacks::OnClosed` will be
|
||||
// called on success.
|
||||
virtual absl::optional<DcSctpSocketHandoverState>
|
||||
GetHandoverStateAndClose() = 0;
|
||||
|
||||
// Returns the detected SCTP implementation of the peer. As this is not
|
||||
// explicitly signalled during the connection establishment, heuristics is
|
||||
// used to analyze e.g. the state cookie in the INIT-ACK chunk.
|
||||
//
|
||||
// If this method is called too early (before
|
||||
// `DcSctpSocketCallbacks::OnConnected` has triggered), this will likely
|
||||
// return `SctpImplementation::kUnknown`.
|
||||
ABSL_DEPRECATED("See Metrics::peer_implementation instead")
|
||||
virtual SctpImplementation peer_implementation() const {
|
||||
return SctpImplementation::kUnknown;
|
||||
}
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_DCSCTP_SOCKET_H_
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#include "net/dcsctp/public/dcsctp_socket_factory.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "net/dcsctp/public/dcsctp_options.h"
|
||||
#include "net/dcsctp/public/dcsctp_socket.h"
|
||||
#include "net/dcsctp/public/packet_observer.h"
|
||||
#include "net/dcsctp/socket/dcsctp_socket.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
DcSctpSocketFactory::~DcSctpSocketFactory() = default;
|
||||
|
||||
std::unique_ptr<DcSctpSocketInterface> DcSctpSocketFactory::Create(
|
||||
absl::string_view log_prefix,
|
||||
DcSctpSocketCallbacks& callbacks,
|
||||
std::unique_ptr<PacketObserver> packet_observer,
|
||||
const DcSctpOptions& options) {
|
||||
return std::make_unique<DcSctpSocket>(log_prefix, callbacks,
|
||||
std::move(packet_observer), options);
|
||||
}
|
||||
} // namespace dcsctp
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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_PUBLIC_DCSCTP_SOCKET_FACTORY_H_
|
||||
#define NET_DCSCTP_PUBLIC_DCSCTP_SOCKET_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "net/dcsctp/public/dcsctp_options.h"
|
||||
#include "net/dcsctp/public/dcsctp_socket.h"
|
||||
#include "net/dcsctp/public/packet_observer.h"
|
||||
|
||||
namespace dcsctp {
|
||||
class DcSctpSocketFactory {
|
||||
public:
|
||||
virtual ~DcSctpSocketFactory();
|
||||
virtual std::unique_ptr<DcSctpSocketInterface> Create(
|
||||
absl::string_view log_prefix,
|
||||
DcSctpSocketCallbacks& callbacks,
|
||||
std::unique_ptr<PacketObserver> packet_observer,
|
||||
const DcSctpOptions& options);
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_DCSCTP_SOCKET_FACTORY_H_
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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_PUBLIC_MOCK_DCSCTP_SOCKET_H_
|
||||
#define NET_DCSCTP_PUBLIC_MOCK_DCSCTP_SOCKET_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/public/dcsctp_socket.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
class MockDcSctpSocket : public DcSctpSocketInterface {
|
||||
public:
|
||||
MOCK_METHOD(void,
|
||||
ReceivePacket,
|
||||
(rtc::ArrayView<const uint8_t> data),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, HandleTimeout, (TimeoutID timeout_id), (override));
|
||||
|
||||
MOCK_METHOD(void, Connect, (), (override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
RestoreFromState,
|
||||
(const DcSctpSocketHandoverState&),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, Shutdown, (), (override));
|
||||
|
||||
MOCK_METHOD(void, Close, (), (override));
|
||||
|
||||
MOCK_METHOD(SocketState, state, (), (const, override));
|
||||
|
||||
MOCK_METHOD(const DcSctpOptions&, options, (), (const, override));
|
||||
|
||||
MOCK_METHOD(void, SetMaxMessageSize, (size_t max_message_size), (override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
SetStreamPriority,
|
||||
(StreamID stream_id, StreamPriority priority),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(StreamPriority,
|
||||
GetStreamPriority,
|
||||
(StreamID stream_id),
|
||||
(const, override));
|
||||
|
||||
MOCK_METHOD(SendStatus,
|
||||
Send,
|
||||
(DcSctpMessage message, const SendOptions& send_options),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(std::vector<SendStatus>,
|
||||
SendMany,
|
||||
(rtc::ArrayView<DcSctpMessage> messages,
|
||||
const SendOptions& send_options),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(ResetStreamsStatus,
|
||||
ResetStreams,
|
||||
(rtc::ArrayView<const StreamID> outgoing_streams),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(size_t, buffered_amount, (StreamID stream_id), (const, override));
|
||||
|
||||
MOCK_METHOD(size_t,
|
||||
buffered_amount_low_threshold,
|
||||
(StreamID stream_id),
|
||||
(const, override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
SetBufferedAmountLowThreshold,
|
||||
(StreamID stream_id, size_t bytes),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(absl::optional<Metrics>, GetMetrics, (), (const, override));
|
||||
|
||||
MOCK_METHOD(HandoverReadinessStatus,
|
||||
GetHandoverReadiness,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(absl::optional<DcSctpSocketHandoverState>,
|
||||
GetHandoverStateAndClose,
|
||||
(),
|
||||
(override));
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_MOCK_DCSCTP_SOCKET_H_
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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_PUBLIC_MOCK_DCSCTP_SOCKET_FACTORY_H_
|
||||
#define NET_DCSCTP_PUBLIC_MOCK_DCSCTP_SOCKET_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "net/dcsctp/public/dcsctp_socket_factory.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
class MockDcSctpSocketFactory : public DcSctpSocketFactory {
|
||||
public:
|
||||
MOCK_METHOD(std::unique_ptr<DcSctpSocketInterface>,
|
||||
Create,
|
||||
(absl::string_view log_prefix,
|
||||
DcSctpSocketCallbacks& callbacks,
|
||||
std::unique_ptr<PacketObserver> packet_observer,
|
||||
const DcSctpOptions& options),
|
||||
(override));
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_MOCK_DCSCTP_SOCKET_FACTORY_H_
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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_PUBLIC_PACKET_OBSERVER_H_
|
||||
#define NET_DCSCTP_PUBLIC_PACKET_OBSERVER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/public/types.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// A PacketObserver can be attached to a socket and will be called for
|
||||
// all sent and received packets.
|
||||
class PacketObserver {
|
||||
public:
|
||||
virtual ~PacketObserver() = default;
|
||||
// Called when a packet is sent, with the current time (in milliseconds) as
|
||||
// `now`, and the packet payload as `payload`.
|
||||
virtual void OnSentPacket(TimeMs now,
|
||||
rtc::ArrayView<const uint8_t> payload) = 0;
|
||||
|
||||
// Called when a packet is received, with the current time (in milliseconds)
|
||||
// as `now`, and the packet payload as `payload`.
|
||||
virtual void OnReceivedPacket(TimeMs now,
|
||||
rtc::ArrayView<const uint8_t> payload) = 0;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_PACKET_OBSERVER_H_
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include "net/dcsctp/public/text_pcap_packet_observer.h"
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/public/types.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
void TextPcapPacketObserver::OnSentPacket(
|
||||
dcsctp::TimeMs now,
|
||||
rtc::ArrayView<const uint8_t> payload) {
|
||||
PrintPacket("O ", name_, now, payload);
|
||||
}
|
||||
|
||||
void TextPcapPacketObserver::OnReceivedPacket(
|
||||
dcsctp::TimeMs now,
|
||||
rtc::ArrayView<const uint8_t> payload) {
|
||||
PrintPacket("I ", name_, now, payload);
|
||||
}
|
||||
|
||||
void TextPcapPacketObserver::PrintPacket(
|
||||
absl::string_view prefix,
|
||||
absl::string_view socket_name,
|
||||
dcsctp::TimeMs now,
|
||||
rtc::ArrayView<const uint8_t> payload) {
|
||||
rtc::StringBuilder s;
|
||||
s << "\n" << prefix;
|
||||
int64_t remaining = *now % (24 * 60 * 60 * 1000);
|
||||
int hours = remaining / (60 * 60 * 1000);
|
||||
remaining = remaining % (60 * 60 * 1000);
|
||||
int minutes = remaining / (60 * 1000);
|
||||
remaining = remaining % (60 * 1000);
|
||||
int seconds = remaining / 1000;
|
||||
int ms = remaining % 1000;
|
||||
s.AppendFormat("%02d:%02d:%02d.%03d", hours, minutes, seconds, ms);
|
||||
s << " 0000";
|
||||
for (uint8_t byte : payload) {
|
||||
s.AppendFormat(" %02x", byte);
|
||||
}
|
||||
s << " # SCTP_PACKET " << socket_name;
|
||||
RTC_LOG(LS_VERBOSE) << s.str();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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_PUBLIC_TEXT_PCAP_PACKET_OBSERVER_H_
|
||||
#define NET_DCSCTP_PUBLIC_TEXT_PCAP_PACKET_OBSERVER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/public/packet_observer.h"
|
||||
#include "net/dcsctp/public/types.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// Print outs all sent and received packets to the logs, at LS_VERBOSE severity.
|
||||
class TextPcapPacketObserver : public dcsctp::PacketObserver {
|
||||
public:
|
||||
explicit TextPcapPacketObserver(absl::string_view name) : name_(name) {}
|
||||
|
||||
// Implementation of `dcsctp::PacketObserver`.
|
||||
void OnSentPacket(dcsctp::TimeMs now,
|
||||
rtc::ArrayView<const uint8_t> payload) override;
|
||||
|
||||
void OnReceivedPacket(dcsctp::TimeMs now,
|
||||
rtc::ArrayView<const uint8_t> payload) override;
|
||||
|
||||
// Prints a packet to the log. Exposed to allow it to be used in compatibility
|
||||
// tests suites that don't use PacketObserver.
|
||||
static void PrintPacket(absl::string_view prefix,
|
||||
absl::string_view socket_name,
|
||||
dcsctp::TimeMs now,
|
||||
rtc::ArrayView<const uint8_t> payload);
|
||||
|
||||
private:
|
||||
const std::string name_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
#endif // NET_DCSCTP_PUBLIC_TEXT_PCAP_PACKET_OBSERVER_H_
|
||||
53
TMessagesProj/jni/voip/webrtc/net/dcsctp/public/timeout.h
Normal file
53
TMessagesProj/jni/voip/webrtc/net/dcsctp/public/timeout.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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_PUBLIC_TIMEOUT_H_
|
||||
#define NET_DCSCTP_PUBLIC_TIMEOUT_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "net/dcsctp/public/types.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// A very simple timeout that can be started and stopped. When started,
|
||||
// it will be given a unique `timeout_id` which should be provided to
|
||||
// `DcSctpSocket::HandleTimeout` when it expires.
|
||||
class Timeout {
|
||||
public:
|
||||
virtual ~Timeout() = default;
|
||||
|
||||
// Called to start time timeout, with the duration in milliseconds as
|
||||
// `duration` and with the timeout identifier as `timeout_id`, which - if
|
||||
// the timeout expires - shall be provided to `DcSctpSocket::HandleTimeout`.
|
||||
//
|
||||
// `Start` and `Stop` will always be called in pairs. In other words will
|
||||
// ´Start` never be called twice, without a call to `Stop` in between.
|
||||
virtual void Start(DurationMs duration, TimeoutID timeout_id) = 0;
|
||||
|
||||
// Called to stop the running timeout.
|
||||
//
|
||||
// `Start` and `Stop` will always be called in pairs. In other words will
|
||||
// ´Start` never be called twice, without a call to `Stop` in between.
|
||||
//
|
||||
// `Stop` will always be called prior to releasing this object.
|
||||
virtual void Stop() = 0;
|
||||
|
||||
// Called to restart an already running timeout, with the `duration` and
|
||||
// `timeout_id` parameters as described in `Start`. This can be overridden by
|
||||
// the implementation to restart it more efficiently.
|
||||
virtual void Restart(DurationMs duration, TimeoutID timeout_id) {
|
||||
Stop();
|
||||
Start(duration, timeout_id);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_TIMEOUT_H_
|
||||
177
TMessagesProj/jni/voip/webrtc/net/dcsctp/public/types.h
Normal file
177
TMessagesProj/jni/voip/webrtc/net/dcsctp/public/types.h
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
* 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_PUBLIC_TYPES_H_
|
||||
#define NET_DCSCTP_PUBLIC_TYPES_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#include "api/units/time_delta.h"
|
||||
#include "rtc_base/strong_alias.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// Stream Identifier
|
||||
using StreamID = webrtc::StrongAlias<class StreamIDTag, uint16_t>;
|
||||
|
||||
// Payload Protocol Identifier (PPID)
|
||||
using PPID = webrtc::StrongAlias<class PPIDTag, uint32_t>;
|
||||
|
||||
// Timeout Identifier
|
||||
using TimeoutID = webrtc::StrongAlias<class TimeoutTag, uint64_t>;
|
||||
|
||||
// Indicates if a message is allowed to be received out-of-order compared to
|
||||
// other messages on the same stream.
|
||||
using IsUnordered = webrtc::StrongAlias<class IsUnorderedTag, bool>;
|
||||
|
||||
// Stream priority, where higher values indicate higher priority. The meaning of
|
||||
// this value and how it's used depends on the stream scheduler.
|
||||
using StreamPriority = webrtc::StrongAlias<class StreamPriorityTag, uint16_t>;
|
||||
|
||||
// Duration, as milliseconds. Overflows after 24 days.
|
||||
class DurationMs : public webrtc::StrongAlias<class DurationMsTag, int32_t> {
|
||||
public:
|
||||
constexpr explicit DurationMs(const UnderlyingType& v)
|
||||
: webrtc::StrongAlias<class DurationMsTag, int32_t>(v) {}
|
||||
|
||||
constexpr explicit DurationMs(webrtc::TimeDelta v)
|
||||
: webrtc::StrongAlias<class DurationMsTag, int32_t>(
|
||||
v.IsInfinite() ? InfiniteDuration() : DurationMs(v.ms())) {}
|
||||
|
||||
static constexpr DurationMs InfiniteDuration() {
|
||||
return DurationMs(std::numeric_limits<int32_t>::max());
|
||||
}
|
||||
// Convenience methods for working with time.
|
||||
constexpr DurationMs& operator+=(DurationMs d) {
|
||||
value_ += d.value_;
|
||||
return *this;
|
||||
}
|
||||
constexpr DurationMs& operator-=(DurationMs d) {
|
||||
value_ -= d.value_;
|
||||
return *this;
|
||||
}
|
||||
template <typename T>
|
||||
constexpr DurationMs& operator*=(T factor) {
|
||||
value_ *= factor;
|
||||
return *this;
|
||||
}
|
||||
constexpr webrtc::TimeDelta ToTimeDelta() const {
|
||||
return *this == DurationMs::InfiniteDuration()
|
||||
? webrtc::TimeDelta::PlusInfinity()
|
||||
: webrtc::TimeDelta::Millis(value_);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr inline DurationMs operator+(DurationMs lhs, DurationMs rhs) {
|
||||
return lhs += rhs;
|
||||
}
|
||||
constexpr inline DurationMs operator-(DurationMs lhs, DurationMs rhs) {
|
||||
return lhs -= rhs;
|
||||
}
|
||||
template <typename T>
|
||||
constexpr inline DurationMs operator*(DurationMs lhs, T rhs) {
|
||||
return lhs *= rhs;
|
||||
}
|
||||
template <typename T>
|
||||
constexpr inline DurationMs operator*(T lhs, DurationMs rhs) {
|
||||
return rhs *= lhs;
|
||||
}
|
||||
constexpr inline int32_t operator/(DurationMs lhs, DurationMs rhs) {
|
||||
return lhs.value() / rhs.value();
|
||||
}
|
||||
|
||||
// Represents time, in milliseconds since a client-defined epoch.
|
||||
class TimeMs : public webrtc::StrongAlias<class TimeMsTag, int64_t> {
|
||||
public:
|
||||
constexpr explicit TimeMs(const UnderlyingType& v)
|
||||
: webrtc::StrongAlias<class TimeMsTag, int64_t>(v) {}
|
||||
|
||||
// Convenience methods for working with time.
|
||||
constexpr TimeMs& operator+=(DurationMs d) {
|
||||
value_ += *d;
|
||||
return *this;
|
||||
}
|
||||
constexpr TimeMs& operator-=(DurationMs d) {
|
||||
value_ -= *d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static constexpr TimeMs InfiniteFuture() {
|
||||
return TimeMs(std::numeric_limits<int64_t>::max());
|
||||
}
|
||||
};
|
||||
|
||||
constexpr inline TimeMs operator+(TimeMs lhs, DurationMs rhs) {
|
||||
return lhs += rhs;
|
||||
}
|
||||
constexpr inline TimeMs operator+(DurationMs lhs, TimeMs rhs) {
|
||||
return rhs += lhs;
|
||||
}
|
||||
constexpr inline TimeMs operator-(TimeMs lhs, DurationMs rhs) {
|
||||
return lhs -= rhs;
|
||||
}
|
||||
constexpr inline DurationMs operator-(TimeMs lhs, TimeMs rhs) {
|
||||
return DurationMs(*lhs - *rhs);
|
||||
}
|
||||
|
||||
// The maximum number of times the socket should attempt to retransmit a
|
||||
// message which fails the first time in unreliable mode.
|
||||
class MaxRetransmits
|
||||
: public webrtc::StrongAlias<class MaxRetransmitsTag, uint16_t> {
|
||||
public:
|
||||
constexpr explicit MaxRetransmits(const UnderlyingType& v)
|
||||
: webrtc::StrongAlias<class MaxRetransmitsTag, uint16_t>(v) {}
|
||||
|
||||
// There should be no limit - the message should be sent reliably.
|
||||
static constexpr MaxRetransmits NoLimit() {
|
||||
return MaxRetransmits(std::numeric_limits<uint16_t>::max());
|
||||
}
|
||||
};
|
||||
|
||||
// An identifier that can be set on sent messages, and picked by the sending
|
||||
// client. If different from `::NotSet()`, lifecycle events will be generated,
|
||||
// and eventually `DcSctpSocketCallbacks::OnLifecycleEnd` will be called to
|
||||
// indicate that the lifecycle isn't tracked any longer. The value zero (0) is
|
||||
// not a valid lifecycle identifier, and will be interpreted as not having it
|
||||
// set.
|
||||
class LifecycleId : public webrtc::StrongAlias<class LifecycleIdTag, uint64_t> {
|
||||
public:
|
||||
constexpr explicit LifecycleId(const UnderlyingType& v)
|
||||
: webrtc::StrongAlias<class LifecycleIdTag, uint64_t>(v) {}
|
||||
|
||||
constexpr bool IsSet() const { return value_ != 0; }
|
||||
|
||||
static constexpr LifecycleId NotSet() { return LifecycleId(0); }
|
||||
};
|
||||
|
||||
// To enable zero checksum feature, both peers must agree on which alternate
|
||||
// error detection method that is used. See
|
||||
// https://www.ietf.org/archive/id/draft-ietf-tsvwg-sctp-zero-checksum-06.html.
|
||||
class ZeroChecksumAlternateErrorDetectionMethod
|
||||
: public webrtc::StrongAlias<
|
||||
class ZeroChecksumAlternateErrorDetectionMethodTag,
|
||||
uint32_t> {
|
||||
public:
|
||||
constexpr explicit ZeroChecksumAlternateErrorDetectionMethod(
|
||||
const UnderlyingType& v)
|
||||
: webrtc::StrongAlias<class ZeroChecksumAlternateErrorDetectionMethodTag,
|
||||
uint32_t>(v) {}
|
||||
|
||||
static constexpr ZeroChecksumAlternateErrorDetectionMethod None() {
|
||||
return ZeroChecksumAlternateErrorDetectionMethod(0);
|
||||
}
|
||||
static constexpr ZeroChecksumAlternateErrorDetectionMethod LowerLayerDtls() {
|
||||
return ZeroChecksumAlternateErrorDetectionMethod(1);
|
||||
}
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PUBLIC_TYPES_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue