blob: 8e00793bf9b13d9380a5fab16f63e55a301815b5 [file] [log] [blame]
Zhi Huange818b6e2018-02-22 15:26:27 -08001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef PC_JSEP_TRANSPORT_H_
12#define PC_JSEP_TRANSPORT_H_
Zhi Huange818b6e2018-02-22 15:26:27 -080013
14#include <map>
15#include <memory>
16#include <string>
17#include <vector>
18
Danil Chapovalov66cadcc2018-06-19 16:47:43 +020019#include "absl/types/optional.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080020#include "api/candidate.h"
Anton Sukhanov292ce4e2019-06-03 13:00:24 -070021#include "api/datagram_transport_interface.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080022#include "api/jsep.h"
Anton Sukhanov7940da02018-10-10 10:34:49 -070023#include "api/media_transport_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "p2p/base/dtls_transport.h"
25#include "p2p/base/p2p_constants.h"
26#include "p2p/base/transport_info.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/session_description.h"
32#include "pc/srtp_filter.h"
33#include "pc/srtp_transport.h"
34#include "pc/transport_stats.h"
35#include "rtc_base/constructor_magic.h"
36#include "rtc_base/message_queue.h"
37#include "rtc_base/rtc_certificate.h"
38#include "rtc_base/ssl_stream_adapter.h"
Artem Titove41c4332018-07-25 15:04:28 +020039#include "rtc_base/third_party/sigslot/sigslot.h"
Harald Alvestrand78a5e962019-04-03 10:42:39 +020040#include "rtc_base/thread_checker.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080041
42namespace cricket {
43
44class DtlsTransportInternal;
45
46struct JsepTransportDescription {
47 public:
48 JsepTransportDescription();
49 JsepTransportDescription(
50 bool rtcp_mux_enabled,
51 const std::vector<CryptoParams>& cryptos,
52 const std::vector<int>& encrypted_header_extension_ids,
Zhi Huange830e682018-03-30 10:48:35 -070053 int rtp_abs_sendtime_extn_id,
Zhi Huange818b6e2018-02-22 15:26:27 -080054 const TransportDescription& transport_description);
55 JsepTransportDescription(const JsepTransportDescription& from);
56 ~JsepTransportDescription();
57
58 JsepTransportDescription& operator=(const JsepTransportDescription& from);
59
60 bool rtcp_mux_enabled = true;
61 std::vector<CryptoParams> cryptos;
62 std::vector<int> encrypted_header_extension_ids;
Zhi Huange830e682018-03-30 10:48:35 -070063 int rtp_abs_sendtime_extn_id = -1;
Zhi Huange818b6e2018-02-22 15:26:27 -080064 // TODO(zhihuang): Add the ICE and DTLS related variables and methods from
65 // TransportDescription and remove this extra layer of abstraction.
66 TransportDescription transport_desc;
67};
68
69// Helper class used by JsepTransportController that processes
70// TransportDescriptions. A TransportDescription represents the
71// transport-specific properties of an SDP m= section, processed according to
72// JSEP. Each transport consists of DTLS and ICE transport channels for RTP
73// (and possibly RTCP, if rtcp-mux isn't used).
74//
Zhi Huang365381f2018-04-13 16:44:34 -070075// On Threading: JsepTransport performs work solely on the network thread, and
Zhi Huange818b6e2018-02-22 15:26:27 -080076// so its methods should only be called on the network thread.
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -070077class JsepTransport : public sigslot::has_slots<>,
78 public webrtc::MediaTransportStateCallback {
Zhi Huange818b6e2018-02-22 15:26:27 -080079 public:
80 // |mid| is just used for log statements in order to identify the Transport.
81 // Note that |local_certificate| is allowed to be null since a remote
82 // description may be set before a local certificate is generated.
Anton Sukhanov7940da02018-10-10 10:34:49 -070083 //
84 // |media_trasport| is optional (experimental). If available it will be used
85 // to send / receive encoded audio and video frames instead of RTP.
86 // Currently |media_transport| can co-exist with RTP / RTCP transports.
Zhi Huang365381f2018-04-13 16:44:34 -070087 JsepTransport(
Zhi Huange818b6e2018-02-22 15:26:27 -080088 const std::string& mid,
89 const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate,
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -070090 std::unique_ptr<cricket::IceTransportInternal> ice_transport,
91 std::unique_ptr<cricket::IceTransportInternal> rtcp_ice_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -080092 std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport,
93 std::unique_ptr<webrtc::SrtpTransport> sdes_transport,
94 std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport,
95 std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
Anton Sukhanov7940da02018-10-10 10:34:49 -070096 std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
Anton Sukhanov292ce4e2019-06-03 13:00:24 -070097 std::unique_ptr<webrtc::MediaTransportInterface> media_transport,
98 std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -080099
Zhi Huang365381f2018-04-13 16:44:34 -0700100 ~JsepTransport() override;
Zhi Huange818b6e2018-02-22 15:26:27 -0800101
102 // Returns the MID of this transport. This is only used for logging.
103 const std::string& mid() const { return mid_; }
104
105 // Must be called before applying local session description.
106 // Needed in order to verify the local fingerprint.
107 void SetLocalCertificate(
108 const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200109 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800110 local_certificate_ = local_certificate;
111 }
112
113 // Return the local certificate provided by SetLocalCertificate.
114 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200115 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800116 return local_certificate_;
117 }
118
119 webrtc::RTCError SetLocalJsepTransportDescription(
120 const JsepTransportDescription& jsep_description,
121 webrtc::SdpType type);
122
123 // Set the remote TransportDescription to be used by DTLS and ICE channels
124 // that are part of this Transport.
125 webrtc::RTCError SetRemoteJsepTransportDescription(
126 const JsepTransportDescription& jsep_description,
127 webrtc::SdpType type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800128 webrtc::RTCError AddRemoteCandidates(const Candidates& candidates);
129
130 // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
131 // set, offers should generate new ufrags/passwords until an ICE restart
132 // occurs.
133 //
134 // This and the below method can be called safely from any thread as long as
135 // SetXTransportDescription is not in progress.
136 void SetNeedsIceRestartFlag();
137 // Returns true if the ICE restart flag above was set, and no ICE restart has
138 // occurred yet for this transport (by applying a local description with
139 // changed ufrag/password).
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200140 bool needs_ice_restart() const {
141 rtc::CritScope scope(&accessor_lock_);
142 return needs_ice_restart_;
143 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800144
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200145 // Returns role if negotiated, or empty absl::optional if it hasn't been
146 // negotiated yet.
147 absl::optional<rtc::SSLRole> GetDtlsRole() const;
Zhi Huange818b6e2018-02-22 15:26:27 -0800148
149 // TODO(deadbeef): Make this const. See comment in transportcontroller.h.
150 bool GetStats(TransportStats* stats);
151
152 const JsepTransportDescription* local_description() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200153 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800154 return local_description_.get();
155 }
156
157 const JsepTransportDescription* remote_description() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200158 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800159 return remote_description_.get();
160 }
161
162 webrtc::RtpTransportInternal* rtp_transport() const {
Bjorn Mellem7e8de0b2019-06-07 06:13:42 +0000163 // This method is called from the signaling thread, which means
164 // that a race is possible, making safety analysis complex.
165 // After fixing, this method should be marked "network thread only".
166 if (dtls_srtp_transport_) {
167 return dtls_srtp_transport_.get();
168 } else if (sdes_transport_) {
169 return sdes_transport_.get();
Zhi Huange818b6e2018-02-22 15:26:27 -0800170 } else {
Bjorn Mellem7e8de0b2019-06-07 06:13:42 +0000171 return unencrypted_rtp_transport_.get();
Zhi Huange818b6e2018-02-22 15:26:27 -0800172 }
173 }
174
Harald Alvestrandad88c882018-11-28 16:47:46 +0100175 const DtlsTransportInternal* rtp_dtls_transport() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200176 rtc::CritScope scope(&accessor_lock_);
Harald Alvestrandad88c882018-11-28 16:47:46 +0100177 if (rtp_dtls_transport_) {
178 return rtp_dtls_transport_->internal();
179 } else {
180 return nullptr;
181 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800182 }
183
Harald Alvestrandad88c882018-11-28 16:47:46 +0100184 DtlsTransportInternal* rtp_dtls_transport() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200185 rtc::CritScope scope(&accessor_lock_);
Harald Alvestrandad88c882018-11-28 16:47:46 +0100186 if (rtp_dtls_transport_) {
187 return rtp_dtls_transport_->internal();
188 } else {
189 return nullptr;
190 }
191 }
192
193 const DtlsTransportInternal* rtcp_dtls_transport() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200194 rtc::CritScope scope(&accessor_lock_);
Harald Alvestrandad88c882018-11-28 16:47:46 +0100195 if (rtcp_dtls_transport_) {
196 return rtcp_dtls_transport_->internal();
197 } else {
198 return nullptr;
199 }
200 }
201
202 DtlsTransportInternal* rtcp_dtls_transport() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200203 rtc::CritScope scope(&accessor_lock_);
Harald Alvestrandad88c882018-11-28 16:47:46 +0100204 if (rtcp_dtls_transport_) {
205 return rtcp_dtls_transport_->internal();
206 } else {
207 return nullptr;
208 }
209 }
210
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100211 rtc::scoped_refptr<webrtc::DtlsTransport> RtpDtlsTransport() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200212 rtc::CritScope scope(&accessor_lock_);
Harald Alvestrandad88c882018-11-28 16:47:46 +0100213 return rtp_dtls_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800214 }
215
Anton Sukhanov7940da02018-10-10 10:34:49 -0700216 // Returns media transport, if available.
217 // Note that media transport is owned by jseptransport and the pointer
218 // to media transport will becomes invalid after destruction of jseptransport.
219 webrtc::MediaTransportInterface* media_transport() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200220 rtc::CritScope scope(&accessor_lock_);
Anton Sukhanov7940da02018-10-10 10:34:49 -0700221 return media_transport_.get();
222 }
223
Anton Sukhanov316f3ac2019-05-23 15:50:38 -0700224 // Returns datagram transport, if available.
225 webrtc::DatagramTransportInterface* datagram_transport() const {
226 rtc::CritScope scope(&accessor_lock_);
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700227 return datagram_transport_.get();
Anton Sukhanov316f3ac2019-05-23 15:50:38 -0700228 }
229
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700230 // Returns the latest media transport state.
231 webrtc::MediaTransportState media_transport_state() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200232 rtc::CritScope scope(&accessor_lock_);
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700233 return media_transport_state_;
234 }
235
Zhi Huange818b6e2018-02-22 15:26:27 -0800236 // This is signaled when RTCP-mux becomes active and
237 // |rtcp_dtls_transport_| is destroyed. The JsepTransportController will
238 // handle the signal and update the aggregate transport states.
239 sigslot::signal<> SignalRtcpMuxActive;
240
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700241 // This is signaled for changes in |media_transport_| state.
242 sigslot::signal<> SignalMediaTransportStateChanged;
243
Zhi Huange818b6e2018-02-22 15:26:27 -0800244 // TODO(deadbeef): The methods below are only public for testing. Should make
245 // them utility functions or objects so they can be tested independently from
246 // this class.
247
248 // Returns an error if the certificate's identity does not match the
249 // fingerprint, or either is NULL.
250 webrtc::RTCError VerifyCertificateFingerprint(
251 const rtc::RTCCertificate* certificate,
252 const rtc::SSLFingerprint* fingerprint) const;
253
Zhi Huangb57e1692018-06-12 11:41:11 -0700254 void SetActiveResetSrtpParams(bool active_reset_srtp_params);
255
Zhi Huange818b6e2018-02-22 15:26:27 -0800256 private:
257 bool SetRtcpMux(bool enable, webrtc::SdpType type, ContentSource source);
258
259 void ActivateRtcpMux();
260
261 bool SetSdes(const std::vector<CryptoParams>& cryptos,
262 const std::vector<int>& encrypted_extension_ids,
263 webrtc::SdpType type,
264 ContentSource source);
265
266 // Negotiates and sets the DTLS parameters based on the current local and
267 // remote transport description, such as the DTLS role to use, and whether
268 // DTLS should be activated.
269 //
270 // Called when an answer TransportDescription is applied.
271 webrtc::RTCError NegotiateAndSetDtlsParameters(
272 webrtc::SdpType local_description_type);
273
274 // Negotiates the DTLS role based off the offer and answer as specified by
275 // RFC 4145, section-4.1. Returns an RTCError if role cannot be determined
276 // from the local description and remote description.
277 webrtc::RTCError NegotiateDtlsRole(
278 webrtc::SdpType local_description_type,
279 ConnectionRole local_connection_role,
280 ConnectionRole remote_connection_role,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200281 absl::optional<rtc::SSLRole>* negotiated_dtls_role);
Zhi Huange818b6e2018-02-22 15:26:27 -0800282
283 // Pushes down the ICE parameters from the local description, such
284 // as the ICE ufrag and pwd.
285 void SetLocalIceParameters(IceTransportInternal* ice);
286
287 // Pushes down the ICE parameters from the remote description.
288 void SetRemoteIceParameters(IceTransportInternal* ice);
289
290 // Pushes down the DTLS parameters obtained via negotiation.
291 webrtc::RTCError SetNegotiatedDtlsParameters(
292 DtlsTransportInternal* dtls_transport,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200293 absl::optional<rtc::SSLRole> dtls_role,
Zhi Huange818b6e2018-02-22 15:26:27 -0800294 rtc::SSLFingerprint* remote_fingerprint);
295
296 bool GetTransportStats(DtlsTransportInternal* dtls_transport,
297 TransportStats* stats);
298
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700299 // Invoked whenever the state of the media transport changes.
300 void OnStateChanged(webrtc::MediaTransportState state) override;
301
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200302 // Owning thread, for safety checks
303 const rtc::Thread* const network_thread_;
304 // Critical scope for fields accessed off-thread
305 // TODO(https://bugs.webrtc.org/10300): Stop doing this.
306 rtc::CriticalSection accessor_lock_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800307 const std::string mid_;
308 // needs-ice-restart bit as described in JSEP.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200309 bool needs_ice_restart_ RTC_GUARDED_BY(accessor_lock_) = false;
310 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_
311 RTC_GUARDED_BY(network_thread_);
312 std::unique_ptr<JsepTransportDescription> local_description_
313 RTC_GUARDED_BY(network_thread_);
314 std::unique_ptr<JsepTransportDescription> remote_description_
315 RTC_GUARDED_BY(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800316
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700317 // Ice transport which may be used by any of upper-layer transports (below).
318 // Owned by JsepTransport and guaranteed to outlive the transports below.
319 const std::unique_ptr<cricket::IceTransportInternal> ice_transport_;
320 const std::unique_ptr<cricket::IceTransportInternal> rtcp_ice_transport_;
321
Zhi Huange818b6e2018-02-22 15:26:27 -0800322 // To avoid downcasting and make it type safe, keep three unique pointers for
323 // different SRTP mode and only one of these is non-nullptr.
Bjorn Mellem7e8de0b2019-06-07 06:13:42 +0000324 // Since these are const, the variables don't need locks;
325 // accessing the objects depends on the objects' thread safety contract.
326 const std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport_;
327 const std::unique_ptr<webrtc::SrtpTransport> sdes_transport_;
328 const std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800329
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200330 rtc::scoped_refptr<webrtc::DtlsTransport> rtp_dtls_transport_
331 RTC_GUARDED_BY(accessor_lock_);
332 rtc::scoped_refptr<webrtc::DtlsTransport> rtcp_dtls_transport_
333 RTC_GUARDED_BY(accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800334
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200335 SrtpFilter sdes_negotiator_ RTC_GUARDED_BY(network_thread_);
336 RtcpMuxFilter rtcp_mux_negotiator_ RTC_GUARDED_BY(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800337
338 // Cache the encrypted header extension IDs for SDES negoitation.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200339 absl::optional<std::vector<int>> send_extension_ids_
340 RTC_GUARDED_BY(network_thread_);
341 absl::optional<std::vector<int>> recv_extension_ids_
342 RTC_GUARDED_BY(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800343
Anton Sukhanov7940da02018-10-10 10:34:49 -0700344 // Optional media transport (experimental).
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200345 std::unique_ptr<webrtc::MediaTransportInterface> media_transport_
346 RTC_GUARDED_BY(accessor_lock_);
Anton Sukhanov7940da02018-10-10 10:34:49 -0700347
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700348 // Optional datagram transport (experimental).
349 std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport_
350 RTC_GUARDED_BY(accessor_lock_);
351
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700352 // If |media_transport_| is provided, this variable represents the state of
353 // media transport.
Anton Sukhanov316f3ac2019-05-23 15:50:38 -0700354 //
355 // NOTE: datagram transport state is handled by DatagramDtlsAdaptor, because
356 // DatagramDtlsAdaptor owns DatagramTransport. This state only represents
357 // media transport.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200358 webrtc::MediaTransportState media_transport_state_
359 RTC_GUARDED_BY(accessor_lock_) = webrtc::MediaTransportState::kPending;
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700360
Zhi Huang365381f2018-04-13 16:44:34 -0700361 RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800362};
363
364} // namespace cricket
365
Steve Anton10542f22019-01-11 09:11:00 -0800366#endif // PC_JSEP_TRANSPORT_H_