jsep_transport_controller.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. * Copyright 2017 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 PC_JSEP_TRANSPORT_CONTROLLER_H_
  11. #define PC_JSEP_TRANSPORT_CONTROLLER_H_
  12. #include <map>
  13. #include <memory>
  14. #include <string>
  15. #include <utility>
  16. #include <vector>
  17. #include "api/candidate.h"
  18. #include "api/crypto/crypto_options.h"
  19. #include "api/ice_transport_factory.h"
  20. #include "api/peer_connection_interface.h"
  21. #include "api/rtc_event_log/rtc_event_log.h"
  22. #include "media/sctp/sctp_transport_internal.h"
  23. #include "p2p/base/dtls_transport.h"
  24. #include "p2p/base/dtls_transport_factory.h"
  25. #include "p2p/base/p2p_transport_channel.h"
  26. #include "pc/channel.h"
  27. #include "pc/dtls_srtp_transport.h"
  28. #include "pc/dtls_transport.h"
  29. #include "pc/jsep_transport.h"
  30. #include "pc/rtp_transport.h"
  31. #include "pc/srtp_transport.h"
  32. #include "rtc_base/async_invoker.h"
  33. #include "rtc_base/constructor_magic.h"
  34. #include "rtc_base/ref_counted_object.h"
  35. #include "rtc_base/robo_caller.h"
  36. #include "rtc_base/third_party/sigslot/sigslot.h"
  37. namespace rtc {
  38. class Thread;
  39. class PacketTransportInternal;
  40. } // namespace rtc
  41. namespace webrtc {
  42. class JsepTransportController : public sigslot::has_slots<> {
  43. public:
  44. // Used when the RtpTransport/DtlsTransport of the m= section is changed
  45. // because the section is rejected or BUNDLE is enabled.
  46. class Observer {
  47. public:
  48. virtual ~Observer() {}
  49. // Returns true if media associated with |mid| was successfully set up to be
  50. // demultiplexed on |rtp_transport|. Could return false if two bundled m=
  51. // sections use the same SSRC, for example.
  52. //
  53. // If a data channel transport must be negotiated, |data_channel_transport|
  54. // and |negotiation_state| indicate negotiation status. If
  55. // |data_channel_transport| is null, the data channel transport should not
  56. // be used. Otherwise, the value is a pointer to the transport to be used
  57. // for data channels on |mid|, if any.
  58. //
  59. // The observer should not send data on |data_channel_transport| until
  60. // |negotiation_state| is provisional or final. It should not delete
  61. // |data_channel_transport| or any fallback transport until
  62. // |negotiation_state| is final.
  63. virtual bool OnTransportChanged(
  64. const std::string& mid,
  65. RtpTransportInternal* rtp_transport,
  66. rtc::scoped_refptr<DtlsTransport> dtls_transport,
  67. DataChannelTransportInterface* data_channel_transport) = 0;
  68. };
  69. struct Config {
  70. // If |redetermine_role_on_ice_restart| is true, ICE role is redetermined
  71. // upon setting a local transport description that indicates an ICE
  72. // restart.
  73. bool redetermine_role_on_ice_restart = true;
  74. rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
  75. // |crypto_options| is used to determine if created DTLS transports
  76. // negotiate GCM crypto suites or not.
  77. webrtc::CryptoOptions crypto_options;
  78. PeerConnectionInterface::BundlePolicy bundle_policy =
  79. PeerConnectionInterface::kBundlePolicyBalanced;
  80. PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy =
  81. PeerConnectionInterface::kRtcpMuxPolicyRequire;
  82. bool disable_encryption = false;
  83. bool enable_external_auth = false;
  84. // Used to inject the ICE/DTLS transports created externally.
  85. webrtc::IceTransportFactory* ice_transport_factory = nullptr;
  86. cricket::DtlsTransportFactory* dtls_transport_factory = nullptr;
  87. Observer* transport_observer = nullptr;
  88. // Must be provided and valid for the lifetime of the
  89. // JsepTransportController instance.
  90. std::function<void(const rtc::CopyOnWriteBuffer& packet,
  91. int64_t packet_time_us)>
  92. rtcp_handler;
  93. bool active_reset_srtp_params = false;
  94. RtcEventLog* event_log = nullptr;
  95. // Factory for SCTP transports.
  96. SctpTransportFactoryInterface* sctp_factory = nullptr;
  97. };
  98. // The ICE related events are signaled on the |signaling_thread|.
  99. // All the transport related methods are called on the |network_thread|.
  100. JsepTransportController(rtc::Thread* signaling_thread,
  101. rtc::Thread* network_thread,
  102. cricket::PortAllocator* port_allocator,
  103. AsyncResolverFactory* async_resolver_factory,
  104. Config config);
  105. virtual ~JsepTransportController();
  106. // The main method to be called; applies a description at the transport
  107. // level, creating/destroying transport objects as needed and updating their
  108. // properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not
  109. // yet? May make sense to in the future.
  110. RTCError SetLocalDescription(SdpType type,
  111. const cricket::SessionDescription* description);
  112. RTCError SetRemoteDescription(SdpType type,
  113. const cricket::SessionDescription* description);
  114. // Get transports to be used for the provided |mid|. If bundling is enabled,
  115. // calling GetRtpTransport for multiple MIDs may yield the same object.
  116. RtpTransportInternal* GetRtpTransport(const std::string& mid) const;
  117. cricket::DtlsTransportInternal* GetDtlsTransport(const std::string& mid);
  118. const cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
  119. const std::string& mid) const;
  120. // Gets the externally sharable version of the DtlsTransport.
  121. rtc::scoped_refptr<webrtc::DtlsTransport> LookupDtlsTransportByMid(
  122. const std::string& mid);
  123. rtc::scoped_refptr<SctpTransport> GetSctpTransport(
  124. const std::string& mid) const;
  125. DataChannelTransportInterface* GetDataChannelTransport(
  126. const std::string& mid) const;
  127. /*********************
  128. * ICE-related methods
  129. ********************/
  130. // This method is public to allow PeerConnection to update it from
  131. // SetConfiguration.
  132. void SetIceConfig(const cricket::IceConfig& config);
  133. // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
  134. // set, offers should generate new ufrags/passwords until an ICE restart
  135. // occurs.
  136. void SetNeedsIceRestartFlag();
  137. // Returns true if the ICE restart flag above was set, and no ICE restart has
  138. // occurred yet for this transport (by applying a local description with
  139. // changed ufrag/password). If the transport has been deleted as a result of
  140. // bundling, returns false.
  141. bool NeedsIceRestart(const std::string& mid) const;
  142. // Start gathering candidates for any new transports, or transports doing an
  143. // ICE restart.
  144. void MaybeStartGathering();
  145. RTCError AddRemoteCandidates(
  146. const std::string& mid,
  147. const std::vector<cricket::Candidate>& candidates);
  148. RTCError RemoveRemoteCandidates(
  149. const std::vector<cricket::Candidate>& candidates);
  150. /**********************
  151. * DTLS-related methods
  152. *********************/
  153. // Specifies the identity to use in this session.
  154. // Can only be called once.
  155. bool SetLocalCertificate(
  156. const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
  157. rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate(
  158. const std::string& mid) const;
  159. // Caller owns returned certificate chain. This method mainly exists for
  160. // stats reporting.
  161. std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
  162. const std::string& mid) const;
  163. // Get negotiated role, if one has been negotiated.
  164. absl::optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
  165. // TODO(deadbeef): GetStats isn't const because all the way down to
  166. // OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not
  167. // const. Fix this.
  168. bool GetStats(const std::string& mid, cricket::TransportStats* stats);
  169. bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; }
  170. void SetActiveResetSrtpParams(bool active_reset_srtp_params);
  171. // For now the rollback only removes mid to transport mappings
  172. // and deletes unused transports, but doesn't consider anything more complex.
  173. void RollbackTransports();
  174. // All of these signals are fired on the signaling thread.
  175. // If any transport failed => failed,
  176. // Else if all completed => completed,
  177. // Else if all connected => connected,
  178. // Else => connecting
  179. RoboCaller<cricket::IceConnectionState> SignalIceConnectionState;
  180. sigslot::signal1<PeerConnectionInterface::PeerConnectionState>
  181. SignalConnectionState;
  182. sigslot::signal1<PeerConnectionInterface::IceConnectionState>
  183. SignalStandardizedIceConnectionState;
  184. // If all transports done gathering => complete,
  185. // Else if any are gathering => gathering,
  186. // Else => new
  187. sigslot::signal1<cricket::IceGatheringState> SignalIceGatheringState;
  188. // (mid, candidates)
  189. sigslot::signal2<const std::string&, const std::vector<cricket::Candidate>&>
  190. SignalIceCandidatesGathered;
  191. sigslot::signal1<const cricket::IceCandidateErrorEvent&>
  192. SignalIceCandidateError;
  193. sigslot::signal1<const std::vector<cricket::Candidate>&>
  194. SignalIceCandidatesRemoved;
  195. sigslot::signal1<const cricket::CandidatePairChangeEvent&>
  196. SignalIceCandidatePairChanged;
  197. sigslot::signal1<rtc::SSLHandshakeError> SignalDtlsHandshakeError;
  198. private:
  199. RTCError ApplyDescription_n(bool local,
  200. SdpType type,
  201. const cricket::SessionDescription* description);
  202. RTCError ValidateAndMaybeUpdateBundleGroup(
  203. bool local,
  204. SdpType type,
  205. const cricket::SessionDescription* description);
  206. RTCError ValidateContent(const cricket::ContentInfo& content_info);
  207. void HandleRejectedContent(const cricket::ContentInfo& content_info,
  208. const cricket::SessionDescription* description);
  209. bool HandleBundledContent(const cricket::ContentInfo& content_info);
  210. bool SetTransportForMid(const std::string& mid,
  211. cricket::JsepTransport* jsep_transport);
  212. void RemoveTransportForMid(const std::string& mid);
  213. cricket::JsepTransportDescription CreateJsepTransportDescription(
  214. const cricket::ContentInfo& content_info,
  215. const cricket::TransportInfo& transport_info,
  216. const std::vector<int>& encrypted_extension_ids,
  217. int rtp_abs_sendtime_extn_id);
  218. absl::optional<std::string> bundled_mid() const {
  219. absl::optional<std::string> bundled_mid;
  220. if (bundle_group_ && bundle_group_->FirstContentName()) {
  221. bundled_mid = *(bundle_group_->FirstContentName());
  222. }
  223. return bundled_mid;
  224. }
  225. bool IsBundled(const std::string& mid) const {
  226. return bundle_group_ && bundle_group_->HasContentName(mid);
  227. }
  228. bool ShouldUpdateBundleGroup(SdpType type,
  229. const cricket::SessionDescription* description);
  230. std::vector<int> MergeEncryptedHeaderExtensionIdsForBundle(
  231. const cricket::SessionDescription* description);
  232. std::vector<int> GetEncryptedHeaderExtensionIds(
  233. const cricket::ContentInfo& content_info);
  234. int GetRtpAbsSendTimeHeaderExtensionId(
  235. const cricket::ContentInfo& content_info);
  236. // This method takes the BUNDLE group into account. If the JsepTransport is
  237. // destroyed because of BUNDLE, it would return the transport which other
  238. // transports are bundled on (In current implementation, it is the first
  239. // content in the BUNDLE group).
  240. const cricket::JsepTransport* GetJsepTransportForMid(
  241. const std::string& mid) const;
  242. cricket::JsepTransport* GetJsepTransportForMid(const std::string& mid);
  243. // Get the JsepTransport without considering the BUNDLE group. Return nullptr
  244. // if the JsepTransport is destroyed.
  245. const cricket::JsepTransport* GetJsepTransportByName(
  246. const std::string& transport_name) const;
  247. cricket::JsepTransport* GetJsepTransportByName(
  248. const std::string& transport_name);
  249. // Creates jsep transport. Noop if transport is already created.
  250. // Transport is created either during SetLocalDescription (|local| == true) or
  251. // during SetRemoteDescription (|local| == false). Passing |local| helps to
  252. // differentiate initiator (caller) from answerer (callee).
  253. RTCError MaybeCreateJsepTransport(
  254. bool local,
  255. const cricket::ContentInfo& content_info,
  256. const cricket::SessionDescription& description);
  257. void MaybeDestroyJsepTransport(const std::string& mid);
  258. void DestroyAllJsepTransports_n();
  259. void SetIceRole_n(cricket::IceRole ice_role);
  260. cricket::IceRole DetermineIceRole(
  261. cricket::JsepTransport* jsep_transport,
  262. const cricket::TransportInfo& transport_info,
  263. SdpType type,
  264. bool local);
  265. std::unique_ptr<cricket::DtlsTransportInternal> CreateDtlsTransport(
  266. const cricket::ContentInfo& content_info,
  267. cricket::IceTransportInternal* ice);
  268. rtc::scoped_refptr<webrtc::IceTransportInterface> CreateIceTransport(
  269. const std::string& transport_name,
  270. bool rtcp);
  271. std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedRtpTransport(
  272. const std::string& transport_name,
  273. rtc::PacketTransportInternal* rtp_packet_transport,
  274. rtc::PacketTransportInternal* rtcp_packet_transport);
  275. std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
  276. const std::string& transport_name,
  277. cricket::DtlsTransportInternal* rtp_dtls_transport,
  278. cricket::DtlsTransportInternal* rtcp_dtls_transport);
  279. std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
  280. const std::string& transport_name,
  281. cricket::DtlsTransportInternal* rtp_dtls_transport,
  282. cricket::DtlsTransportInternal* rtcp_dtls_transport);
  283. // Collect all the DtlsTransports, including RTP and RTCP, from the
  284. // JsepTransports. JsepTransportController can iterate all the DtlsTransports
  285. // and update the aggregate states.
  286. std::vector<cricket::DtlsTransportInternal*> GetDtlsTransports();
  287. // Handlers for signals from Transport.
  288. void OnTransportWritableState_n(rtc::PacketTransportInternal* transport);
  289. void OnTransportReceivingState_n(rtc::PacketTransportInternal* transport);
  290. void OnTransportGatheringState_n(cricket::IceTransportInternal* transport);
  291. void OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport,
  292. const cricket::Candidate& candidate);
  293. void OnTransportCandidateError_n(
  294. cricket::IceTransportInternal* transport,
  295. const cricket::IceCandidateErrorEvent& event);
  296. void OnTransportCandidatesRemoved_n(cricket::IceTransportInternal* transport,
  297. const cricket::Candidates& candidates);
  298. void OnTransportRoleConflict_n(cricket::IceTransportInternal* transport);
  299. void OnTransportStateChanged_n(cricket::IceTransportInternal* transport);
  300. void OnTransportCandidatePairChanged_n(
  301. const cricket::CandidatePairChangeEvent& event);
  302. void UpdateAggregateStates_n();
  303. void OnRtcpPacketReceived_n(rtc::CopyOnWriteBuffer* packet,
  304. int64_t packet_time_us);
  305. void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
  306. rtc::Thread* const signaling_thread_ = nullptr;
  307. rtc::Thread* const network_thread_ = nullptr;
  308. cricket::PortAllocator* const port_allocator_ = nullptr;
  309. AsyncResolverFactory* const async_resolver_factory_ = nullptr;
  310. std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
  311. jsep_transports_by_name_;
  312. // This keeps track of the mapping between media section
  313. // (BaseChannel/SctpTransport) and the JsepTransport underneath.
  314. std::map<std::string, cricket::JsepTransport*> mid_to_transport_;
  315. // Keep track of mids that have been mapped to transports. Used for rollback.
  316. std::vector<std::string> pending_mids_ RTC_GUARDED_BY(network_thread_);
  317. // Aggregate states for Transports.
  318. // standardized_ice_connection_state_ is intended to replace
  319. // ice_connection_state, see bugs.webrtc.org/9308
  320. cricket::IceConnectionState ice_connection_state_ =
  321. cricket::kIceConnectionConnecting;
  322. PeerConnectionInterface::IceConnectionState
  323. standardized_ice_connection_state_ =
  324. PeerConnectionInterface::kIceConnectionNew;
  325. PeerConnectionInterface::PeerConnectionState combined_connection_state_ =
  326. PeerConnectionInterface::PeerConnectionState::kNew;
  327. cricket::IceGatheringState ice_gathering_state_ = cricket::kIceGatheringNew;
  328. Config config_;
  329. const cricket::SessionDescription* local_desc_ = nullptr;
  330. const cricket::SessionDescription* remote_desc_ = nullptr;
  331. absl::optional<bool> initial_offerer_;
  332. absl::optional<cricket::ContentGroup> bundle_group_;
  333. cricket::IceConfig ice_config_;
  334. cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING;
  335. uint64_t ice_tiebreaker_ = rtc::CreateRandomId64();
  336. rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
  337. rtc::AsyncInvoker invoker_;
  338. RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController);
  339. };
  340. } // namespace webrtc
  341. #endif // PC_JSEP_TRANSPORT_CONTROLLER_H_