xref: /aosp_15_r20/external/webrtc/pc/sctp_data_channel.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2020 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 
11 #ifndef PC_SCTP_DATA_CHANNEL_H_
12 #define PC_SCTP_DATA_CHANNEL_H_
13 
14 #include <stdint.h>
15 
16 #include <memory>
17 #include <set>
18 #include <string>
19 
20 #include "absl/types/optional.h"
21 #include "api/data_channel_interface.h"
22 #include "api/priority.h"
23 #include "api/rtc_error.h"
24 #include "api/scoped_refptr.h"
25 #include "api/transport/data_channel_transport_interface.h"
26 #include "media/base/media_channel.h"
27 #include "pc/data_channel_utils.h"
28 #include "rtc_base/copy_on_write_buffer.h"
29 #include "rtc_base/ssl_stream_adapter.h"  // For SSLRole
30 #include "rtc_base/third_party/sigslot/sigslot.h"
31 #include "rtc_base/thread.h"
32 #include "rtc_base/thread_annotations.h"
33 
34 namespace webrtc {
35 
36 class SctpDataChannel;
37 
38 // TODO(deadbeef): Get rid of this and have SctpDataChannel depend on
39 // SctpTransportInternal (pure virtual SctpTransport interface) instead.
40 class SctpDataChannelControllerInterface {
41  public:
42   // Sends the data to the transport.
43   virtual bool SendData(int sid,
44                         const SendDataParams& params,
45                         const rtc::CopyOnWriteBuffer& payload,
46                         cricket::SendDataResult* result) = 0;
47   // Connects to the transport signals.
48   virtual bool ConnectDataChannel(SctpDataChannel* data_channel) = 0;
49   // Disconnects from the transport signals.
50   virtual void DisconnectDataChannel(SctpDataChannel* data_channel) = 0;
51   // Adds the data channel SID to the transport for SCTP.
52   virtual void AddSctpDataStream(int sid) = 0;
53   // Begins the closing procedure by sending an outgoing stream reset. Still
54   // need to wait for callbacks to tell when this completes.
55   virtual void RemoveSctpDataStream(int sid) = 0;
56   // Returns true if the transport channel is ready to send data.
57   virtual bool ReadyToSendData() const = 0;
58 
59  protected:
~SctpDataChannelControllerInterface()60   virtual ~SctpDataChannelControllerInterface() {}
61 };
62 
63 // TODO(tommi): Change to not inherit from DataChannelInit but to have it as
64 // a const member. Block access to the 'id' member since it cannot be const.
65 struct InternalDataChannelInit : public DataChannelInit {
66   enum OpenHandshakeRole { kOpener, kAcker, kNone };
67   // The default role is kOpener because the default `negotiated` is false.
InternalDataChannelInitInternalDataChannelInit68   InternalDataChannelInit() : open_handshake_role(kOpener) {}
69   explicit InternalDataChannelInit(const DataChannelInit& base);
70   OpenHandshakeRole open_handshake_role;
71 };
72 
73 // Helper class to allocate unique IDs for SCTP DataChannels.
74 class SctpSidAllocator {
75  public:
76   // Gets the first unused odd/even id based on the DTLS role. If `role` is
77   // SSL_CLIENT, the allocated id starts from 0 and takes even numbers;
78   // otherwise, the id starts from 1 and takes odd numbers.
79   // Returns false if no ID can be allocated.
80   bool AllocateSid(rtc::SSLRole role, int* sid);
81 
82   // Attempts to reserve a specific sid. Returns false if it's unavailable.
83   bool ReserveSid(int sid);
84 
85   // Indicates that `sid` isn't in use any more, and is thus available again.
86   void ReleaseSid(int sid);
87 
88  private:
89   // Checks if `sid` is available to be assigned to a new SCTP data channel.
90   bool IsSidAvailable(int sid) const;
91 
92   std::set<int> used_sids_;
93 };
94 
95 // SctpDataChannel is an implementation of the DataChannelInterface based on
96 // SctpTransport. It provides an implementation of unreliable or
97 // reliabledata channels.
98 
99 // DataChannel states:
100 // kConnecting: The channel has been created the transport might not yet be
101 //              ready.
102 // kOpen: The open handshake has been performed (if relevant) and the data
103 //        channel is able to send messages.
104 // kClosing: DataChannelInterface::Close has been called, or the remote side
105 //           initiated the closing procedure, but the closing procedure has not
106 //           yet finished.
107 // kClosed: The closing handshake is finished (possibly initiated from this,
108 //          side, possibly from the peer).
109 //
110 // How the closing procedure works for SCTP:
111 // 1. Alice calls Close(), state changes to kClosing.
112 // 2. Alice finishes sending any queued data.
113 // 3. Alice calls RemoveSctpDataStream, sends outgoing stream reset.
114 // 4. Bob receives incoming stream reset; OnClosingProcedureStartedRemotely
115 //    called.
116 // 5. Bob sends outgoing stream reset.
117 // 6. Alice receives incoming reset, Bob receives acknowledgement. Both receive
118 //    OnClosingProcedureComplete callback and transition to kClosed.
119 class SctpDataChannel : public DataChannelInterface,
120                         public sigslot::has_slots<> {
121  public:
122   static rtc::scoped_refptr<SctpDataChannel> Create(
123       SctpDataChannelControllerInterface* controller,
124       const std::string& label,
125       const InternalDataChannelInit& config,
126       rtc::Thread* signaling_thread,
127       rtc::Thread* network_thread);
128 
129   // Instantiates an API proxy for a SctpDataChannel instance that will be
130   // handed out to external callers.
131   static rtc::scoped_refptr<DataChannelInterface> CreateProxy(
132       rtc::scoped_refptr<SctpDataChannel> channel);
133 
134   // Invalidate the link to the controller (DataChannelController);
135   void DetachFromController();
136 
137   void RegisterObserver(DataChannelObserver* observer) override;
138   void UnregisterObserver() override;
139 
label()140   std::string label() const override { return label_; }
141   bool reliable() const override;
ordered()142   bool ordered() const override { return config_.ordered; }
143   // Backwards compatible accessors
maxRetransmitTime()144   uint16_t maxRetransmitTime() const override {
145     return config_.maxRetransmitTime ? *config_.maxRetransmitTime
146                                      : static_cast<uint16_t>(-1);
147   }
maxRetransmits()148   uint16_t maxRetransmits() const override {
149     return config_.maxRetransmits ? *config_.maxRetransmits
150                                   : static_cast<uint16_t>(-1);
151   }
maxPacketLifeTime()152   absl::optional<int> maxPacketLifeTime() const override {
153     return config_.maxRetransmitTime;
154   }
maxRetransmitsOpt()155   absl::optional<int> maxRetransmitsOpt() const override {
156     return config_.maxRetransmits;
157   }
protocol()158   std::string protocol() const override { return config_.protocol; }
negotiated()159   bool negotiated() const override { return config_.negotiated; }
id()160   int id() const override { return config_.id; }
priority()161   Priority priority() const override {
162     return config_.priority ? *config_.priority : Priority::kLow;
163   }
164 
internal_id()165   virtual int internal_id() const { return internal_id_; }
166 
167   uint64_t buffered_amount() const override;
168   void Close() override;
169   DataState state() const override;
170   RTCError error() const override;
171   uint32_t messages_sent() const override;
172   uint64_t bytes_sent() const override;
173   uint32_t messages_received() const override;
174   uint64_t bytes_received() const override;
175   bool Send(const DataBuffer& buffer) override;
176 
177   // Close immediately, ignoring any queued data or closing procedure.
178   // This is called when the underlying SctpTransport is being destroyed.
179   // It is also called by the PeerConnection if SCTP ID assignment fails.
180   void CloseAbruptlyWithError(RTCError error);
181   // Specializations of CloseAbruptlyWithError
182   void CloseAbruptlyWithDataChannelFailure(const std::string& message);
183 
184   // Slots for controller to connect signals to.
185   //
186   // TODO(deadbeef): Make these private once we're hooking up signals ourselves,
187   // instead of relying on SctpDataChannelControllerInterface.
188 
189   // Called when the SctpTransport's ready to use. That can happen when we've
190   // finished negotiation, or if the channel was created after negotiation has
191   // already finished.
192   void OnTransportReady(bool writable);
193 
194   void OnDataReceived(const cricket::ReceiveDataParams& params,
195                       const rtc::CopyOnWriteBuffer& payload);
196 
197   // Sets the SCTP sid and adds to transport layer if not set yet. Should only
198   // be called once.
199   void SetSctpSid(int sid);
200   // The remote side started the closing procedure by resetting its outgoing
201   // stream (our incoming stream). Sets state to kClosing.
202   void OnClosingProcedureStartedRemotely(int sid);
203   // The closing procedure is complete; both incoming and outgoing stream
204   // resets are done and the channel can transition to kClosed. Called
205   // asynchronously after RemoveSctpDataStream.
206   void OnClosingProcedureComplete(int sid);
207   // Called when the transport channel is created.
208   // Only needs to be called for SCTP data channels.
209   void OnTransportChannelCreated();
210   // Called when the transport channel is unusable.
211   // This method makes sure the DataChannel is disconnected and changes state
212   // to kClosed.
213   void OnTransportChannelClosed(RTCError error);
214 
215   DataChannelStats GetStats() const;
216 
217   // Emitted when state transitions to kOpen.
218   sigslot::signal1<DataChannelInterface*> SignalOpened;
219   // Emitted when state transitions to kClosed.
220   // This signal can be used to tell when the channel's sid is free.
221   sigslot::signal1<DataChannelInterface*> SignalClosed;
222 
223   // Reset the allocator for internal ID values for testing, so that
224   // the internal IDs generated are predictable. Test only.
225   static void ResetInternalIdAllocatorForTesting(int new_value);
226 
227  protected:
228   SctpDataChannel(const InternalDataChannelInit& config,
229                   SctpDataChannelControllerInterface* client,
230                   const std::string& label,
231                   rtc::Thread* signaling_thread,
232                   rtc::Thread* network_thread);
233   ~SctpDataChannel() override;
234 
235  private:
236   // The OPEN(_ACK) signaling state.
237   enum HandshakeState {
238     kHandshakeInit,
239     kHandshakeShouldSendOpen,
240     kHandshakeShouldSendAck,
241     kHandshakeWaitingForAck,
242     kHandshakeReady
243   };
244 
245   bool Init();
246   void UpdateState();
247   void SetState(DataState state);
248   void DisconnectFromTransport();
249 
250   void DeliverQueuedReceivedData();
251 
252   void SendQueuedDataMessages();
253   bool SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked);
254   bool QueueSendDataMessage(const DataBuffer& buffer);
255 
256   void SendQueuedControlMessages();
257   void QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer);
258   bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer);
259 
260   rtc::Thread* const signaling_thread_;
261   rtc::Thread* const network_thread_;
262   const int internal_id_;
263   const std::string label_;
264   const InternalDataChannelInit config_;
265   DataChannelObserver* observer_ RTC_GUARDED_BY(signaling_thread_) = nullptr;
266   DataState state_ RTC_GUARDED_BY(signaling_thread_) = kConnecting;
267   RTCError error_ RTC_GUARDED_BY(signaling_thread_);
268   uint32_t messages_sent_ RTC_GUARDED_BY(signaling_thread_) = 0;
269   uint64_t bytes_sent_ RTC_GUARDED_BY(signaling_thread_) = 0;
270   uint32_t messages_received_ RTC_GUARDED_BY(signaling_thread_) = 0;
271   uint64_t bytes_received_ RTC_GUARDED_BY(signaling_thread_) = 0;
272   SctpDataChannelControllerInterface* const controller_
273       RTC_GUARDED_BY(signaling_thread_);
274   bool controller_detached_ RTC_GUARDED_BY(signaling_thread_) = false;
275   HandshakeState handshake_state_ RTC_GUARDED_BY(signaling_thread_) =
276       kHandshakeInit;
277   bool connected_to_transport_ RTC_GUARDED_BY(signaling_thread_) = false;
278   bool writable_ RTC_GUARDED_BY(signaling_thread_) = false;
279   // Did we already start the graceful SCTP closing procedure?
280   bool started_closing_procedure_ RTC_GUARDED_BY(signaling_thread_) = false;
281   // Control messages that always have to get sent out before any queued
282   // data.
283   PacketQueue queued_control_data_ RTC_GUARDED_BY(signaling_thread_);
284   PacketQueue queued_received_data_ RTC_GUARDED_BY(signaling_thread_);
285   PacketQueue queued_send_data_ RTC_GUARDED_BY(signaling_thread_);
286 };
287 
288 // Downcast a PeerConnectionInterface that points to a proxy object
289 // to its underlying SctpDataChannel object. For testing only.
290 SctpDataChannel* DowncastProxiedDataChannelInterfaceToSctpDataChannelForTesting(
291     DataChannelInterface* channel);
292 
293 }  // namespace webrtc
294 
295 #endif  // PC_SCTP_DATA_CHANNEL_H_
296