jsep_transport.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /*
  2. * Copyright 2018 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_H_
  11. #define PC_JSEP_TRANSPORT_H_
  12. #include <map>
  13. #include <memory>
  14. #include <string>
  15. #include <vector>
  16. #include "absl/types/optional.h"
  17. #include "api/candidate.h"
  18. #include "api/ice_transport_interface.h"
  19. #include "api/jsep.h"
  20. #include "api/transport/datagram_transport_interface.h"
  21. #include "media/sctp/sctp_transport_internal.h"
  22. #include "p2p/base/dtls_transport.h"
  23. #include "p2p/base/p2p_constants.h"
  24. #include "p2p/base/transport_info.h"
  25. #include "pc/composite_data_channel_transport.h"
  26. #include "pc/composite_rtp_transport.h"
  27. #include "pc/dtls_srtp_transport.h"
  28. #include "pc/dtls_transport.h"
  29. #include "pc/rtcp_mux_filter.h"
  30. #include "pc/rtp_transport.h"
  31. #include "pc/sctp_transport.h"
  32. #include "pc/session_description.h"
  33. #include "pc/srtp_filter.h"
  34. #include "pc/srtp_transport.h"
  35. #include "pc/transport_stats.h"
  36. #include "rtc_base/constructor_magic.h"
  37. #include "rtc_base/rtc_certificate.h"
  38. #include "rtc_base/ssl_stream_adapter.h"
  39. #include "rtc_base/third_party/sigslot/sigslot.h"
  40. #include "rtc_base/thread_checker.h"
  41. namespace cricket {
  42. class DtlsTransportInternal;
  43. struct JsepTransportDescription {
  44. public:
  45. JsepTransportDescription();
  46. JsepTransportDescription(
  47. bool rtcp_mux_enabled,
  48. const std::vector<CryptoParams>& cryptos,
  49. const std::vector<int>& encrypted_header_extension_ids,
  50. int rtp_abs_sendtime_extn_id,
  51. const TransportDescription& transport_description,
  52. absl::optional<std::string> media_alt_protocol,
  53. absl::optional<std::string> data_alt_protocol);
  54. JsepTransportDescription(const JsepTransportDescription& from);
  55. ~JsepTransportDescription();
  56. JsepTransportDescription& operator=(const JsepTransportDescription& from);
  57. bool rtcp_mux_enabled = true;
  58. std::vector<CryptoParams> cryptos;
  59. std::vector<int> encrypted_header_extension_ids;
  60. int rtp_abs_sendtime_extn_id = -1;
  61. // TODO(zhihuang): Add the ICE and DTLS related variables and methods from
  62. // TransportDescription and remove this extra layer of abstraction.
  63. TransportDescription transport_desc;
  64. // Alt-protocols that apply to this JsepTransport. Presence indicates a
  65. // request to use an alternative protocol for media and/or data. The
  66. // alt-protocol is handled by a datagram transport. If one or both of these
  67. // values are present, JsepTransport will attempt to negotiate use of the
  68. // datagram transport for media and/or data.
  69. absl::optional<std::string> media_alt_protocol;
  70. absl::optional<std::string> data_alt_protocol;
  71. };
  72. // Helper class used by JsepTransportController that processes
  73. // TransportDescriptions. A TransportDescription represents the
  74. // transport-specific properties of an SDP m= section, processed according to
  75. // JSEP. Each transport consists of DTLS and ICE transport channels for RTP
  76. // (and possibly RTCP, if rtcp-mux isn't used).
  77. //
  78. // On Threading: JsepTransport performs work solely on the network thread, and
  79. // so its methods should only be called on the network thread.
  80. class JsepTransport : public sigslot::has_slots<> {
  81. public:
  82. // |mid| is just used for log statements in order to identify the Transport.
  83. // Note that |local_certificate| is allowed to be null since a remote
  84. // description may be set before a local certificate is generated.
  85. JsepTransport(
  86. const std::string& mid,
  87. const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate,
  88. rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport,
  89. rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice_transport,
  90. std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport,
  91. std::unique_ptr<webrtc::SrtpTransport> sdes_transport,
  92. std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport,
  93. std::unique_ptr<webrtc::RtpTransportInternal> datagram_rtp_transport,
  94. std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
  95. std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
  96. std::unique_ptr<SctpTransportInternal> sctp_transport,
  97. std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport,
  98. webrtc::DataChannelTransportInterface* data_channel_transport);
  99. ~JsepTransport() override;
  100. // Returns the MID of this transport. This is only used for logging.
  101. const std::string& mid() const { return mid_; }
  102. // Must be called before applying local session description.
  103. // Needed in order to verify the local fingerprint.
  104. void SetLocalCertificate(
  105. const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate) {
  106. RTC_DCHECK_RUN_ON(network_thread_);
  107. local_certificate_ = local_certificate;
  108. }
  109. // Return the local certificate provided by SetLocalCertificate.
  110. rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const {
  111. RTC_DCHECK_RUN_ON(network_thread_);
  112. return local_certificate_;
  113. }
  114. webrtc::RTCError SetLocalJsepTransportDescription(
  115. const JsepTransportDescription& jsep_description,
  116. webrtc::SdpType type) RTC_LOCKS_EXCLUDED(accessor_lock_);
  117. // Set the remote TransportDescription to be used by DTLS and ICE channels
  118. // that are part of this Transport.
  119. webrtc::RTCError SetRemoteJsepTransportDescription(
  120. const JsepTransportDescription& jsep_description,
  121. webrtc::SdpType type) RTC_LOCKS_EXCLUDED(accessor_lock_);
  122. webrtc::RTCError AddRemoteCandidates(const Candidates& candidates)
  123. RTC_LOCKS_EXCLUDED(accessor_lock_);
  124. // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
  125. // set, offers should generate new ufrags/passwords until an ICE restart
  126. // occurs.
  127. //
  128. // This and the below method can be called safely from any thread as long as
  129. // SetXTransportDescription is not in progress.
  130. void SetNeedsIceRestartFlag() RTC_LOCKS_EXCLUDED(accessor_lock_);
  131. // Returns true if the ICE restart flag above was set, and no ICE restart has
  132. // occurred yet for this transport (by applying a local description with
  133. // changed ufrag/password).
  134. bool needs_ice_restart() const RTC_LOCKS_EXCLUDED(accessor_lock_) {
  135. rtc::CritScope scope(&accessor_lock_);
  136. return needs_ice_restart_;
  137. }
  138. // Returns role if negotiated, or empty absl::optional if it hasn't been
  139. // negotiated yet.
  140. absl::optional<rtc::SSLRole> GetDtlsRole() const
  141. RTC_LOCKS_EXCLUDED(accessor_lock_);
  142. absl::optional<OpaqueTransportParameters> GetTransportParameters() const
  143. RTC_LOCKS_EXCLUDED(accessor_lock_);
  144. // TODO(deadbeef): Make this const. See comment in transportcontroller.h.
  145. bool GetStats(TransportStats* stats) RTC_LOCKS_EXCLUDED(accessor_lock_);
  146. const JsepTransportDescription* local_description() const {
  147. RTC_DCHECK_RUN_ON(network_thread_);
  148. return local_description_.get();
  149. }
  150. const JsepTransportDescription* remote_description() const {
  151. RTC_DCHECK_RUN_ON(network_thread_);
  152. return remote_description_.get();
  153. }
  154. webrtc::RtpTransportInternal* rtp_transport() const
  155. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  156. rtc::CritScope scope(&accessor_lock_);
  157. if (composite_rtp_transport_) {
  158. return composite_rtp_transport_.get();
  159. } else if (datagram_rtp_transport_) {
  160. return datagram_rtp_transport_.get();
  161. } else {
  162. return default_rtp_transport();
  163. }
  164. }
  165. const DtlsTransportInternal* rtp_dtls_transport() const
  166. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  167. rtc::CritScope scope(&accessor_lock_);
  168. if (rtp_dtls_transport_) {
  169. return rtp_dtls_transport_->internal();
  170. } else {
  171. return nullptr;
  172. }
  173. }
  174. DtlsTransportInternal* rtp_dtls_transport()
  175. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  176. rtc::CritScope scope(&accessor_lock_);
  177. return rtp_dtls_transport_locked();
  178. }
  179. const DtlsTransportInternal* rtcp_dtls_transport() const
  180. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  181. rtc::CritScope scope(&accessor_lock_);
  182. if (rtcp_dtls_transport_) {
  183. return rtcp_dtls_transport_->internal();
  184. } else {
  185. return nullptr;
  186. }
  187. }
  188. DtlsTransportInternal* rtcp_dtls_transport()
  189. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  190. rtc::CritScope scope(&accessor_lock_);
  191. if (rtcp_dtls_transport_) {
  192. return rtcp_dtls_transport_->internal();
  193. } else {
  194. return nullptr;
  195. }
  196. }
  197. rtc::scoped_refptr<webrtc::DtlsTransport> RtpDtlsTransport()
  198. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  199. rtc::CritScope scope(&accessor_lock_);
  200. return rtp_dtls_transport_;
  201. }
  202. rtc::scoped_refptr<webrtc::SctpTransport> SctpTransport() const
  203. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  204. rtc::CritScope scope(&accessor_lock_);
  205. return sctp_transport_;
  206. }
  207. webrtc::DataChannelTransportInterface* data_channel_transport() const
  208. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  209. rtc::CritScope scope(&accessor_lock_);
  210. if (composite_data_channel_transport_) {
  211. return composite_data_channel_transport_.get();
  212. } else if (sctp_data_channel_transport_) {
  213. return sctp_data_channel_transport_.get();
  214. }
  215. return data_channel_transport_;
  216. }
  217. // Returns datagram transport, if available.
  218. webrtc::DatagramTransportInterface* datagram_transport() const
  219. RTC_LOCKS_EXCLUDED(accessor_lock_) {
  220. rtc::CritScope scope(&accessor_lock_);
  221. return datagram_transport_.get();
  222. }
  223. // This is signaled when RTCP-mux becomes active and
  224. // |rtcp_dtls_transport_| is destroyed. The JsepTransportController will
  225. // handle the signal and update the aggregate transport states.
  226. sigslot::signal<> SignalRtcpMuxActive;
  227. // Signals that a data channel transport was negotiated and may be used to
  228. // send data. The first parameter is |this|. The second parameter is the
  229. // transport that was negotiated, or null if negotiation rejected the data
  230. // channel transport. The third parameter (bool) indicates whether the
  231. // negotiation was provisional or final. If true, it is provisional, if
  232. // false, it is final.
  233. sigslot::signal2<JsepTransport*, webrtc::DataChannelTransportInterface*>
  234. SignalDataChannelTransportNegotiated;
  235. // TODO(deadbeef): The methods below are only public for testing. Should make
  236. // them utility functions or objects so they can be tested independently from
  237. // this class.
  238. // Returns an error if the certificate's identity does not match the
  239. // fingerprint, or either is NULL.
  240. webrtc::RTCError VerifyCertificateFingerprint(
  241. const rtc::RTCCertificate* certificate,
  242. const rtc::SSLFingerprint* fingerprint) const;
  243. void SetActiveResetSrtpParams(bool active_reset_srtp_params);
  244. private:
  245. DtlsTransportInternal* rtp_dtls_transport_locked()
  246. RTC_EXCLUSIVE_LOCKS_REQUIRED(accessor_lock_) {
  247. if (rtp_dtls_transport_) {
  248. return rtp_dtls_transport_->internal();
  249. } else {
  250. return nullptr;
  251. }
  252. }
  253. bool SetRtcpMux(bool enable, webrtc::SdpType type, ContentSource source);
  254. void ActivateRtcpMux();
  255. bool SetSdes(const std::vector<CryptoParams>& cryptos,
  256. const std::vector<int>& encrypted_extension_ids,
  257. webrtc::SdpType type,
  258. ContentSource source)
  259. RTC_EXCLUSIVE_LOCKS_REQUIRED(accessor_lock_);
  260. // Negotiates and sets the DTLS parameters based on the current local and
  261. // remote transport description, such as the DTLS role to use, and whether
  262. // DTLS should be activated.
  263. //
  264. // Called when an answer TransportDescription is applied.
  265. webrtc::RTCError NegotiateAndSetDtlsParameters(
  266. webrtc::SdpType local_description_type);
  267. // Negotiates the DTLS role based off the offer and answer as specified by
  268. // RFC 4145, section-4.1. Returns an RTCError if role cannot be determined
  269. // from the local description and remote description.
  270. webrtc::RTCError NegotiateDtlsRole(
  271. webrtc::SdpType local_description_type,
  272. ConnectionRole local_connection_role,
  273. ConnectionRole remote_connection_role,
  274. absl::optional<rtc::SSLRole>* negotiated_dtls_role)
  275. RTC_LOCKS_EXCLUDED(accessor_lock_);
  276. // Pushes down the ICE parameters from the remote description.
  277. void SetRemoteIceParameters(const IceParameters& ice_parameters,
  278. IceTransportInternal* ice);
  279. // Pushes down the DTLS parameters obtained via negotiation.
  280. static webrtc::RTCError SetNegotiatedDtlsParameters(
  281. DtlsTransportInternal* dtls_transport,
  282. absl::optional<rtc::SSLRole> dtls_role,
  283. rtc::SSLFingerprint* remote_fingerprint);
  284. bool GetTransportStats(DtlsTransportInternal* dtls_transport,
  285. TransportStats* stats)
  286. RTC_EXCLUSIVE_LOCKS_REQUIRED(accessor_lock_);
  287. // Deactivates, signals removal, and deletes |composite_rtp_transport_| if the
  288. // current state of negotiation is sufficient to determine which rtp_transport
  289. // and data channel transport to use.
  290. void NegotiateDatagramTransport(webrtc::SdpType type)
  291. RTC_RUN_ON(network_thread_) RTC_LOCKS_EXCLUDED(accessor_lock_);
  292. // Returns the default (non-datagram) rtp transport, if any.
  293. webrtc::RtpTransportInternal* default_rtp_transport() const
  294. RTC_EXCLUSIVE_LOCKS_REQUIRED(accessor_lock_) {
  295. if (dtls_srtp_transport_) {
  296. return dtls_srtp_transport_.get();
  297. } else if (sdes_transport_) {
  298. return sdes_transport_.get();
  299. } else if (unencrypted_rtp_transport_) {
  300. return unencrypted_rtp_transport_.get();
  301. } else {
  302. return nullptr;
  303. }
  304. }
  305. // Owning thread, for safety checks
  306. const rtc::Thread* const network_thread_;
  307. // Critical scope for fields accessed off-thread
  308. // TODO(https://bugs.webrtc.org/10300): Stop doing this.
  309. rtc::CriticalSection accessor_lock_;
  310. const std::string mid_;
  311. // needs-ice-restart bit as described in JSEP.
  312. bool needs_ice_restart_ RTC_GUARDED_BY(accessor_lock_) = false;
  313. rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_
  314. RTC_GUARDED_BY(network_thread_);
  315. std::unique_ptr<JsepTransportDescription> local_description_
  316. RTC_GUARDED_BY(network_thread_);
  317. std::unique_ptr<JsepTransportDescription> remote_description_
  318. RTC_GUARDED_BY(network_thread_);
  319. // Ice transport which may be used by any of upper-layer transports (below).
  320. // Owned by JsepTransport and guaranteed to outlive the transports below.
  321. const rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_;
  322. const rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice_transport_;
  323. // To avoid downcasting and make it type safe, keep three unique pointers for
  324. // different SRTP mode and only one of these is non-nullptr.
  325. std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport_
  326. RTC_GUARDED_BY(accessor_lock_);
  327. std::unique_ptr<webrtc::SrtpTransport> sdes_transport_
  328. RTC_GUARDED_BY(accessor_lock_);
  329. std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport_
  330. RTC_GUARDED_BY(accessor_lock_);
  331. // If multiple RTP transports are in use, |composite_rtp_transport_| will be
  332. // passed to callers. This is only valid for offer-only, receive-only
  333. // scenarios, as it is not possible for the composite to correctly choose
  334. // which transport to use for sending.
  335. std::unique_ptr<webrtc::CompositeRtpTransport> composite_rtp_transport_
  336. RTC_GUARDED_BY(accessor_lock_);
  337. rtc::scoped_refptr<webrtc::DtlsTransport> rtp_dtls_transport_
  338. RTC_GUARDED_BY(accessor_lock_);
  339. rtc::scoped_refptr<webrtc::DtlsTransport> rtcp_dtls_transport_
  340. RTC_GUARDED_BY(accessor_lock_);
  341. rtc::scoped_refptr<webrtc::DtlsTransport> datagram_dtls_transport_
  342. RTC_GUARDED_BY(accessor_lock_);
  343. std::unique_ptr<webrtc::DataChannelTransportInterface>
  344. sctp_data_channel_transport_ RTC_GUARDED_BY(accessor_lock_);
  345. rtc::scoped_refptr<webrtc::SctpTransport> sctp_transport_
  346. RTC_GUARDED_BY(accessor_lock_);
  347. SrtpFilter sdes_negotiator_ RTC_GUARDED_BY(network_thread_);
  348. RtcpMuxFilter rtcp_mux_negotiator_ RTC_GUARDED_BY(network_thread_);
  349. // Cache the encrypted header extension IDs for SDES negoitation.
  350. absl::optional<std::vector<int>> send_extension_ids_
  351. RTC_GUARDED_BY(network_thread_);
  352. absl::optional<std::vector<int>> recv_extension_ids_
  353. RTC_GUARDED_BY(network_thread_);
  354. // Optional datagram transport (experimental).
  355. std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport_
  356. RTC_GUARDED_BY(accessor_lock_);
  357. std::unique_ptr<webrtc::RtpTransportInternal> datagram_rtp_transport_
  358. RTC_GUARDED_BY(accessor_lock_);
  359. // Non-SCTP data channel transport. Set to |datagram_transport_| if that
  360. // transport should be used for data chanels. Unset otherwise.
  361. webrtc::DataChannelTransportInterface* data_channel_transport_
  362. RTC_GUARDED_BY(accessor_lock_) = nullptr;
  363. // Composite data channel transport, used during negotiation.
  364. std::unique_ptr<webrtc::CompositeDataChannelTransport>
  365. composite_data_channel_transport_ RTC_GUARDED_BY(accessor_lock_);
  366. RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
  367. };
  368. } // namespace cricket
  369. #endif // PC_JSEP_TRANSPORT_H_