sctp_transport.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * Copyright (c) 2012 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 MEDIA_SCTP_SCTP_TRANSPORT_H_
  11. #define MEDIA_SCTP_SCTP_TRANSPORT_H_
  12. #include <errno.h>
  13. #include <cstdint>
  14. #include <map>
  15. #include <memory>
  16. #include <set>
  17. #include <string>
  18. #include <vector>
  19. #include "absl/types/optional.h"
  20. #include "api/transport/sctp_transport_factory_interface.h"
  21. #include "rtc_base/async_invoker.h"
  22. #include "rtc_base/buffer.h"
  23. #include "rtc_base/constructor_magic.h"
  24. #include "rtc_base/copy_on_write_buffer.h"
  25. #include "rtc_base/third_party/sigslot/sigslot.h"
  26. #include "rtc_base/thread.h"
  27. // For SendDataParams/ReceiveDataParams.
  28. #include "media/base/media_channel.h"
  29. #include "media/sctp/sctp_transport_internal.h"
  30. // Defined by "usrsctplib/usrsctp.h"
  31. struct sockaddr_conn;
  32. struct sctp_assoc_change;
  33. struct sctp_rcvinfo;
  34. struct sctp_stream_reset_event;
  35. struct sctp_sendv_spa;
  36. // Defined by <sys/socket.h>
  37. struct socket;
  38. namespace cricket {
  39. // Holds data to be passed on to a transport.
  40. struct SctpInboundPacket;
  41. // From transport calls, data flows like this:
  42. // [network thread (although it can in princple be another thread)]
  43. // 1. SctpTransport::SendData(data)
  44. // 2. usrsctp_sendv(data)
  45. // [network thread returns; sctp thread then calls the following]
  46. // 3. OnSctpOutboundPacket(wrapped_data)
  47. // [sctp thread returns having async invoked on the network thread]
  48. // 4. SctpTransport::OnPacketFromSctpToNetwork(wrapped_data)
  49. // 5. DtlsTransport::SendPacket(wrapped_data)
  50. // 6. ... across network ... a packet is sent back ...
  51. // 7. SctpTransport::OnPacketReceived(wrapped_data)
  52. // 8. usrsctp_conninput(wrapped_data)
  53. // [network thread returns; sctp thread then calls the following]
  54. // 9. OnSctpInboundData(data)
  55. // 10. SctpTransport::OnDataFromSctpToTransport(data)
  56. // [sctp thread returns having async invoked on the network thread]
  57. // 11. SctpTransport::OnDataFromSctpToTransport(data)
  58. // 12. SctpTransport::SignalDataReceived(data)
  59. // [from the same thread, methods registered/connected to
  60. // SctpTransport are called with the recieved data]
  61. class SctpTransport : public SctpTransportInternal,
  62. public sigslot::has_slots<> {
  63. public:
  64. // |network_thread| is where packets will be processed and callbacks from
  65. // this transport will be posted, and is the only thread on which public
  66. // methods can be called.
  67. // |transport| is not required (can be null).
  68. SctpTransport(rtc::Thread* network_thread,
  69. rtc::PacketTransportInternal* transport);
  70. ~SctpTransport() override;
  71. // SctpTransportInternal overrides (see sctptransportinternal.h for comments).
  72. void SetDtlsTransport(rtc::PacketTransportInternal* transport) override;
  73. bool Start(int local_port, int remote_port, int max_message_size) override;
  74. bool OpenStream(int sid) override;
  75. bool ResetStream(int sid) override;
  76. bool SendData(const SendDataParams& params,
  77. const rtc::CopyOnWriteBuffer& payload,
  78. SendDataResult* result = nullptr) override;
  79. bool ReadyToSendData() override;
  80. int max_message_size() const override { return max_message_size_; }
  81. absl::optional<int> max_outbound_streams() const override {
  82. return max_outbound_streams_;
  83. }
  84. absl::optional<int> max_inbound_streams() const override {
  85. return max_inbound_streams_;
  86. }
  87. void set_debug_name_for_testing(const char* debug_name) override {
  88. debug_name_ = debug_name;
  89. }
  90. int InjectDataOrNotificationFromSctpForTesting(void* data,
  91. size_t length,
  92. struct sctp_rcvinfo rcv,
  93. int flags);
  94. // Exposed to allow Post call from c-callbacks.
  95. // TODO(deadbeef): Remove this or at least make it return a const pointer.
  96. rtc::Thread* network_thread() const { return network_thread_; }
  97. private:
  98. // A message to be sent by the sctp library. This class is used to track the
  99. // progress of writing a single message to the sctp library in the presence of
  100. // partial writes. In this case, the Advance() function is provided in order
  101. // to advance over what has already been accepted by the sctp library and
  102. // avoid copying the remaining partial message buffer.
  103. class OutgoingMessage {
  104. public:
  105. OutgoingMessage(const rtc::CopyOnWriteBuffer& buffer,
  106. const SendDataParams& send_params)
  107. : buffer_(buffer), send_params_(send_params) {}
  108. // Advances the buffer by the incremented amount. Must not advance further
  109. // than the current data size.
  110. void Advance(size_t increment) {
  111. RTC_DCHECK_LE(increment + offset_, buffer_.size());
  112. offset_ += increment;
  113. }
  114. size_t size() const { return buffer_.size() - offset_; }
  115. const void* data() const { return buffer_.data() + offset_; }
  116. SendDataParams send_params() const { return send_params_; }
  117. private:
  118. const rtc::CopyOnWriteBuffer buffer_;
  119. const SendDataParams send_params_;
  120. size_t offset_ = 0;
  121. };
  122. void ConnectTransportSignals();
  123. void DisconnectTransportSignals();
  124. // Creates the socket and connects.
  125. bool Connect();
  126. // Returns false when opening the socket failed.
  127. bool OpenSctpSocket();
  128. // Helpet method to set socket options.
  129. bool ConfigureSctpSocket();
  130. // Sets |sock_ |to nullptr.
  131. void CloseSctpSocket();
  132. // Sends a SCTP_RESET_STREAM for all streams in closing_ssids_.
  133. bool SendQueuedStreamResets();
  134. // Sets the "ready to send" flag and fires signal if needed.
  135. void SetReadyToSendData();
  136. // Sends the outgoing buffered message that was only partially accepted by the
  137. // sctp lib because it did not have enough space. Returns true if the entire
  138. // buffered message was accepted by the sctp lib.
  139. bool SendBufferedMessage();
  140. // Tries to send the |payload| on the usrsctp lib. The message will be
  141. // advanced by the amount that was sent.
  142. SendDataResult SendMessageInternal(OutgoingMessage* message);
  143. // Callbacks from DTLS transport.
  144. void OnWritableState(rtc::PacketTransportInternal* transport);
  145. virtual void OnPacketRead(rtc::PacketTransportInternal* transport,
  146. const char* data,
  147. size_t len,
  148. const int64_t& packet_time_us,
  149. int flags);
  150. void OnClosed(rtc::PacketTransportInternal* transport);
  151. // Methods related to usrsctp callbacks.
  152. void OnSendThresholdCallback();
  153. sockaddr_conn GetSctpSockAddr(int port);
  154. // Called using |invoker_| to send packet on the network.
  155. void OnPacketFromSctpToNetwork(const rtc::CopyOnWriteBuffer& buffer);
  156. // Called on the SCTP thread.
  157. // Flags are standard socket API flags (RFC 6458).
  158. int OnDataOrNotificationFromSctp(void* data,
  159. size_t length,
  160. struct sctp_rcvinfo rcv,
  161. int flags);
  162. // Called using |invoker_| to decide what to do with the data.
  163. void OnDataFromSctpToTransport(const ReceiveDataParams& params,
  164. const rtc::CopyOnWriteBuffer& buffer);
  165. // Called using |invoker_| to decide what to do with the notification.
  166. void OnNotificationFromSctp(const rtc::CopyOnWriteBuffer& buffer);
  167. void OnNotificationAssocChange(const sctp_assoc_change& change);
  168. void OnStreamResetEvent(const struct sctp_stream_reset_event* evt);
  169. // Responsible for marshalling incoming data to the transports listeners, and
  170. // outgoing data to the network interface.
  171. rtc::Thread* network_thread_;
  172. // Helps pass inbound/outbound packets asynchronously to the network thread.
  173. rtc::AsyncInvoker invoker_;
  174. // Underlying DTLS transport.
  175. rtc::PacketTransportInternal* transport_ = nullptr;
  176. // Track the data received from usrsctp between callbacks until the EOR bit
  177. // arrives.
  178. rtc::CopyOnWriteBuffer partial_incoming_message_;
  179. ReceiveDataParams partial_params_;
  180. int partial_flags_;
  181. // A message that was attempted to be sent, but was only partially accepted by
  182. // usrsctp lib with usrsctp_sendv() because it cannot buffer the full message.
  183. // This occurs because we explicitly set the EOR bit when sending, so
  184. // usrsctp_sendv() is not atomic.
  185. absl::optional<OutgoingMessage> partial_outgoing_message_;
  186. bool was_ever_writable_ = false;
  187. int local_port_ = kSctpDefaultPort;
  188. int remote_port_ = kSctpDefaultPort;
  189. int max_message_size_ = kSctpSendBufferSize;
  190. struct socket* sock_ = nullptr; // The socket created by usrsctp_socket(...).
  191. // Has Start been called? Don't create SCTP socket until it has.
  192. bool started_ = false;
  193. // Are we ready to queue data (SCTP socket created, and not blocked due to
  194. // congestion control)? Different than |transport_|'s "ready to send".
  195. bool ready_to_send_data_ = false;
  196. // Used to keep track of the status of each stream (or rather, each pair of
  197. // incoming/outgoing streams with matching IDs). It's specifically used to
  198. // keep track of the status of resets, but more information could be put here
  199. // later.
  200. //
  201. // See datachannel.h for a summary of the closing procedure.
  202. struct StreamStatus {
  203. // Closure initiated by application via ResetStream? Note that
  204. // this may be true while outgoing_reset_initiated is false if the outgoing
  205. // reset needed to be queued.
  206. bool closure_initiated = false;
  207. // Whether we've initiated the outgoing stream reset via
  208. // SCTP_RESET_STREAMS.
  209. bool outgoing_reset_initiated = false;
  210. // Whether usrsctp has indicated that the incoming/outgoing streams have
  211. // been reset. It's expected that the peer will reset its outgoing stream
  212. // (our incoming stream) after receiving the reset for our outgoing stream,
  213. // though older versions of chromium won't do this. See crbug.com/559394
  214. // for context.
  215. bool outgoing_reset_complete = false;
  216. bool incoming_reset_complete = false;
  217. // Some helper methods to improve code readability.
  218. bool is_open() const {
  219. return !closure_initiated && !incoming_reset_complete &&
  220. !outgoing_reset_complete;
  221. }
  222. // We need to send an outgoing reset if the application has closed the data
  223. // channel, or if we received a reset of the incoming stream from the
  224. // remote endpoint, indicating the data channel was closed remotely.
  225. bool need_outgoing_reset() const {
  226. return (incoming_reset_complete || closure_initiated) &&
  227. !outgoing_reset_initiated;
  228. }
  229. bool reset_complete() const {
  230. return outgoing_reset_complete && incoming_reset_complete;
  231. }
  232. };
  233. // Entries should only be removed from this map if |reset_complete| is
  234. // true.
  235. std::map<uint32_t, StreamStatus> stream_status_by_sid_;
  236. // A static human-readable name for debugging messages.
  237. const char* debug_name_ = "SctpTransport";
  238. // Hides usrsctp interactions from this header file.
  239. class UsrSctpWrapper;
  240. // Number of channels negotiated. Not set before negotiation completes.
  241. absl::optional<int> max_outbound_streams_;
  242. absl::optional<int> max_inbound_streams_;
  243. // Used for associating this transport with the underlying sctp socket in
  244. // various callbacks.
  245. uintptr_t id_ = 0;
  246. RTC_DISALLOW_COPY_AND_ASSIGN(SctpTransport);
  247. };
  248. class SctpTransportFactory : public webrtc::SctpTransportFactoryInterface {
  249. public:
  250. explicit SctpTransportFactory(rtc::Thread* network_thread)
  251. : network_thread_(network_thread) {}
  252. std::unique_ptr<SctpTransportInternal> CreateSctpTransport(
  253. rtc::PacketTransportInternal* transport) override {
  254. return std::unique_ptr<SctpTransportInternal>(
  255. new SctpTransport(network_thread_, transport));
  256. }
  257. private:
  258. rtc::Thread* network_thread_;
  259. };
  260. } // namespace cricket
  261. #endif // MEDIA_SCTP_SCTP_TRANSPORT_H_