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