summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h')
-rw-r--r--third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h193
1 files changed, 193 insertions, 0 deletions
diff --git a/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h b/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h
new file mode 100644
index 0000000000..8e0e9a3ec5
--- /dev/null
+++ b/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h
@@ -0,0 +1,193 @@
+/*
+ * 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_SOCKET_TRANSMISSION_CONTROL_BLOCK_H_
+#define NET_DCSCTP_SOCKET_TRANSMISSION_CONTROL_BLOCK_H_
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/functional/bind_front.h"
+#include "absl/strings/string_view.h"
+#include "api/task_queue/task_queue_base.h"
+#include "net/dcsctp/common/sequence_numbers.h"
+#include "net/dcsctp/packet/chunk/cookie_echo_chunk.h"
+#include "net/dcsctp/packet/sctp_packet.h"
+#include "net/dcsctp/public/dcsctp_options.h"
+#include "net/dcsctp/public/dcsctp_socket.h"
+#include "net/dcsctp/rx/data_tracker.h"
+#include "net/dcsctp/rx/reassembly_queue.h"
+#include "net/dcsctp/socket/capabilities.h"
+#include "net/dcsctp/socket/context.h"
+#include "net/dcsctp/socket/heartbeat_handler.h"
+#include "net/dcsctp/socket/packet_sender.h"
+#include "net/dcsctp/socket/stream_reset_handler.h"
+#include "net/dcsctp/timer/timer.h"
+#include "net/dcsctp/tx/retransmission_error_counter.h"
+#include "net/dcsctp/tx/retransmission_queue.h"
+#include "net/dcsctp/tx/retransmission_timeout.h"
+#include "net/dcsctp/tx/send_queue.h"
+
+namespace dcsctp {
+
+// The TransmissionControlBlock (TCB) represents an open connection to a peer,
+// and holds all the resources for that. If the connection is e.g. shutdown,
+// closed or restarted, this object will be deleted and/or replaced.
+class TransmissionControlBlock : public Context {
+ public:
+ TransmissionControlBlock(TimerManager& timer_manager,
+ absl::string_view log_prefix,
+ const DcSctpOptions& options,
+ const Capabilities& capabilities,
+ DcSctpSocketCallbacks& callbacks,
+ SendQueue& send_queue,
+ VerificationTag my_verification_tag,
+ TSN my_initial_tsn,
+ VerificationTag peer_verification_tag,
+ TSN peer_initial_tsn,
+ size_t a_rwnd,
+ TieTag tie_tag,
+ PacketSender& packet_sender,
+ std::function<bool()> is_connection_established);
+
+ // Implementation of `Context`.
+ bool is_connection_established() const override {
+ return is_connection_established_();
+ }
+ TSN my_initial_tsn() const override { return my_initial_tsn_; }
+ TSN peer_initial_tsn() const override { return peer_initial_tsn_; }
+ DcSctpSocketCallbacks& callbacks() const override { return callbacks_; }
+ void ObserveRTT(DurationMs rtt) override;
+ DurationMs current_rto() const override { return rto_.rto(); }
+ bool IncrementTxErrorCounter(absl::string_view reason) override {
+ return tx_error_counter_.Increment(reason);
+ }
+ void ClearTxErrorCounter() override { tx_error_counter_.Clear(); }
+ SctpPacket::Builder PacketBuilder() const override {
+ return SctpPacket::Builder(peer_verification_tag_, options_);
+ }
+ bool HasTooManyTxErrors() const override {
+ return tx_error_counter_.IsExhausted();
+ }
+ void Send(SctpPacket::Builder& builder) override {
+ packet_sender_.Send(builder);
+ }
+
+ // Other accessors
+ DataTracker& data_tracker() { return data_tracker_; }
+ ReassemblyQueue& reassembly_queue() { return reassembly_queue_; }
+ RetransmissionQueue& retransmission_queue() { return retransmission_queue_; }
+ StreamResetHandler& stream_reset_handler() { return stream_reset_handler_; }
+ HeartbeatHandler& heartbeat_handler() { return heartbeat_handler_; }
+ size_t cwnd() const { return retransmission_queue_.cwnd(); }
+ DurationMs current_srtt() const { return rto_.srtt(); }
+
+ // Returns this socket's verification tag, set in all packet headers.
+ VerificationTag my_verification_tag() const { return my_verification_tag_; }
+ // Returns the peer's verification tag, which should be in received packets.
+ VerificationTag peer_verification_tag() const {
+ return peer_verification_tag_;
+ }
+ // All negotiated supported capabilities.
+ const Capabilities& capabilities() const { return capabilities_; }
+ // A 64-bit tie-tag, used to e.g. detect reconnections.
+ TieTag tie_tag() const { return tie_tag_; }
+
+ // Sends a SACK, if there is a need to.
+ void MaybeSendSack();
+
+ // Sends a FORWARD-TSN, if it is needed and allowed (rate-limited).
+ void MaybeSendForwardTsn(SctpPacket::Builder& builder, TimeMs now);
+
+ // Will be set while the socket is in kCookieEcho state. In this state, there
+ // can only be a single packet outstanding, and it must contain the COOKIE
+ // ECHO chunk as the first chunk in that packet, until the COOKIE ACK has been
+ // received, which will make the socket call `ClearCookieEchoChunk`.
+ void SetCookieEchoChunk(CookieEchoChunk chunk) {
+ cookie_echo_chunk_ = std::move(chunk);
+ }
+
+ // Called when the COOKIE ACK chunk has been received, to allow further
+ // packets to be sent.
+ void ClearCookieEchoChunk() { cookie_echo_chunk_ = absl::nullopt; }
+
+ bool has_cookie_echo_chunk() const { return cookie_echo_chunk_.has_value(); }
+
+ void MaybeSendFastRetransmit();
+
+ // Fills `builder` (which may already be filled with control chunks) with
+ // other control and data chunks, and sends packets as much as can be
+ // allowed by the congestion control algorithm.
+ void SendBufferedPackets(SctpPacket::Builder& builder, TimeMs now);
+
+ // As above, but without passing in a builder. If `cookie_echo_chunk_` is
+ // present, then only one packet will be sent, with this chunk as the first
+ // chunk.
+ void SendBufferedPackets(TimeMs now) {
+ SctpPacket::Builder builder(peer_verification_tag_, options_);
+ SendBufferedPackets(builder, now);
+ }
+
+ // Returns a textual representation of this object, for logging.
+ std::string ToString() const;
+
+ HandoverReadinessStatus GetHandoverReadiness() const;
+
+ void AddHandoverState(DcSctpSocketHandoverState& state);
+ void RestoreFromState(const DcSctpSocketHandoverState& handover_state);
+
+ private:
+ // Will be called when the retransmission timer (t3-rtx) expires.
+ absl::optional<DurationMs> OnRtxTimerExpiry();
+ // Will be called when the delayed ack timer expires.
+ absl::optional<DurationMs> OnDelayedAckTimerExpiry();
+
+ const std::string log_prefix_;
+ const DcSctpOptions options_;
+ TimerManager& timer_manager_;
+ // Negotiated capabilities that both peers support.
+ const Capabilities capabilities_;
+ DcSctpSocketCallbacks& callbacks_;
+ // The data retransmission timer, called t3-rtx in SCTP.
+ const std::unique_ptr<Timer> t3_rtx_;
+ // Delayed ack timer, which triggers when acks should be sent (when delayed).
+ const std::unique_ptr<Timer> delayed_ack_timer_;
+ const VerificationTag my_verification_tag_;
+ const TSN my_initial_tsn_;
+ const VerificationTag peer_verification_tag_;
+ const TSN peer_initial_tsn_;
+ // Nonce, used to detect reconnections.
+ const TieTag tie_tag_;
+ const std::function<bool()> is_connection_established_;
+ PacketSender& packet_sender_;
+ // Rate limiting of FORWARD-TSN. Next can be sent at or after this timestamp.
+ TimeMs limit_forward_tsn_until_ = TimeMs(0);
+
+ RetransmissionTimeout rto_;
+ RetransmissionErrorCounter tx_error_counter_;
+ DataTracker data_tracker_;
+ ReassemblyQueue reassembly_queue_;
+ RetransmissionQueue retransmission_queue_;
+ StreamResetHandler stream_reset_handler_;
+ HeartbeatHandler heartbeat_handler_;
+
+ // Only valid when the socket state == State::kCookieEchoed. In this state,
+ // the socket must wait for COOKIE ACK to continue sending any packets (not
+ // including a COOKIE ECHO). So if `cookie_echo_chunk_` is present, the
+ // SendBufferedChunks will always only just send one packet, with this chunk
+ // as the first chunk in the packet.
+ absl::optional<CookieEchoChunk> cookie_echo_chunk_ = absl::nullopt;
+};
+} // namespace dcsctp
+
+#endif // NET_DCSCTP_SOCKET_TRANSMISSION_CONTROL_BLOCK_H_