xref: /aosp_15_r20/external/webrtc/net/dcsctp/socket/transmission_control_block.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #ifndef NET_DCSCTP_SOCKET_TRANSMISSION_CONTROL_BLOCK_H_
11 #define NET_DCSCTP_SOCKET_TRANSMISSION_CONTROL_BLOCK_H_
12 
13 #include <cstdint>
14 #include <functional>
15 #include <memory>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include "absl/functional/bind_front.h"
21 #include "absl/strings/string_view.h"
22 #include "api/task_queue/task_queue_base.h"
23 #include "net/dcsctp/common/sequence_numbers.h"
24 #include "net/dcsctp/packet/chunk/cookie_echo_chunk.h"
25 #include "net/dcsctp/packet/sctp_packet.h"
26 #include "net/dcsctp/public/dcsctp_options.h"
27 #include "net/dcsctp/public/dcsctp_socket.h"
28 #include "net/dcsctp/rx/data_tracker.h"
29 #include "net/dcsctp/rx/reassembly_queue.h"
30 #include "net/dcsctp/socket/capabilities.h"
31 #include "net/dcsctp/socket/context.h"
32 #include "net/dcsctp/socket/heartbeat_handler.h"
33 #include "net/dcsctp/socket/packet_sender.h"
34 #include "net/dcsctp/socket/stream_reset_handler.h"
35 #include "net/dcsctp/timer/timer.h"
36 #include "net/dcsctp/tx/retransmission_error_counter.h"
37 #include "net/dcsctp/tx/retransmission_queue.h"
38 #include "net/dcsctp/tx/retransmission_timeout.h"
39 #include "net/dcsctp/tx/send_queue.h"
40 
41 namespace dcsctp {
42 
43 // The TransmissionControlBlock (TCB) represents an open connection to a peer,
44 // and holds all the resources for that. If the connection is e.g. shutdown,
45 // closed or restarted, this object will be deleted and/or replaced.
46 class TransmissionControlBlock : public Context {
47  public:
48   TransmissionControlBlock(TimerManager& timer_manager,
49                            absl::string_view log_prefix,
50                            const DcSctpOptions& options,
51                            const Capabilities& capabilities,
52                            DcSctpSocketCallbacks& callbacks,
53                            SendQueue& send_queue,
54                            VerificationTag my_verification_tag,
55                            TSN my_initial_tsn,
56                            VerificationTag peer_verification_tag,
57                            TSN peer_initial_tsn,
58                            size_t a_rwnd,
59                            TieTag tie_tag,
60                            PacketSender& packet_sender,
61                            std::function<bool()> is_connection_established);
62 
63   // Implementation of `Context`.
is_connection_established()64   bool is_connection_established() const override {
65     return is_connection_established_();
66   }
my_initial_tsn()67   TSN my_initial_tsn() const override { return my_initial_tsn_; }
peer_initial_tsn()68   TSN peer_initial_tsn() const override { return peer_initial_tsn_; }
callbacks()69   DcSctpSocketCallbacks& callbacks() const override { return callbacks_; }
70   void ObserveRTT(DurationMs rtt) override;
current_rto()71   DurationMs current_rto() const override { return rto_.rto(); }
IncrementTxErrorCounter(absl::string_view reason)72   bool IncrementTxErrorCounter(absl::string_view reason) override {
73     return tx_error_counter_.Increment(reason);
74   }
ClearTxErrorCounter()75   void ClearTxErrorCounter() override { tx_error_counter_.Clear(); }
PacketBuilder()76   SctpPacket::Builder PacketBuilder() const override {
77     return SctpPacket::Builder(peer_verification_tag_, options_);
78   }
HasTooManyTxErrors()79   bool HasTooManyTxErrors() const override {
80     return tx_error_counter_.IsExhausted();
81   }
Send(SctpPacket::Builder & builder)82   void Send(SctpPacket::Builder& builder) override {
83     packet_sender_.Send(builder);
84   }
85 
86   // Other accessors
data_tracker()87   DataTracker& data_tracker() { return data_tracker_; }
reassembly_queue()88   ReassemblyQueue& reassembly_queue() { return reassembly_queue_; }
retransmission_queue()89   RetransmissionQueue& retransmission_queue() { return retransmission_queue_; }
stream_reset_handler()90   StreamResetHandler& stream_reset_handler() { return stream_reset_handler_; }
heartbeat_handler()91   HeartbeatHandler& heartbeat_handler() { return heartbeat_handler_; }
cwnd()92   size_t cwnd() const { return retransmission_queue_.cwnd(); }
current_srtt()93   DurationMs current_srtt() const { return rto_.srtt(); }
94 
95   // Returns this socket's verification tag, set in all packet headers.
my_verification_tag()96   VerificationTag my_verification_tag() const { return my_verification_tag_; }
97   // Returns the peer's verification tag, which should be in received packets.
peer_verification_tag()98   VerificationTag peer_verification_tag() const {
99     return peer_verification_tag_;
100   }
101   // All negotiated supported capabilities.
capabilities()102   const Capabilities& capabilities() const { return capabilities_; }
103   // A 64-bit tie-tag, used to e.g. detect reconnections.
tie_tag()104   TieTag tie_tag() const { return tie_tag_; }
105 
106   // Sends a SACK, if there is a need to.
107   void MaybeSendSack();
108 
109   // Sends a FORWARD-TSN, if it is needed and allowed (rate-limited).
110   void MaybeSendForwardTsn(SctpPacket::Builder& builder, TimeMs now);
111 
112   // Will be set while the socket is in kCookieEcho state. In this state, there
113   // can only be a single packet outstanding, and it must contain the COOKIE
114   // ECHO chunk as the first chunk in that packet, until the COOKIE ACK has been
115   // received, which will make the socket call `ClearCookieEchoChunk`.
SetCookieEchoChunk(CookieEchoChunk chunk)116   void SetCookieEchoChunk(CookieEchoChunk chunk) {
117     cookie_echo_chunk_ = std::move(chunk);
118   }
119 
120   // Called when the COOKIE ACK chunk has been received, to allow further
121   // packets to be sent.
ClearCookieEchoChunk()122   void ClearCookieEchoChunk() { cookie_echo_chunk_ = absl::nullopt; }
123 
has_cookie_echo_chunk()124   bool has_cookie_echo_chunk() const { return cookie_echo_chunk_.has_value(); }
125 
126   void MaybeSendFastRetransmit();
127 
128   // Fills `builder` (which may already be filled with control chunks) with
129   // other control and data chunks, and sends packets as much as can be
130   // allowed by the congestion control algorithm.
131   void SendBufferedPackets(SctpPacket::Builder& builder, TimeMs now);
132 
133   // As above, but without passing in a builder. If `cookie_echo_chunk_` is
134   // present, then only one packet will be sent, with this chunk as the first
135   // chunk.
SendBufferedPackets(TimeMs now)136   void SendBufferedPackets(TimeMs now) {
137     SctpPacket::Builder builder(peer_verification_tag_, options_);
138     SendBufferedPackets(builder, now);
139   }
140 
141   // Returns a textual representation of this object, for logging.
142   std::string ToString() const;
143 
144   HandoverReadinessStatus GetHandoverReadiness() const;
145 
146   void AddHandoverState(DcSctpSocketHandoverState& state);
147   void RestoreFromState(const DcSctpSocketHandoverState& handover_state);
148 
149  private:
150   // Will be called when the retransmission timer (t3-rtx) expires.
151   absl::optional<DurationMs> OnRtxTimerExpiry();
152   // Will be called when the delayed ack timer expires.
153   absl::optional<DurationMs> OnDelayedAckTimerExpiry();
154 
155   const std::string log_prefix_;
156   const DcSctpOptions options_;
157   TimerManager& timer_manager_;
158   // Negotiated capabilities that both peers support.
159   const Capabilities capabilities_;
160   DcSctpSocketCallbacks& callbacks_;
161   // The data retransmission timer, called t3-rtx in SCTP.
162   const std::unique_ptr<Timer> t3_rtx_;
163   // Delayed ack timer, which triggers when acks should be sent (when delayed).
164   const std::unique_ptr<Timer> delayed_ack_timer_;
165   const VerificationTag my_verification_tag_;
166   const TSN my_initial_tsn_;
167   const VerificationTag peer_verification_tag_;
168   const TSN peer_initial_tsn_;
169   // Nonce, used to detect reconnections.
170   const TieTag tie_tag_;
171   const std::function<bool()> is_connection_established_;
172   PacketSender& packet_sender_;
173   // Rate limiting of FORWARD-TSN. Next can be sent at or after this timestamp.
174   TimeMs limit_forward_tsn_until_ = TimeMs(0);
175 
176   RetransmissionTimeout rto_;
177   RetransmissionErrorCounter tx_error_counter_;
178   DataTracker data_tracker_;
179   ReassemblyQueue reassembly_queue_;
180   RetransmissionQueue retransmission_queue_;
181   StreamResetHandler stream_reset_handler_;
182   HeartbeatHandler heartbeat_handler_;
183 
184   // Only valid when the socket state == State::kCookieEchoed. In this state,
185   // the socket must wait for COOKIE ACK to continue sending any packets (not
186   // including a COOKIE ECHO). So if `cookie_echo_chunk_` is present, the
187   // SendBufferedChunks will always only just send one packet, with this chunk
188   // as the first chunk in the packet.
189   absl::optional<CookieEchoChunk> cookie_echo_chunk_ = absl::nullopt;
190 };
191 }  // namespace dcsctp
192 
193 #endif  // NET_DCSCTP_SOCKET_TRANSMISSION_CONTROL_BLOCK_H_
194