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 11 #ifndef PC_JSEP_TRANSPORT_CONTROLLER_H_ 12 #define PC_JSEP_TRANSPORT_CONTROLLER_H_ 13 14 #include <stdint.h> 15 16 #include <functional> 17 #include <map> 18 #include <memory> 19 #include <string> 20 #include <type_traits> 21 #include <utility> 22 #include <vector> 23 24 #include "absl/types/optional.h" 25 #include "api/async_dns_resolver.h" 26 #include "api/candidate.h" 27 #include "api/crypto/crypto_options.h" 28 #include "api/ice_transport_factory.h" 29 #include "api/ice_transport_interface.h" 30 #include "api/jsep.h" 31 #include "api/peer_connection_interface.h" 32 #include "api/rtc_error.h" 33 #include "api/rtc_event_log/rtc_event_log.h" 34 #include "api/scoped_refptr.h" 35 #include "api/sequence_checker.h" 36 #include "api/transport/data_channel_transport_interface.h" 37 #include "api/transport/sctp_transport_factory_interface.h" 38 #include "media/sctp/sctp_transport_internal.h" 39 #include "p2p/base/dtls_transport.h" 40 #include "p2p/base/dtls_transport_factory.h" 41 #include "p2p/base/dtls_transport_internal.h" 42 #include "p2p/base/ice_transport_internal.h" 43 #include "p2p/base/p2p_transport_channel.h" 44 #include "p2p/base/packet_transport_internal.h" 45 #include "p2p/base/port.h" 46 #include "p2p/base/port_allocator.h" 47 #include "p2p/base/transport_description.h" 48 #include "p2p/base/transport_info.h" 49 #include "pc/dtls_srtp_transport.h" 50 #include "pc/dtls_transport.h" 51 #include "pc/jsep_transport.h" 52 #include "pc/jsep_transport_collection.h" 53 #include "pc/rtp_transport.h" 54 #include "pc/rtp_transport_internal.h" 55 #include "pc/sctp_transport.h" 56 #include "pc/session_description.h" 57 #include "pc/srtp_transport.h" 58 #include "pc/transport_stats.h" 59 #include "rtc_base/callback_list.h" 60 #include "rtc_base/checks.h" 61 #include "rtc_base/copy_on_write_buffer.h" 62 #include "rtc_base/helpers.h" 63 #include "rtc_base/rtc_certificate.h" 64 #include "rtc_base/ssl_certificate.h" 65 #include "rtc_base/ssl_stream_adapter.h" 66 #include "rtc_base/third_party/sigslot/sigslot.h" 67 #include "rtc_base/thread.h" 68 #include "rtc_base/thread_annotations.h" 69 70 namespace rtc { 71 class Thread; 72 class PacketTransportInternal; 73 } // namespace rtc 74 75 namespace webrtc { 76 77 class JsepTransportController : public sigslot::has_slots<> { 78 public: 79 // Used when the RtpTransport/DtlsTransport of the m= section is changed 80 // because the section is rejected or BUNDLE is enabled. 81 class Observer { 82 public: ~Observer()83 virtual ~Observer() {} 84 85 // Returns true if media associated with `mid` was successfully set up to be 86 // demultiplexed on `rtp_transport`. Could return false if two bundled m= 87 // sections use the same SSRC, for example. 88 // 89 // If a data channel transport must be negotiated, `data_channel_transport` 90 // and `negotiation_state` indicate negotiation status. If 91 // `data_channel_transport` is null, the data channel transport should not 92 // be used. Otherwise, the value is a pointer to the transport to be used 93 // for data channels on `mid`, if any. 94 // 95 // The observer should not send data on `data_channel_transport` until 96 // `negotiation_state` is provisional or final. It should not delete 97 // `data_channel_transport` or any fallback transport until 98 // `negotiation_state` is final. 99 virtual bool OnTransportChanged( 100 const std::string& mid, 101 RtpTransportInternal* rtp_transport, 102 rtc::scoped_refptr<DtlsTransport> dtls_transport, 103 DataChannelTransportInterface* data_channel_transport) = 0; 104 }; 105 106 struct Config { 107 // If `redetermine_role_on_ice_restart` is true, ICE role is redetermined 108 // upon setting a local transport description that indicates an ICE 109 // restart. 110 bool redetermine_role_on_ice_restart = true; 111 rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; 112 // `crypto_options` is used to determine if created DTLS transports 113 // negotiate GCM crypto suites or not. 114 webrtc::CryptoOptions crypto_options; 115 PeerConnectionInterface::BundlePolicy bundle_policy = 116 PeerConnectionInterface::kBundlePolicyBalanced; 117 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy = 118 PeerConnectionInterface::kRtcpMuxPolicyRequire; 119 bool disable_encryption = false; 120 bool enable_external_auth = false; 121 // Used to inject the ICE/DTLS transports created externally. 122 webrtc::IceTransportFactory* ice_transport_factory = nullptr; 123 cricket::DtlsTransportFactory* dtls_transport_factory = nullptr; 124 Observer* transport_observer = nullptr; 125 // Must be provided and valid for the lifetime of the 126 // JsepTransportController instance. 127 std::function<void(const rtc::CopyOnWriteBuffer& packet, 128 int64_t packet_time_us)> 129 rtcp_handler; 130 // Initial value for whether DtlsTransport reset causes a reset 131 // of SRTP parameters. 132 bool active_reset_srtp_params = false; 133 RtcEventLog* event_log = nullptr; 134 135 // Factory for SCTP transports. 136 SctpTransportFactoryInterface* sctp_factory = nullptr; 137 std::function<void(rtc::SSLHandshakeError)> on_dtls_handshake_error_; 138 139 // Field trials. 140 const webrtc::FieldTrialsView* field_trials; 141 }; 142 143 // The ICE related events are fired on the `network_thread`. 144 // All the transport related methods are called on the `network_thread` 145 // and destruction of the JsepTransportController must occur on the 146 // `network_thread`. 147 JsepTransportController( 148 rtc::Thread* network_thread, 149 cricket::PortAllocator* port_allocator, 150 AsyncDnsResolverFactoryInterface* async_dns_resolver_factory, 151 Config config); 152 virtual ~JsepTransportController(); 153 154 JsepTransportController(const JsepTransportController&) = delete; 155 JsepTransportController& operator=(const JsepTransportController&) = delete; 156 157 // The main method to be called; applies a description at the transport 158 // level, creating/destroying transport objects as needed and updating their 159 // properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not 160 // yet? May make sense to in the future. 161 RTCError SetLocalDescription(SdpType type, 162 const cricket::SessionDescription* description); 163 164 RTCError SetRemoteDescription(SdpType type, 165 const cricket::SessionDescription* description); 166 167 // Get transports to be used for the provided `mid`. If bundling is enabled, 168 // calling GetRtpTransport for multiple MIDs may yield the same object. 169 RtpTransportInternal* GetRtpTransport(absl::string_view mid) const; 170 cricket::DtlsTransportInternal* GetDtlsTransport(const std::string& mid); 171 const cricket::DtlsTransportInternal* GetRtcpDtlsTransport( 172 const std::string& mid) const; 173 // Gets the externally sharable version of the DtlsTransport. 174 rtc::scoped_refptr<webrtc::DtlsTransport> LookupDtlsTransportByMid( 175 const std::string& mid); 176 rtc::scoped_refptr<SctpTransport> GetSctpTransport( 177 const std::string& mid) const; 178 179 DataChannelTransportInterface* GetDataChannelTransport( 180 const std::string& mid) const; 181 182 /********************* 183 * ICE-related methods 184 ********************/ 185 // This method is public to allow PeerConnection to update it from 186 // SetConfiguration. 187 void SetIceConfig(const cricket::IceConfig& config); 188 // Set the "needs-ice-restart" flag as described in JSEP. After the flag is 189 // set, offers should generate new ufrags/passwords until an ICE restart 190 // occurs. 191 void SetNeedsIceRestartFlag(); 192 // Returns true if the ICE restart flag above was set, and no ICE restart has 193 // occurred yet for this transport (by applying a local description with 194 // changed ufrag/password). If the transport has been deleted as a result of 195 // bundling, returns false. 196 bool NeedsIceRestart(const std::string& mid) const; 197 // Start gathering candidates for any new transports, or transports doing an 198 // ICE restart. 199 void MaybeStartGathering(); 200 RTCError AddRemoteCandidates( 201 const std::string& mid, 202 const std::vector<cricket::Candidate>& candidates); 203 RTCError RemoveRemoteCandidates( 204 const std::vector<cricket::Candidate>& candidates); 205 206 /********************** 207 * DTLS-related methods 208 *********************/ 209 // Specifies the identity to use in this session. 210 // Can only be called once. 211 bool SetLocalCertificate( 212 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); 213 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate( 214 const std::string& mid) const; 215 // Caller owns returned certificate chain. This method mainly exists for 216 // stats reporting. 217 std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain( 218 const std::string& mid) const; 219 // Get negotiated role, if one has been negotiated. 220 absl::optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const; 221 222 // TODO(deadbeef): GetStats isn't const because all the way down to 223 // OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not 224 // const. Fix this. 225 bool GetStats(const std::string& mid, cricket::TransportStats* stats); 226 initial_offerer()227 bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; } 228 229 void SetActiveResetSrtpParams(bool active_reset_srtp_params); 230 231 RTCError RollbackTransports(); 232 233 // F: void(const std::string&, const std::vector<cricket::Candidate>&) 234 template <typename F> SubscribeIceCandidateGathered(F && callback)235 void SubscribeIceCandidateGathered(F&& callback) { 236 RTC_DCHECK_RUN_ON(network_thread_); 237 signal_ice_candidates_gathered_.AddReceiver(std::forward<F>(callback)); 238 } 239 240 // F: void(cricket::IceConnectionState) 241 template <typename F> SubscribeIceConnectionState(F && callback)242 void SubscribeIceConnectionState(F&& callback) { 243 RTC_DCHECK_RUN_ON(network_thread_); 244 signal_ice_connection_state_.AddReceiver(std::forward<F>(callback)); 245 } 246 247 // F: void(PeerConnectionInterface::PeerConnectionState) 248 template <typename F> SubscribeConnectionState(F && callback)249 void SubscribeConnectionState(F&& callback) { 250 RTC_DCHECK_RUN_ON(network_thread_); 251 signal_connection_state_.AddReceiver(std::forward<F>(callback)); 252 } 253 254 // F: void(PeerConnectionInterface::IceConnectionState) 255 template <typename F> SubscribeStandardizedIceConnectionState(F && callback)256 void SubscribeStandardizedIceConnectionState(F&& callback) { 257 RTC_DCHECK_RUN_ON(network_thread_); 258 signal_standardized_ice_connection_state_.AddReceiver( 259 std::forward<F>(callback)); 260 } 261 262 // F: void(cricket::IceGatheringState) 263 template <typename F> SubscribeIceGatheringState(F && callback)264 void SubscribeIceGatheringState(F&& callback) { 265 RTC_DCHECK_RUN_ON(network_thread_); 266 signal_ice_gathering_state_.AddReceiver(std::forward<F>(callback)); 267 } 268 269 // F: void(const cricket::IceCandidateErrorEvent&) 270 template <typename F> SubscribeIceCandidateError(F && callback)271 void SubscribeIceCandidateError(F&& callback) { 272 RTC_DCHECK_RUN_ON(network_thread_); 273 signal_ice_candidate_error_.AddReceiver(std::forward<F>(callback)); 274 } 275 276 // F: void(const std::vector<cricket::Candidate>&) 277 template <typename F> SubscribeIceCandidatesRemoved(F && callback)278 void SubscribeIceCandidatesRemoved(F&& callback) { 279 RTC_DCHECK_RUN_ON(network_thread_); 280 signal_ice_candidates_removed_.AddReceiver(std::forward<F>(callback)); 281 } 282 283 // F: void(const cricket::CandidatePairChangeEvent&) 284 template <typename F> SubscribeIceCandidatePairChanged(F && callback)285 void SubscribeIceCandidatePairChanged(F&& callback) { 286 RTC_DCHECK_RUN_ON(network_thread_); 287 signal_ice_candidate_pair_changed_.AddReceiver(std::forward<F>(callback)); 288 } 289 290 private: 291 // All of these callbacks are fired on the network thread. 292 293 // If any transport failed => failed, 294 // Else if all completed => completed, 295 // Else if all connected => connected, 296 // Else => connecting 297 CallbackList<cricket::IceConnectionState> signal_ice_connection_state_ 298 RTC_GUARDED_BY(network_thread_); 299 300 CallbackList<PeerConnectionInterface::PeerConnectionState> 301 signal_connection_state_ RTC_GUARDED_BY(network_thread_); 302 303 CallbackList<PeerConnectionInterface::IceConnectionState> 304 signal_standardized_ice_connection_state_ RTC_GUARDED_BY(network_thread_); 305 306 // If all transports done gathering => complete, 307 // Else if any are gathering => gathering, 308 // Else => new 309 CallbackList<cricket::IceGatheringState> signal_ice_gathering_state_ 310 RTC_GUARDED_BY(network_thread_); 311 312 // [mid, candidates] 313 CallbackList<const std::string&, const std::vector<cricket::Candidate>&> 314 signal_ice_candidates_gathered_ RTC_GUARDED_BY(network_thread_); 315 316 CallbackList<const cricket::IceCandidateErrorEvent&> 317 signal_ice_candidate_error_ RTC_GUARDED_BY(network_thread_); 318 319 CallbackList<const std::vector<cricket::Candidate>&> 320 signal_ice_candidates_removed_ RTC_GUARDED_BY(network_thread_); 321 322 CallbackList<const cricket::CandidatePairChangeEvent&> 323 signal_ice_candidate_pair_changed_ RTC_GUARDED_BY(network_thread_); 324 325 RTCError ApplyDescription_n(bool local, 326 SdpType type, 327 const cricket::SessionDescription* description) 328 RTC_RUN_ON(network_thread_); 329 RTCError ValidateAndMaybeUpdateBundleGroups( 330 bool local, 331 SdpType type, 332 const cricket::SessionDescription* description); 333 RTCError ValidateContent(const cricket::ContentInfo& content_info); 334 335 void HandleRejectedContent(const cricket::ContentInfo& content_info) 336 RTC_RUN_ON(network_thread_); 337 bool HandleBundledContent(const cricket::ContentInfo& content_info, 338 const cricket::ContentGroup& bundle_group) 339 RTC_RUN_ON(network_thread_); 340 341 cricket::JsepTransportDescription CreateJsepTransportDescription( 342 const cricket::ContentInfo& content_info, 343 const cricket::TransportInfo& transport_info, 344 const std::vector<int>& encrypted_extension_ids, 345 int rtp_abs_sendtime_extn_id); 346 347 std::map<const cricket::ContentGroup*, std::vector<int>> 348 MergeEncryptedHeaderExtensionIdsForBundles( 349 const cricket::SessionDescription* description); 350 std::vector<int> GetEncryptedHeaderExtensionIds( 351 const cricket::ContentInfo& content_info); 352 353 int GetRtpAbsSendTimeHeaderExtensionId( 354 const cricket::ContentInfo& content_info); 355 356 // This method takes the BUNDLE group into account. If the JsepTransport is 357 // destroyed because of BUNDLE, it would return the transport which other 358 // transports are bundled on (In current implementation, it is the first 359 // content in the BUNDLE group). 360 const cricket::JsepTransport* GetJsepTransportForMid( 361 const std::string& mid) const RTC_RUN_ON(network_thread_); 362 cricket::JsepTransport* GetJsepTransportForMid(const std::string& mid) 363 RTC_RUN_ON(network_thread_); 364 const cricket::JsepTransport* GetJsepTransportForMid( 365 absl::string_view mid) const RTC_RUN_ON(network_thread_); 366 cricket::JsepTransport* GetJsepTransportForMid(absl::string_view mid) 367 RTC_RUN_ON(network_thread_); 368 369 // Get the JsepTransport without considering the BUNDLE group. Return nullptr 370 // if the JsepTransport is destroyed. 371 const cricket::JsepTransport* GetJsepTransportByName( 372 const std::string& transport_name) const RTC_RUN_ON(network_thread_); 373 cricket::JsepTransport* GetJsepTransportByName( 374 const std::string& transport_name) RTC_RUN_ON(network_thread_); 375 376 // Creates jsep transport. Noop if transport is already created. 377 // Transport is created either during SetLocalDescription (`local` == true) or 378 // during SetRemoteDescription (`local` == false). Passing `local` helps to 379 // differentiate initiator (caller) from answerer (callee). 380 RTCError MaybeCreateJsepTransport( 381 bool local, 382 const cricket::ContentInfo& content_info, 383 const cricket::SessionDescription& description) 384 RTC_RUN_ON(network_thread_); 385 386 void DestroyAllJsepTransports_n() RTC_RUN_ON(network_thread_); 387 388 void SetIceRole_n(cricket::IceRole ice_role) RTC_RUN_ON(network_thread_); 389 390 cricket::IceRole DetermineIceRole( 391 cricket::JsepTransport* jsep_transport, 392 const cricket::TransportInfo& transport_info, 393 SdpType type, 394 bool local); 395 396 std::unique_ptr<cricket::DtlsTransportInternal> CreateDtlsTransport( 397 const cricket::ContentInfo& content_info, 398 cricket::IceTransportInternal* ice); 399 rtc::scoped_refptr<webrtc::IceTransportInterface> CreateIceTransport( 400 const std::string& transport_name, 401 bool rtcp); 402 403 std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedRtpTransport( 404 const std::string& transport_name, 405 rtc::PacketTransportInternal* rtp_packet_transport, 406 rtc::PacketTransportInternal* rtcp_packet_transport); 407 std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport( 408 const std::string& transport_name, 409 cricket::DtlsTransportInternal* rtp_dtls_transport, 410 cricket::DtlsTransportInternal* rtcp_dtls_transport); 411 std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport( 412 const std::string& transport_name, 413 cricket::DtlsTransportInternal* rtp_dtls_transport, 414 cricket::DtlsTransportInternal* rtcp_dtls_transport); 415 416 // Collect all the DtlsTransports, including RTP and RTCP, from the 417 // JsepTransports, including those not mapped to a MID because they are being 418 // kept alive in case of rollback. 419 std::vector<cricket::DtlsTransportInternal*> GetDtlsTransports(); 420 // Same as the above, but doesn't include rollback transports. 421 // JsepTransportController can iterate all the DtlsTransports and update the 422 // aggregate states. 423 std::vector<cricket::DtlsTransportInternal*> GetActiveDtlsTransports(); 424 425 // Handlers for signals from Transport. 426 void OnTransportWritableState_n(rtc::PacketTransportInternal* transport) 427 RTC_RUN_ON(network_thread_); 428 void OnTransportReceivingState_n(rtc::PacketTransportInternal* transport) 429 RTC_RUN_ON(network_thread_); 430 void OnTransportGatheringState_n(cricket::IceTransportInternal* transport) 431 RTC_RUN_ON(network_thread_); 432 void OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport, 433 const cricket::Candidate& candidate) 434 RTC_RUN_ON(network_thread_); 435 void OnTransportCandidateError_n(cricket::IceTransportInternal* transport, 436 const cricket::IceCandidateErrorEvent& event) 437 RTC_RUN_ON(network_thread_); 438 void OnTransportCandidatesRemoved_n(cricket::IceTransportInternal* transport, 439 const cricket::Candidates& candidates) 440 RTC_RUN_ON(network_thread_); 441 void OnTransportRoleConflict_n(cricket::IceTransportInternal* transport) 442 RTC_RUN_ON(network_thread_); 443 void OnTransportStateChanged_n(cricket::IceTransportInternal* transport) 444 RTC_RUN_ON(network_thread_); 445 void OnTransportCandidatePairChanged_n( 446 const cricket::CandidatePairChangeEvent& event) 447 RTC_RUN_ON(network_thread_); 448 void UpdateAggregateStates_n() RTC_RUN_ON(network_thread_); 449 450 void OnRtcpPacketReceived_n(rtc::CopyOnWriteBuffer* packet, 451 int64_t packet_time_us) 452 RTC_RUN_ON(network_thread_); 453 454 void OnDtlsHandshakeError(rtc::SSLHandshakeError error); 455 456 bool OnTransportChanged(const std::string& mid, 457 cricket::JsepTransport* transport); 458 459 rtc::Thread* const network_thread_ = nullptr; 460 cricket::PortAllocator* const port_allocator_ = nullptr; 461 AsyncDnsResolverFactoryInterface* const async_dns_resolver_factory_ = nullptr; 462 463 JsepTransportCollection transports_ RTC_GUARDED_BY(network_thread_); 464 // Aggregate states for Transports. 465 // standardized_ice_connection_state_ is intended to replace 466 // ice_connection_state, see bugs.webrtc.org/9308 467 cricket::IceConnectionState ice_connection_state_ = 468 cricket::kIceConnectionConnecting; 469 PeerConnectionInterface::IceConnectionState 470 standardized_ice_connection_state_ = 471 PeerConnectionInterface::kIceConnectionNew; 472 PeerConnectionInterface::PeerConnectionState combined_connection_state_ = 473 PeerConnectionInterface::PeerConnectionState::kNew; 474 cricket::IceGatheringState ice_gathering_state_ = cricket::kIceGatheringNew; 475 476 const Config config_; 477 bool active_reset_srtp_params_ RTC_GUARDED_BY(network_thread_); 478 479 const cricket::SessionDescription* local_desc_ = nullptr; 480 const cricket::SessionDescription* remote_desc_ = nullptr; 481 absl::optional<bool> initial_offerer_; 482 483 cricket::IceConfig ice_config_; 484 cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING; 485 uint64_t ice_tiebreaker_ = rtc::CreateRandomId64(); 486 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; 487 488 BundleManager bundles_; 489 }; 490 491 } // namespace webrtc 492 493 #endif // PC_JSEP_TRANSPORT_CONTROLLER_H_ 494