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