sctp_transport.h 11 KB

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