jsep_transport_controller.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  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 "api/transport/media/media_transport_config.h"
  23. #include "media/sctp/sctp_transport_internal.h"
  24. #include "p2p/base/dtls_transport.h"
  25. #include "p2p/base/dtls_transport_factory.h"
  26. #include "p2p/base/p2p_transport_channel.h"
  27. #include "pc/channel.h"
  28. #include "pc/dtls_srtp_transport.h"
  29. #include "pc/dtls_transport.h"
  30. #include "pc/jsep_transport.h"
  31. #include "pc/rtp_transport.h"
  32. #include "pc/srtp_transport.h"
  33. #include "rtc_base/async_invoker.h"
  34. #include "rtc_base/constructor_magic.h"
  35. #include "rtc_base/ref_counted_object.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. cricket::SctpTransportInternalFactory* sctp_factory = nullptr;
  97. // Whether an RtpMediaTransport should be created as default, when no
  98. // MediaTransportFactory is provided.
  99. bool use_rtp_media_transport = false;
  100. // Use encrypted datagram transport to send packets.
  101. bool use_datagram_transport = false;
  102. // Use datagram transport's implementation of data channels instead of SCTP.
  103. bool use_datagram_transport_for_data_channels = false;
  104. // Whether |use_datagram_transport_for_data_channels| applies to outgoing
  105. // calls. If true, |use_datagram_transport_for_data_channels| applies only
  106. // to incoming calls.
  107. bool use_datagram_transport_for_data_channels_receive_only = false;
  108. // Optional media transport factory (experimental). If provided it will be
  109. // used to create datagram_transport (as long as either
  110. // |use_datagram_transport| or
  111. // |use_datagram_transport_for_data_channels| is set to true). However,
  112. // whether it will be used to send / receive audio and video frames instead
  113. // of RTP is determined by |use_datagram_transport|. Note that currently
  114. // datagram_transport co-exists with RTP / RTCP transports and may use the
  115. // same underlying ICE transport.
  116. MediaTransportFactory* media_transport_factory = nullptr;
  117. };
  118. // The ICE related events are signaled on the |signaling_thread|.
  119. // All the transport related methods are called on the |network_thread|.
  120. JsepTransportController(rtc::Thread* signaling_thread,
  121. rtc::Thread* network_thread,
  122. cricket::PortAllocator* port_allocator,
  123. AsyncResolverFactory* async_resolver_factory,
  124. Config config);
  125. virtual ~JsepTransportController();
  126. // The main method to be called; applies a description at the transport
  127. // level, creating/destroying transport objects as needed and updating their
  128. // properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not
  129. // yet? May make sense to in the future.
  130. RTCError SetLocalDescription(SdpType type,
  131. const cricket::SessionDescription* description);
  132. RTCError SetRemoteDescription(SdpType type,
  133. const cricket::SessionDescription* description);
  134. // Get transports to be used for the provided |mid|. If bundling is enabled,
  135. // calling GetRtpTransport for multiple MIDs may yield the same object.
  136. RtpTransportInternal* GetRtpTransport(const std::string& mid) const;
  137. cricket::DtlsTransportInternal* GetDtlsTransport(const std::string& mid);
  138. const cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
  139. const std::string& mid) const;
  140. // Gets the externally sharable version of the DtlsTransport.
  141. rtc::scoped_refptr<webrtc::DtlsTransport> LookupDtlsTransportByMid(
  142. const std::string& mid);
  143. rtc::scoped_refptr<SctpTransport> GetSctpTransport(
  144. const std::string& mid) const;
  145. MediaTransportConfig GetMediaTransportConfig(const std::string& mid) const;
  146. DataChannelTransportInterface* GetDataChannelTransport(
  147. const std::string& mid) const;
  148. /*********************
  149. * ICE-related methods
  150. ********************/
  151. // This method is public to allow PeerConnection to update it from
  152. // SetConfiguration.
  153. void SetIceConfig(const cricket::IceConfig& config);
  154. // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
  155. // set, offers should generate new ufrags/passwords until an ICE restart
  156. // occurs.
  157. void SetNeedsIceRestartFlag();
  158. // Returns true if the ICE restart flag above was set, and no ICE restart has
  159. // occurred yet for this transport (by applying a local description with
  160. // changed ufrag/password). If the transport has been deleted as a result of
  161. // bundling, returns false.
  162. bool NeedsIceRestart(const std::string& mid) const;
  163. // Start gathering candidates for any new transports, or transports doing an
  164. // ICE restart.
  165. void MaybeStartGathering();
  166. RTCError AddRemoteCandidates(
  167. const std::string& mid,
  168. const std::vector<cricket::Candidate>& candidates);
  169. RTCError RemoveRemoteCandidates(
  170. const std::vector<cricket::Candidate>& candidates);
  171. /**********************
  172. * DTLS-related methods
  173. *********************/
  174. // Specifies the identity to use in this session.
  175. // Can only be called once.
  176. bool SetLocalCertificate(
  177. const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
  178. rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate(
  179. const std::string& mid) const;
  180. // Caller owns returned certificate chain. This method mainly exists for
  181. // stats reporting.
  182. std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
  183. const std::string& mid) const;
  184. // Get negotiated role, if one has been negotiated.
  185. absl::optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
  186. // TODO(deadbeef): GetStats isn't const because all the way down to
  187. // OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not
  188. // const. Fix this.
  189. bool GetStats(const std::string& mid, cricket::TransportStats* stats);
  190. bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; }
  191. void SetActiveResetSrtpParams(bool active_reset_srtp_params);
  192. // Allows to overwrite the settings from config. You may set or reset the
  193. // media transport configuration on the jsep transport controller, as long as
  194. // you did not call 'GetMediaTransport' or 'MaybeCreateJsepTransport'. Once
  195. // Jsep transport is created, you can't change this setting.
  196. void SetMediaTransportSettings(
  197. bool use_datagram_transport,
  198. bool use_datagram_transport_for_data_channels,
  199. bool use_datagram_transport_for_data_channels_receive_only);
  200. // For now the rollback only removes mid to transport mappings
  201. // and deletes unused transports, but doesn't consider anything more complex.
  202. void RollbackTransports();
  203. // Gets the transport parameters for the transport identified by |mid|.
  204. // If |mid| is bundled, returns the parameters for the bundled transport.
  205. // If the transport for |mid| has not been created yet, it may be allocated in
  206. // order to generate transport parameters.
  207. absl::optional<cricket::OpaqueTransportParameters> GetTransportParameters(
  208. const std::string& mid);
  209. // All of these signals are fired on the signaling thread.
  210. // If any transport failed => failed,
  211. // Else if all completed => completed,
  212. // Else if all connected => connected,
  213. // Else => connecting
  214. sigslot::signal1<cricket::IceConnectionState> SignalIceConnectionState;
  215. sigslot::signal1<PeerConnectionInterface::PeerConnectionState>
  216. SignalConnectionState;
  217. sigslot::signal1<PeerConnectionInterface::IceConnectionState>
  218. SignalStandardizedIceConnectionState;
  219. // If all transports done gathering => complete,
  220. // Else if any are gathering => gathering,
  221. // Else => new
  222. sigslot::signal1<cricket::IceGatheringState> SignalIceGatheringState;
  223. // (mid, candidates)
  224. sigslot::signal2<const std::string&, const std::vector<cricket::Candidate>&>
  225. SignalIceCandidatesGathered;
  226. sigslot::signal1<const cricket::IceCandidateErrorEvent&>
  227. SignalIceCandidateError;
  228. sigslot::signal1<const std::vector<cricket::Candidate>&>
  229. SignalIceCandidatesRemoved;
  230. sigslot::signal1<const cricket::CandidatePairChangeEvent&>
  231. SignalIceCandidatePairChanged;
  232. sigslot::signal1<rtc::SSLHandshakeError> SignalDtlsHandshakeError;
  233. private:
  234. RTCError ApplyDescription_n(bool local,
  235. SdpType type,
  236. const cricket::SessionDescription* description);
  237. RTCError ValidateAndMaybeUpdateBundleGroup(
  238. bool local,
  239. SdpType type,
  240. const cricket::SessionDescription* description);
  241. RTCError ValidateContent(const cricket::ContentInfo& content_info);
  242. void HandleRejectedContent(const cricket::ContentInfo& content_info,
  243. const cricket::SessionDescription* description);
  244. bool HandleBundledContent(const cricket::ContentInfo& content_info);
  245. bool SetTransportForMid(const std::string& mid,
  246. cricket::JsepTransport* jsep_transport);
  247. void RemoveTransportForMid(const std::string& mid);
  248. cricket::JsepTransportDescription CreateJsepTransportDescription(
  249. const cricket::ContentInfo& content_info,
  250. const cricket::TransportInfo& transport_info,
  251. const std::vector<int>& encrypted_extension_ids,
  252. int rtp_abs_sendtime_extn_id,
  253. absl::optional<std::string> media_alt_protocol,
  254. absl::optional<std::string> data_alt_protocol);
  255. absl::optional<std::string> bundled_mid() const {
  256. absl::optional<std::string> bundled_mid;
  257. if (bundle_group_ && bundle_group_->FirstContentName()) {
  258. bundled_mid = *(bundle_group_->FirstContentName());
  259. }
  260. return bundled_mid;
  261. }
  262. bool IsBundled(const std::string& mid) const {
  263. return bundle_group_ && bundle_group_->HasContentName(mid);
  264. }
  265. bool ShouldUpdateBundleGroup(SdpType type,
  266. const cricket::SessionDescription* description);
  267. std::vector<int> MergeEncryptedHeaderExtensionIdsForBundle(
  268. const cricket::SessionDescription* description);
  269. std::vector<int> GetEncryptedHeaderExtensionIds(
  270. const cricket::ContentInfo& content_info);
  271. // Extracts the alt-protocol settings that apply to the bundle group.
  272. RTCError GetAltProtocolsForBundle(
  273. const cricket::SessionDescription* description,
  274. absl::optional<std::string>* media_alt_protocol,
  275. absl::optional<std::string>* data_alt_protocol);
  276. int GetRtpAbsSendTimeHeaderExtensionId(
  277. const cricket::ContentInfo& content_info);
  278. // This method takes the BUNDLE group into account. If the JsepTransport is
  279. // destroyed because of BUNDLE, it would return the transport which other
  280. // transports are bundled on (In current implementation, it is the first
  281. // content in the BUNDLE group).
  282. const cricket::JsepTransport* GetJsepTransportForMid(
  283. const std::string& mid) const;
  284. cricket::JsepTransport* GetJsepTransportForMid(const std::string& mid);
  285. // Get the JsepTransport without considering the BUNDLE group. Return nullptr
  286. // if the JsepTransport is destroyed.
  287. const cricket::JsepTransport* GetJsepTransportByName(
  288. const std::string& transport_name) const;
  289. cricket::JsepTransport* GetJsepTransportByName(
  290. const std::string& transport_name);
  291. // Creates jsep transport. Noop if transport is already created.
  292. // Transport is created either during SetLocalDescription (|local| == true) or
  293. // during SetRemoteDescription (|local| == false). Passing |local| helps to
  294. // differentiate initiator (caller) from answerer (callee).
  295. RTCError MaybeCreateJsepTransport(
  296. bool local,
  297. const cricket::ContentInfo& content_info,
  298. const cricket::SessionDescription& description);
  299. // Creates datagram transport if config wants to use it, and a=x-mt line is
  300. // present for the current media transport. Returned
  301. // DatagramTransportInterface is not connected, and must be connected to ICE.
  302. // You must call |GenerateOrGetLastMediaTransportOffer| on the caller before
  303. // calling MaybeCreateDatagramTransport.
  304. std::unique_ptr<webrtc::DatagramTransportInterface>
  305. MaybeCreateDatagramTransport(const cricket::ContentInfo& content_info,
  306. const cricket::SessionDescription& description,
  307. bool local);
  308. void MaybeDestroyJsepTransport(const std::string& mid);
  309. void DestroyAllJsepTransports_n();
  310. void SetIceRole_n(cricket::IceRole ice_role);
  311. cricket::IceRole DetermineIceRole(
  312. cricket::JsepTransport* jsep_transport,
  313. const cricket::TransportInfo& transport_info,
  314. SdpType type,
  315. bool local);
  316. std::unique_ptr<cricket::DtlsTransportInternal> CreateDtlsTransport(
  317. const cricket::ContentInfo& content_info,
  318. cricket::IceTransportInternal* ice,
  319. DatagramTransportInterface* datagram_transport);
  320. rtc::scoped_refptr<webrtc::IceTransportInterface> CreateIceTransport(
  321. const std::string& transport_name,
  322. bool rtcp);
  323. std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedRtpTransport(
  324. const std::string& transport_name,
  325. rtc::PacketTransportInternal* rtp_packet_transport,
  326. rtc::PacketTransportInternal* rtcp_packet_transport);
  327. std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
  328. const std::string& transport_name,
  329. cricket::DtlsTransportInternal* rtp_dtls_transport,
  330. cricket::DtlsTransportInternal* rtcp_dtls_transport);
  331. std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
  332. const std::string& transport_name,
  333. cricket::DtlsTransportInternal* rtp_dtls_transport,
  334. cricket::DtlsTransportInternal* rtcp_dtls_transport);
  335. // Collect all the DtlsTransports, including RTP and RTCP, from the
  336. // JsepTransports. JsepTransportController can iterate all the DtlsTransports
  337. // and update the aggregate states.
  338. std::vector<cricket::DtlsTransportInternal*> GetDtlsTransports();
  339. // Handlers for signals from Transport.
  340. void OnTransportWritableState_n(rtc::PacketTransportInternal* transport);
  341. void OnTransportReceivingState_n(rtc::PacketTransportInternal* transport);
  342. void OnTransportGatheringState_n(cricket::IceTransportInternal* transport);
  343. void OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport,
  344. const cricket::Candidate& candidate);
  345. void OnTransportCandidateError_n(
  346. cricket::IceTransportInternal* transport,
  347. const cricket::IceCandidateErrorEvent& event);
  348. void OnTransportCandidatesRemoved_n(cricket::IceTransportInternal* transport,
  349. const cricket::Candidates& candidates);
  350. void OnTransportRoleConflict_n(cricket::IceTransportInternal* transport);
  351. void OnTransportStateChanged_n(cricket::IceTransportInternal* transport);
  352. void OnTransportCandidatePairChanged_n(
  353. const cricket::CandidatePairChangeEvent& event);
  354. void OnDataChannelTransportNegotiated_n(
  355. cricket::JsepTransport* transport,
  356. DataChannelTransportInterface* data_channel_transport);
  357. void UpdateAggregateStates_n();
  358. void OnRtcpPacketReceived_n(rtc::CopyOnWriteBuffer* packet,
  359. int64_t packet_time_us);
  360. void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
  361. rtc::Thread* const signaling_thread_ = nullptr;
  362. rtc::Thread* const network_thread_ = nullptr;
  363. cricket::PortAllocator* const port_allocator_ = nullptr;
  364. AsyncResolverFactory* const async_resolver_factory_ = nullptr;
  365. std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
  366. jsep_transports_by_name_;
  367. // This keeps track of the mapping between media section
  368. // (BaseChannel/SctpTransport) and the JsepTransport underneath.
  369. std::map<std::string, cricket::JsepTransport*> mid_to_transport_;
  370. // Keep track of mids that have been mapped to transports. Used for rollback.
  371. std::vector<std::string> pending_mids_ RTC_GUARDED_BY(network_thread_);
  372. // Aggregate states for Transports.
  373. // standardized_ice_connection_state_ is intended to replace
  374. // ice_connection_state, see bugs.webrtc.org/9308
  375. cricket::IceConnectionState ice_connection_state_ =
  376. cricket::kIceConnectionConnecting;
  377. PeerConnectionInterface::IceConnectionState
  378. standardized_ice_connection_state_ =
  379. PeerConnectionInterface::kIceConnectionNew;
  380. PeerConnectionInterface::PeerConnectionState combined_connection_state_ =
  381. PeerConnectionInterface::PeerConnectionState::kNew;
  382. cricket::IceGatheringState ice_gathering_state_ = cricket::kIceGatheringNew;
  383. Config config_;
  384. // Early on in the call we don't know if datagram transport is going to be
  385. // used, but we need to get the server-supported parameters to add to an SDP.
  386. // This server datagram transport will be promoted to the used datagram
  387. // transport after the local description is set, and the ownership will be
  388. // transferred to the actual JsepTransport. This "offer" datagram transport is
  389. // not created if it's done on the party that provides answer. This offer
  390. // datagram transport is only created once at the beginning of the connection,
  391. // and never again.
  392. std::unique_ptr<DatagramTransportInterface> offer_datagram_transport_ =
  393. nullptr;
  394. const cricket::SessionDescription* local_desc_ = nullptr;
  395. const cricket::SessionDescription* remote_desc_ = nullptr;
  396. absl::optional<bool> initial_offerer_;
  397. absl::optional<cricket::ContentGroup> bundle_group_;
  398. cricket::IceConfig ice_config_;
  399. cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING;
  400. uint64_t ice_tiebreaker_ = rtc::CreateRandomId64();
  401. rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
  402. rtc::AsyncInvoker invoker_;
  403. RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController);
  404. };
  405. } // namespace webrtc
  406. #endif // PC_JSEP_TRANSPORT_CONTROLLER_H_