blob: 79b933c9e5d3b4078866df1954ba55cde8b009a7 [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#include "pc/jsep_transport.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <stddef.h>
14#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
Zhi Huange818b6e2018-02-22 15:26:27 -080016#include <memory>
Yves Gerey3e707812018-11-28 16:47:49 +010017#include <type_traits>
Zhi Huange818b6e2018-02-22 15:26:27 -080018#include <utility> // for std::pair
19
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "api/array_view.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080021#include "api/candidate.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "p2p/base/p2p_constants.h"
23#include "p2p/base/p2p_transport_channel.h"
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -070024#include "pc/sctp_data_channel_transport.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080025#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "rtc_base/copy_on_write_buffer.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080027#include "rtc_base/logging.h"
Zhi Huang365381f2018-04-13 16:44:34 -070028#include "rtc_base/strings/string_builder.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080029
30using webrtc::SdpType;
31
32namespace cricket {
33
34static bool VerifyIceParams(const JsepTransportDescription& jsep_description) {
35 // For legacy protocols.
36 // TODO(zhihuang): Remove this once the legacy protocol is no longer
37 // supported.
38 if (jsep_description.transport_desc.ice_ufrag.empty() &&
39 jsep_description.transport_desc.ice_pwd.empty()) {
40 return true;
41 }
42
43 if (jsep_description.transport_desc.ice_ufrag.length() <
44 ICE_UFRAG_MIN_LENGTH ||
45 jsep_description.transport_desc.ice_ufrag.length() >
46 ICE_UFRAG_MAX_LENGTH) {
47 return false;
48 }
49 if (jsep_description.transport_desc.ice_pwd.length() < ICE_PWD_MIN_LENGTH ||
50 jsep_description.transport_desc.ice_pwd.length() > ICE_PWD_MAX_LENGTH) {
51 return false;
52 }
53 return true;
54}
55
56JsepTransportDescription::JsepTransportDescription() {}
57
58JsepTransportDescription::JsepTransportDescription(
59 bool rtcp_mux_enabled,
60 const std::vector<CryptoParams>& cryptos,
61 const std::vector<int>& encrypted_header_extension_ids,
Zhi Huange830e682018-03-30 10:48:35 -070062 int rtp_abs_sendtime_extn_id,
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070063 const TransportDescription& transport_desc,
64 absl::optional<std::string> media_alt_protocol,
65 absl::optional<std::string> data_alt_protocol)
Zhi Huange818b6e2018-02-22 15:26:27 -080066 : rtcp_mux_enabled(rtcp_mux_enabled),
67 cryptos(cryptos),
68 encrypted_header_extension_ids(encrypted_header_extension_ids),
Zhi Huange830e682018-03-30 10:48:35 -070069 rtp_abs_sendtime_extn_id(rtp_abs_sendtime_extn_id),
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070070 transport_desc(transport_desc),
71 media_alt_protocol(media_alt_protocol),
72 data_alt_protocol(data_alt_protocol) {}
Zhi Huange818b6e2018-02-22 15:26:27 -080073
74JsepTransportDescription::JsepTransportDescription(
75 const JsepTransportDescription& from)
76 : rtcp_mux_enabled(from.rtcp_mux_enabled),
77 cryptos(from.cryptos),
78 encrypted_header_extension_ids(from.encrypted_header_extension_ids),
Zhi Huange830e682018-03-30 10:48:35 -070079 rtp_abs_sendtime_extn_id(from.rtp_abs_sendtime_extn_id),
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070080 transport_desc(from.transport_desc),
81 media_alt_protocol(from.media_alt_protocol),
82 data_alt_protocol(from.data_alt_protocol) {}
Zhi Huange818b6e2018-02-22 15:26:27 -080083
84JsepTransportDescription::~JsepTransportDescription() = default;
85
86JsepTransportDescription& JsepTransportDescription::operator=(
87 const JsepTransportDescription& from) {
88 if (this == &from) {
89 return *this;
90 }
91 rtcp_mux_enabled = from.rtcp_mux_enabled;
92 cryptos = from.cryptos;
93 encrypted_header_extension_ids = from.encrypted_header_extension_ids;
Zhi Huange830e682018-03-30 10:48:35 -070094 rtp_abs_sendtime_extn_id = from.rtp_abs_sendtime_extn_id;
Zhi Huange818b6e2018-02-22 15:26:27 -080095 transport_desc = from.transport_desc;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070096 media_alt_protocol = from.media_alt_protocol;
97 data_alt_protocol = from.data_alt_protocol;
Zhi Huange818b6e2018-02-22 15:26:27 -080098
99 return *this;
100}
101
Zhi Huang365381f2018-04-13 16:44:34 -0700102JsepTransport::JsepTransport(
Zhi Huange818b6e2018-02-22 15:26:27 -0800103 const std::string& mid,
104 const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate,
Qingsi Wang25ec8882019-11-15 12:33:05 -0800105 rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport,
106 rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -0800107 std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport,
108 std::unique_ptr<webrtc::SrtpTransport> sdes_transport,
109 std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport,
Bjorn A Mellem364b2672019-08-20 16:58:03 -0700110 std::unique_ptr<webrtc::RtpTransportInternal> datagram_rtp_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -0800111 std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
Anton Sukhanov7940da02018-10-10 10:34:49 -0700112 std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700113 std::unique_ptr<SctpTransportInternal> sctp_transport,
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700114 std::unique_ptr<webrtc::MediaTransportInterface> media_transport,
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700115 std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport,
116 webrtc::DataChannelTransportInterface* data_channel_transport)
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200117 : network_thread_(rtc::Thread::Current()),
118 mid_(mid),
Zhi Huange818b6e2018-02-22 15:26:27 -0800119 local_certificate_(local_certificate),
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700120 ice_transport_(std::move(ice_transport)),
121 rtcp_ice_transport_(std::move(rtcp_ice_transport)),
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200122 unencrypted_rtp_transport_(std::move(unencrypted_rtp_transport)),
123 sdes_transport_(std::move(sdes_transport)),
124 dtls_srtp_transport_(std::move(dtls_srtp_transport)),
Harald Alvestrandad88c882018-11-28 16:47:46 +0100125 rtp_dtls_transport_(
126 rtp_dtls_transport ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
127 std::move(rtp_dtls_transport))
128 : nullptr),
129 rtcp_dtls_transport_(
130 rtcp_dtls_transport
131 ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
132 std::move(rtcp_dtls_transport))
133 : nullptr),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700134 sctp_data_channel_transport_(
135 sctp_transport ? std::make_unique<webrtc::SctpDataChannelTransport>(
136 sctp_transport.get())
137 : nullptr),
138 sctp_transport_(sctp_transport
139 ? new rtc::RefCountedObject<webrtc::SctpTransport>(
140 std::move(sctp_transport))
141 : nullptr),
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700142 media_transport_(std::move(media_transport)),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700143 datagram_transport_(std::move(datagram_transport)),
Bjorn A Mellemfc604aa2019-09-24 14:59:21 -0700144 datagram_rtp_transport_(std::move(datagram_rtp_transport)),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700145 data_channel_transport_(data_channel_transport) {
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700146 RTC_DCHECK(ice_transport_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800147 RTC_DCHECK(rtp_dtls_transport_);
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700148 // |rtcp_ice_transport_| must be present iff |rtcp_dtls_transport_| is
149 // present.
150 RTC_DCHECK_EQ((rtcp_ice_transport_ != nullptr),
151 (rtcp_dtls_transport_ != nullptr));
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700152 RTC_DCHECK(!datagram_transport_ || !media_transport_);
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200153 // Verify the "only one out of these three can be set" invariant.
154 if (unencrypted_rtp_transport_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800155 RTC_DCHECK(!sdes_transport);
156 RTC_DCHECK(!dtls_srtp_transport);
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200157 } else if (sdes_transport_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800158 RTC_DCHECK(!unencrypted_rtp_transport);
159 RTC_DCHECK(!dtls_srtp_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800160 } else {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200161 RTC_DCHECK(dtls_srtp_transport_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800162 RTC_DCHECK(!unencrypted_rtp_transport);
163 RTC_DCHECK(!sdes_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800164 }
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700165
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700166 if (sctp_transport_) {
167 sctp_transport_->SetDtlsTransport(rtp_dtls_transport_);
168 }
169
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700170 if (datagram_rtp_transport_ && default_rtp_transport()) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200171 composite_rtp_transport_ = std::make_unique<webrtc::CompositeRtpTransport>(
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700172 std::vector<webrtc::RtpTransportInternal*>{
173 datagram_rtp_transport_.get(), default_rtp_transport()});
174 }
175
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700176 if (media_transport_) {
177 media_transport_->SetMediaTransportStateCallback(this);
178 }
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700179
180 if (data_channel_transport_ && sctp_data_channel_transport_) {
181 composite_data_channel_transport_ =
182 std::make_unique<webrtc::CompositeDataChannelTransport>(
183 std::vector<webrtc::DataChannelTransportInterface*>{
184 data_channel_transport_, sctp_data_channel_transport_.get()});
185 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800186}
187
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700188JsepTransport::~JsepTransport() {
Bjorn A Mellemfc604aa2019-09-24 14:59:21 -0700189 // Disconnect media transport state callbacks.
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700190 if (media_transport_) {
191 media_transport_->SetMediaTransportStateCallback(nullptr);
192 }
Anton Sukhanov316f3ac2019-05-23 15:50:38 -0700193
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700194 if (sctp_transport_) {
195 sctp_transport_->Clear();
196 }
197
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100198 // Clear all DtlsTransports. There may be pointers to these from
199 // other places, so we can't assume they'll be deleted by the destructor.
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100200 rtp_dtls_transport_->Clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100201 if (rtcp_dtls_transport_) {
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100202 rtcp_dtls_transport_->Clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100203 }
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700204
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700205 // ICE will be the last transport to be deleted.
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700206}
Zhi Huange818b6e2018-02-22 15:26:27 -0800207
Zhi Huang365381f2018-04-13 16:44:34 -0700208webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
Zhi Huange818b6e2018-02-22 15:26:27 -0800209 const JsepTransportDescription& jsep_description,
210 SdpType type) {
211 webrtc::RTCError error;
212
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200213 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800214 if (!VerifyIceParams(jsep_description)) {
215 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
216 "Invalid ice-ufrag or ice-pwd length.");
217 }
218
219 if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
220 ContentSource::CS_LOCAL)) {
221 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
222 "Failed to setup RTCP mux.");
223 }
224
225 // If doing SDES, setup the SDES crypto parameters.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700226 {
227 rtc::CritScope scope(&accessor_lock_);
228 if (sdes_transport_) {
229 RTC_DCHECK(!unencrypted_rtp_transport_);
230 RTC_DCHECK(!dtls_srtp_transport_);
231 if (!SetSdes(jsep_description.cryptos,
232 jsep_description.encrypted_header_extension_ids, type,
233 ContentSource::CS_LOCAL)) {
234 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
235 "Failed to setup SDES crypto parameters.");
236 }
237 } else if (dtls_srtp_transport_) {
238 RTC_DCHECK(!unencrypted_rtp_transport_);
239 RTC_DCHECK(!sdes_transport_);
240 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
241 jsep_description.encrypted_header_extension_ids);
Zhi Huange818b6e2018-02-22 15:26:27 -0800242 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800243 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800244 bool ice_restarting =
245 local_description_ != nullptr &&
246 IceCredentialsChanged(local_description_->transport_desc.ice_ufrag,
247 local_description_->transport_desc.ice_pwd,
248 jsep_description.transport_desc.ice_ufrag,
249 jsep_description.transport_desc.ice_pwd);
250 local_description_.reset(new JsepTransportDescription(jsep_description));
251
252 rtc::SSLFingerprint* local_fp =
253 local_description_->transport_desc.identity_fingerprint.get();
254
255 if (!local_fp) {
256 local_certificate_ = nullptr;
257 } else {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200258 error = VerifyCertificateFingerprint(local_certificate_, local_fp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800259 if (!error.ok()) {
260 local_description_.reset();
261 return error;
262 }
263 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200264 {
265 rtc::CritScope scope(&accessor_lock_);
266 RTC_DCHECK(rtp_dtls_transport_->internal());
267 SetLocalIceParameters(rtp_dtls_transport_->internal()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800268
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200269 if (rtcp_dtls_transport_) {
270 RTC_DCHECK(rtcp_dtls_transport_->internal());
271 SetLocalIceParameters(rtcp_dtls_transport_->internal()->ice_transport());
272 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800273 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800274 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
275 if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
276 error = NegotiateAndSetDtlsParameters(type);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700277 NegotiateDatagramTransport(type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800278 }
279 if (!error.ok()) {
280 local_description_.reset();
281 return error;
282 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200283 {
284 rtc::CritScope scope(&accessor_lock_);
285 if (needs_ice_restart_ && ice_restarting) {
286 needs_ice_restart_ = false;
287 RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag cleared for transport "
288 << mid();
289 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800290 }
291
292 return webrtc::RTCError::OK();
293}
294
Zhi Huang365381f2018-04-13 16:44:34 -0700295webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription(
Zhi Huange818b6e2018-02-22 15:26:27 -0800296 const JsepTransportDescription& jsep_description,
297 webrtc::SdpType type) {
298 webrtc::RTCError error;
299
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200300 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800301 if (!VerifyIceParams(jsep_description)) {
302 remote_description_.reset();
303 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
304 "Invalid ice-ufrag or ice-pwd length.");
305 }
306
307 if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
308 ContentSource::CS_REMOTE)) {
309 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
310 "Failed to setup RTCP mux.");
311 }
312
313 // If doing SDES, setup the SDES crypto parameters.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700314 {
315 rtc::CritScope lock(&accessor_lock_);
316 if (sdes_transport_) {
317 RTC_DCHECK(!unencrypted_rtp_transport_);
318 RTC_DCHECK(!dtls_srtp_transport_);
319 if (!SetSdes(jsep_description.cryptos,
320 jsep_description.encrypted_header_extension_ids, type,
321 ContentSource::CS_REMOTE)) {
322 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
323 "Failed to setup SDES crypto parameters.");
324 }
325 sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
326 jsep_description.rtp_abs_sendtime_extn_id);
327 } else if (dtls_srtp_transport_) {
328 RTC_DCHECK(!unencrypted_rtp_transport_);
329 RTC_DCHECK(!sdes_transport_);
330 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
331 jsep_description.encrypted_header_extension_ids);
332 dtls_srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
333 jsep_description.rtp_abs_sendtime_extn_id);
Zhi Huange818b6e2018-02-22 15:26:27 -0800334 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800335 }
336
337 remote_description_.reset(new JsepTransportDescription(jsep_description));
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200338 RTC_DCHECK(rtp_dtls_transport());
339 SetRemoteIceParameters(rtp_dtls_transport()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800340
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200341 if (rtcp_dtls_transport()) {
342 SetRemoteIceParameters(rtcp_dtls_transport()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800343 }
344
345 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
346 if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
347 error = NegotiateAndSetDtlsParameters(SdpType::kOffer);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700348 NegotiateDatagramTransport(type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800349 }
350 if (!error.ok()) {
351 remote_description_.reset();
352 return error;
353 }
354 return webrtc::RTCError::OK();
355}
356
Zhi Huang365381f2018-04-13 16:44:34 -0700357webrtc::RTCError JsepTransport::AddRemoteCandidates(
Zhi Huange818b6e2018-02-22 15:26:27 -0800358 const Candidates& candidates) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200359 RTC_DCHECK_RUN_ON(network_thread_);
Henrik Boström5d8f8fa2018-04-13 15:22:50 +0000360 if (!local_description_ || !remote_description_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800361 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
362 mid() +
363 " is not ready to use the remote candidate "
Henrik Boström5d8f8fa2018-04-13 15:22:50 +0000364 "because the local or remote description is "
365 "not set.");
Zhi Huange818b6e2018-02-22 15:26:27 -0800366 }
367
368 for (const cricket::Candidate& candidate : candidates) {
369 auto transport =
370 candidate.component() == cricket::ICE_CANDIDATE_COMPONENT_RTP
Harald Alvestrandad88c882018-11-28 16:47:46 +0100371 ? rtp_dtls_transport_
372 : rtcp_dtls_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800373 if (!transport) {
374 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
375 "Candidate has an unknown component: " +
Qingsi Wang20232a92019-09-06 12:51:17 -0700376 candidate.ToSensitiveString() + " for mid " +
377 mid());
Zhi Huange818b6e2018-02-22 15:26:27 -0800378 }
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100379 RTC_DCHECK(transport->internal() && transport->internal()->ice_transport());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100380 transport->internal()->ice_transport()->AddRemoteCandidate(candidate);
Zhi Huange818b6e2018-02-22 15:26:27 -0800381 }
382 return webrtc::RTCError::OK();
383}
384
Zhi Huang365381f2018-04-13 16:44:34 -0700385void JsepTransport::SetNeedsIceRestartFlag() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200386 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800387 if (!needs_ice_restart_) {
388 needs_ice_restart_ = true;
389 RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid();
390 }
391}
392
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200393absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200394 RTC_DCHECK_RUN_ON(network_thread_);
395 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800396 RTC_DCHECK(rtp_dtls_transport_);
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100397 RTC_DCHECK(rtp_dtls_transport_->internal());
Zhi Huange818b6e2018-02-22 15:26:27 -0800398 rtc::SSLRole dtls_role;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100399 if (!rtp_dtls_transport_->internal()->GetDtlsRole(&dtls_role)) {
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200400 return absl::optional<rtc::SSLRole>();
Zhi Huange818b6e2018-02-22 15:26:27 -0800401 }
402
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200403 return absl::optional<rtc::SSLRole>(dtls_role);
Zhi Huange818b6e2018-02-22 15:26:27 -0800404}
405
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700406absl::optional<OpaqueTransportParameters>
407JsepTransport::GetTransportParameters() const {
408 rtc::CritScope scope(&accessor_lock_);
409 if (!datagram_transport()) {
410 return absl::nullopt;
411 }
412
413 OpaqueTransportParameters params;
414 params.parameters = datagram_transport()->GetTransportParameters();
415 return params;
416}
417
Zhi Huang365381f2018-04-13 16:44:34 -0700418bool JsepTransport::GetStats(TransportStats* stats) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200419 RTC_DCHECK_RUN_ON(network_thread_);
420 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800421 stats->transport_name = mid();
422 stats->channel_stats.clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100423 RTC_DCHECK(rtp_dtls_transport_->internal());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100424 bool ret = GetTransportStats(rtp_dtls_transport_->internal(), stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800425 if (rtcp_dtls_transport_) {
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100426 RTC_DCHECK(rtcp_dtls_transport_->internal());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100427 ret &= GetTransportStats(rtcp_dtls_transport_->internal(), stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800428 }
429 return ret;
430}
431
Zhi Huang365381f2018-04-13 16:44:34 -0700432webrtc::RTCError JsepTransport::VerifyCertificateFingerprint(
Zhi Huange818b6e2018-02-22 15:26:27 -0800433 const rtc::RTCCertificate* certificate,
434 const rtc::SSLFingerprint* fingerprint) const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200435 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800436 if (!fingerprint) {
437 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
438 "No fingerprint");
439 }
440 if (!certificate) {
441 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
442 "Fingerprint provided but no identity available.");
443 }
Steve Anton4905edb2018-10-15 19:27:44 -0700444 std::unique_ptr<rtc::SSLFingerprint> fp_tmp =
445 rtc::SSLFingerprint::CreateUnique(fingerprint->algorithm,
446 *certificate->identity());
Zhi Huange818b6e2018-02-22 15:26:27 -0800447 RTC_DCHECK(fp_tmp.get() != NULL);
448 if (*fp_tmp == *fingerprint) {
449 return webrtc::RTCError::OK();
450 }
Zhi Huang365381f2018-04-13 16:44:34 -0700451 char ss_buf[1024];
452 rtc::SimpleStringBuilder desc(ss_buf);
Zhi Huange818b6e2018-02-22 15:26:27 -0800453 desc << "Local fingerprint does not match identity. Expected: ";
454 desc << fp_tmp->ToString();
455 desc << " Got: " << fingerprint->ToString();
Zhi Huang365381f2018-04-13 16:44:34 -0700456 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
457 std::string(desc.str()));
Zhi Huange818b6e2018-02-22 15:26:27 -0800458}
459
Zhi Huangb57e1692018-06-12 11:41:11 -0700460void JsepTransport::SetActiveResetSrtpParams(bool active_reset_srtp_params) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200461 RTC_DCHECK_RUN_ON(network_thread_);
462 rtc::CritScope scope(&accessor_lock_);
Zhi Huangb57e1692018-06-12 11:41:11 -0700463 if (dtls_srtp_transport_) {
464 RTC_LOG(INFO)
465 << "Setting active_reset_srtp_params of DtlsSrtpTransport to: "
466 << active_reset_srtp_params;
467 dtls_srtp_transport_->SetActiveResetSrtpParams(active_reset_srtp_params);
468 }
469}
470
Zhi Huang365381f2018-04-13 16:44:34 -0700471void JsepTransport::SetLocalIceParameters(IceTransportInternal* ice_transport) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200472 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800473 RTC_DCHECK(ice_transport);
474 RTC_DCHECK(local_description_);
475 ice_transport->SetIceParameters(
476 local_description_->transport_desc.GetIceParameters());
477}
478
Zhi Huang365381f2018-04-13 16:44:34 -0700479void JsepTransport::SetRemoteIceParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800480 IceTransportInternal* ice_transport) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200481 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800482 RTC_DCHECK(ice_transport);
483 RTC_DCHECK(remote_description_);
484 ice_transport->SetRemoteIceParameters(
485 remote_description_->transport_desc.GetIceParameters());
486 ice_transport->SetRemoteIceMode(remote_description_->transport_desc.ice_mode);
487}
488
Zhi Huang365381f2018-04-13 16:44:34 -0700489webrtc::RTCError JsepTransport::SetNegotiatedDtlsParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800490 DtlsTransportInternal* dtls_transport,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200491 absl::optional<rtc::SSLRole> dtls_role,
Zhi Huange818b6e2018-02-22 15:26:27 -0800492 rtc::SSLFingerprint* remote_fingerprint) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200493 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800494 RTC_DCHECK(dtls_transport);
495 // Set SSL role. Role must be set before fingerprint is applied, which
496 // initiates DTLS setup.
497 if (dtls_role && !dtls_transport->SetDtlsRole(*dtls_role)) {
498 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
499 "Failed to set SSL role for the transport.");
500 }
501 // Apply remote fingerprint.
502 if (!remote_fingerprint ||
503 !dtls_transport->SetRemoteFingerprint(
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700504 remote_fingerprint->algorithm, remote_fingerprint->digest.cdata(),
Zhi Huange818b6e2018-02-22 15:26:27 -0800505 remote_fingerprint->digest.size())) {
506 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
507 "Failed to apply remote fingerprint.");
508 }
509 return webrtc::RTCError::OK();
510}
511
Zhi Huang365381f2018-04-13 16:44:34 -0700512bool JsepTransport::SetRtcpMux(bool enable,
513 webrtc::SdpType type,
514 ContentSource source) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200515 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800516 bool ret = false;
517 switch (type) {
518 case SdpType::kOffer:
519 ret = rtcp_mux_negotiator_.SetOffer(enable, source);
520 break;
521 case SdpType::kPrAnswer:
522 // This may activate RTCP muxing, but we don't yet destroy the transport
523 // because the final answer may deactivate it.
524 ret = rtcp_mux_negotiator_.SetProvisionalAnswer(enable, source);
525 break;
526 case SdpType::kAnswer:
527 ret = rtcp_mux_negotiator_.SetAnswer(enable, source);
528 if (ret && rtcp_mux_negotiator_.IsActive()) {
529 ActivateRtcpMux();
530 }
531 break;
532 default:
533 RTC_NOTREACHED();
534 }
535
536 if (!ret) {
537 return false;
538 }
539
540 auto transport = rtp_transport();
541 transport->SetRtcpMuxEnabled(rtcp_mux_negotiator_.IsActive());
542 return ret;
543}
544
Zhi Huang365381f2018-04-13 16:44:34 -0700545void JsepTransport::ActivateRtcpMux() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200546 {
547 // Don't hold the network_thread_ lock while calling other functions,
548 // since they might call other functions that call RTC_DCHECK_RUN_ON.
549 // TODO(https://crbug.com/webrtc/10318): Simplify when possible.
550 RTC_DCHECK_RUN_ON(network_thread_);
551 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200552 {
553 rtc::CritScope scope(&accessor_lock_);
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700554 if (unencrypted_rtp_transport_) {
555 RTC_DCHECK(!sdes_transport_);
556 RTC_DCHECK(!dtls_srtp_transport_);
557 unencrypted_rtp_transport_->SetRtcpPacketTransport(nullptr);
558 } else if (sdes_transport_) {
559 RTC_DCHECK(!unencrypted_rtp_transport_);
560 RTC_DCHECK(!dtls_srtp_transport_);
561 sdes_transport_->SetRtcpPacketTransport(nullptr);
562 } else if (dtls_srtp_transport_) {
563 RTC_DCHECK(dtls_srtp_transport_);
564 RTC_DCHECK(!unencrypted_rtp_transport_);
565 RTC_DCHECK(!sdes_transport_);
566 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport(),
567 /*rtcp_dtls_transport=*/nullptr);
568 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200569 rtcp_dtls_transport_ = nullptr; // Destroy this reference.
570 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800571 // Notify the JsepTransportController to update the aggregate states.
572 SignalRtcpMuxActive();
573}
574
Zhi Huang365381f2018-04-13 16:44:34 -0700575bool JsepTransport::SetSdes(const std::vector<CryptoParams>& cryptos,
576 const std::vector<int>& encrypted_extension_ids,
577 webrtc::SdpType type,
578 ContentSource source) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200579 RTC_DCHECK_RUN_ON(network_thread_);
580 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800581 bool ret = false;
582 ret = sdes_negotiator_.Process(cryptos, type, source);
583 if (!ret) {
584 return ret;
585 }
586
587 if (source == ContentSource::CS_LOCAL) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700588 recv_extension_ids_ = encrypted_extension_ids;
Zhi Huange818b6e2018-02-22 15:26:27 -0800589 } else {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700590 send_extension_ids_ = encrypted_extension_ids;
Zhi Huange818b6e2018-02-22 15:26:27 -0800591 }
592
593 // If setting an SDES answer succeeded, apply the negotiated parameters
594 // to the SRTP transport.
595 if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) {
596 if (sdes_negotiator_.send_cipher_suite() &&
597 sdes_negotiator_.recv_cipher_suite()) {
598 RTC_DCHECK(send_extension_ids_);
599 RTC_DCHECK(recv_extension_ids_);
600 ret = sdes_transport_->SetRtpParams(
601 *(sdes_negotiator_.send_cipher_suite()),
602 sdes_negotiator_.send_key().data(),
603 static_cast<int>(sdes_negotiator_.send_key().size()),
604 *(send_extension_ids_), *(sdes_negotiator_.recv_cipher_suite()),
605 sdes_negotiator_.recv_key().data(),
606 static_cast<int>(sdes_negotiator_.recv_key().size()),
607 *(recv_extension_ids_));
608 } else {
609 RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES.";
610 if (type == SdpType::kAnswer) {
611 // Explicitly reset the |sdes_transport_| if no crypto param is
612 // provided in the answer. No need to call |ResetParams()| for
613 // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
614 sdes_transport_->ResetParams();
615 }
616 }
617 }
618 return ret;
619}
620
Zhi Huang365381f2018-04-13 16:44:34 -0700621webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800622 SdpType local_description_type) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200623 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800624 if (!local_description_ || !remote_description_) {
625 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
626 "Applying an answer transport description "
627 "without applying any offer.");
628 }
629 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200630 absl::optional<rtc::SSLRole> negotiated_dtls_role;
Zhi Huange818b6e2018-02-22 15:26:27 -0800631
632 rtc::SSLFingerprint* local_fp =
633 local_description_->transport_desc.identity_fingerprint.get();
634 rtc::SSLFingerprint* remote_fp =
635 remote_description_->transport_desc.identity_fingerprint.get();
636 if (remote_fp && local_fp) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200637 remote_fingerprint = std::make_unique<rtc::SSLFingerprint>(*remote_fp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800638 webrtc::RTCError error =
639 NegotiateDtlsRole(local_description_type,
640 local_description_->transport_desc.connection_role,
641 remote_description_->transport_desc.connection_role,
642 &negotiated_dtls_role);
643 if (!error.ok()) {
644 return error;
645 }
646 } else if (local_fp && (local_description_type == SdpType::kAnswer)) {
647 return webrtc::RTCError(
648 webrtc::RTCErrorType::INVALID_PARAMETER,
649 "Local fingerprint supplied when caller didn't offer DTLS.");
650 } else {
651 // We are not doing DTLS
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200652 remote_fingerprint = std::make_unique<rtc::SSLFingerprint>(
Steve Anton4905edb2018-10-15 19:27:44 -0700653 "", rtc::ArrayView<const uint8_t>());
Zhi Huange818b6e2018-02-22 15:26:27 -0800654 }
655 // Now that we have negotiated everything, push it downward.
656 // Note that we cache the result so that if we have race conditions
657 // between future SetRemote/SetLocal invocations and new transport
658 // creation, we have the negotiation state saved until a new
659 // negotiation happens.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200660 RTC_DCHECK(rtp_dtls_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800661 webrtc::RTCError error = SetNegotiatedDtlsParameters(
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200662 rtp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800663 if (!error.ok()) {
664 return error;
665 }
666
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200667 if (rtcp_dtls_transport()) {
668 error = SetNegotiatedDtlsParameters(
669 rtcp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800670 }
671 return error;
672}
673
Zhi Huang365381f2018-04-13 16:44:34 -0700674webrtc::RTCError JsepTransport::NegotiateDtlsRole(
Zhi Huange818b6e2018-02-22 15:26:27 -0800675 SdpType local_description_type,
676 ConnectionRole local_connection_role,
677 ConnectionRole remote_connection_role,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200678 absl::optional<rtc::SSLRole>* negotiated_dtls_role) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800679 // From RFC 4145, section-4.1, The following are the values that the
680 // 'setup' attribute can take in an offer/answer exchange:
681 // Offer Answer
682 // ________________
683 // active passive / holdconn
684 // passive active / holdconn
685 // actpass active / passive / holdconn
686 // holdconn holdconn
687 //
688 // Set the role that is most conformant with RFC 5763, Section 5, bullet 1
689 // The endpoint MUST use the setup attribute defined in [RFC4145].
690 // The endpoint that is the offerer MUST use the setup attribute
691 // value of setup:actpass and be prepared to receive a client_hello
692 // before it receives the answer. The answerer MUST use either a
693 // setup attribute value of setup:active or setup:passive. Note that
694 // if the answerer uses setup:passive, then the DTLS handshake will
695 // not begin until the answerer is received, which adds additional
696 // latency. setup:active allows the answer and the DTLS handshake to
697 // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever
698 // party is active MUST initiate a DTLS handshake by sending a
699 // ClientHello over each flow (host/port quartet).
700 // IOW - actpass and passive modes should be treated as server and
701 // active as client.
702 bool is_remote_server = false;
703 if (local_description_type == SdpType::kOffer) {
704 if (local_connection_role != CONNECTIONROLE_ACTPASS) {
705 return webrtc::RTCError(
706 webrtc::RTCErrorType::INVALID_PARAMETER,
707 "Offerer must use actpass value for setup attribute.");
708 }
709
710 if (remote_connection_role == CONNECTIONROLE_ACTIVE ||
711 remote_connection_role == CONNECTIONROLE_PASSIVE ||
712 remote_connection_role == CONNECTIONROLE_NONE) {
713 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE);
714 } else {
715 return webrtc::RTCError(
716 webrtc::RTCErrorType::INVALID_PARAMETER,
717 "Answerer must use either active or passive value "
718 "for setup attribute.");
719 }
720 // If remote is NONE or ACTIVE it will act as client.
721 } else {
722 if (remote_connection_role != CONNECTIONROLE_ACTPASS &&
723 remote_connection_role != CONNECTIONROLE_NONE) {
724 // Accept a remote role attribute that's not "actpass", but matches the
725 // current negotiated role. This is allowed by dtls-sdp, though our
726 // implementation will never generate such an offer as it's not
727 // recommended.
728 //
729 // See https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-dtls-sdp,
730 // section 5.5.
731 auto current_dtls_role = GetDtlsRole();
732 if (!current_dtls_role ||
733 (*current_dtls_role == rtc::SSL_CLIENT &&
734 remote_connection_role == CONNECTIONROLE_ACTIVE) ||
735 (*current_dtls_role == rtc::SSL_SERVER &&
736 remote_connection_role == CONNECTIONROLE_PASSIVE)) {
737 return webrtc::RTCError(
738 webrtc::RTCErrorType::INVALID_PARAMETER,
739 "Offerer must use actpass value or current negotiated role for "
740 "setup attribute.");
741 }
742 }
743
744 if (local_connection_role == CONNECTIONROLE_ACTIVE ||
745 local_connection_role == CONNECTIONROLE_PASSIVE) {
746 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE);
747 } else {
748 return webrtc::RTCError(
749 webrtc::RTCErrorType::INVALID_PARAMETER,
750 "Answerer must use either active or passive value "
751 "for setup attribute.");
752 }
753
754 // If local is passive, local will act as server.
755 }
756
Mirko Bonadei05cf6be2019-01-31 21:38:12 +0100757 *negotiated_dtls_role =
758 (is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER);
Zhi Huange818b6e2018-02-22 15:26:27 -0800759 return webrtc::RTCError::OK();
760}
761
Zhi Huang365381f2018-04-13 16:44:34 -0700762bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
763 TransportStats* stats) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200764 RTC_DCHECK_RUN_ON(network_thread_);
765 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800766 RTC_DCHECK(dtls_transport);
767 TransportChannelStats substats;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100768 if (rtcp_dtls_transport_) {
769 substats.component = dtls_transport == rtcp_dtls_transport_->internal()
770 ? ICE_CANDIDATE_COMPONENT_RTCP
771 : ICE_CANDIDATE_COMPONENT_RTP;
772 } else {
773 substats.component = ICE_CANDIDATE_COMPONENT_RTP;
774 }
Harald Alvestrand5cb78072019-10-28 09:51:17 +0100775 dtls_transport->GetSslVersionBytes(&substats.ssl_version_bytes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800776 dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
777 dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
778 substats.dtls_state = dtls_transport->dtls_state();
779 if (!dtls_transport->ice_transport()->GetStats(
Jonas Oreland149dc722019-08-28 08:10:27 +0200780 &substats.ice_transport_stats)) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800781 return false;
782 }
783 stats->channel_stats.push_back(substats);
784 return true;
785}
786
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700787void JsepTransport::OnStateChanged(webrtc::MediaTransportState state) {
788 // TODO(bugs.webrtc.org/9719) This method currently fires on the network
789 // thread, but media transport does not make such guarantees. We need to make
790 // sure this callback is guaranteed to be executed on the network thread.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200791 RTC_DCHECK_RUN_ON(network_thread_);
792 {
793 rtc::CritScope scope(&accessor_lock_);
794 media_transport_state_ = state;
795 }
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700796 SignalMediaTransportStateChanged();
797}
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700798
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700799void JsepTransport::NegotiateDatagramTransport(SdpType type) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700800 RTC_DCHECK(type == SdpType::kAnswer || type == SdpType::kPrAnswer);
801 rtc::CritScope lock(&accessor_lock_);
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700802 if (!datagram_transport_) {
803 return; // No need to negotiate the use of datagram transport.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700804 }
805
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700806 bool compatible_datagram_transport =
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700807 remote_description_->transport_desc.opaque_parameters &&
808 remote_description_->transport_desc.opaque_parameters ==
809 local_description_->transport_desc.opaque_parameters;
810
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700811 bool use_datagram_transport_for_media =
812 compatible_datagram_transport &&
813 remote_description_->media_alt_protocol ==
814 remote_description_->transport_desc.opaque_parameters->protocol &&
815 remote_description_->media_alt_protocol ==
816 local_description_->media_alt_protocol;
817
818 bool use_datagram_transport_for_data =
819 compatible_datagram_transport &&
820 remote_description_->data_alt_protocol ==
821 remote_description_->transport_desc.opaque_parameters->protocol &&
822 remote_description_->data_alt_protocol ==
823 local_description_->data_alt_protocol;
824
825 RTC_LOG(LS_INFO)
826 << "Negotiating datagram transport, use_datagram_transport_for_media="
827 << use_datagram_transport_for_media
828 << ", use_datagram_transport_for_data=" << use_datagram_transport_for_data
829 << " answer type=" << (type == SdpType::kAnswer ? "answer" : "pr_answer");
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700830
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700831 // A provisional or full or answer lets the peer start sending on one of the
832 // transports.
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700833 if (composite_rtp_transport_) {
834 composite_rtp_transport_->SetSendTransport(
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700835 use_datagram_transport_for_media ? datagram_rtp_transport_.get()
836 : default_rtp_transport());
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700837 }
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700838 if (composite_data_channel_transport_) {
839 composite_data_channel_transport_->SetSendTransport(
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700840 use_datagram_transport_for_data ? data_channel_transport_
841 : sctp_data_channel_transport_.get());
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700842 }
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700843
844 if (type != SdpType::kAnswer) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700845 return;
846 }
847
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700848 if (composite_rtp_transport_) {
849 if (use_datagram_transport_for_media) {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700850 // Negotiated use of datagram transport for RTP, so remove the
851 // non-datagram RTP transport.
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700852 composite_rtp_transport_->RemoveTransport(default_rtp_transport());
853 if (unencrypted_rtp_transport_) {
854 unencrypted_rtp_transport_ = nullptr;
855 } else if (sdes_transport_) {
856 sdes_transport_ = nullptr;
857 } else {
858 dtls_srtp_transport_ = nullptr;
859 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700860 } else {
861 composite_rtp_transport_->RemoveTransport(datagram_rtp_transport_.get());
862 datagram_rtp_transport_ = nullptr;
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700863 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700864 }
865
866 if (composite_data_channel_transport_) {
867 if (use_datagram_transport_for_data) {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700868 // Negotiated use of datagram transport for data channels, so remove the
869 // non-datagram data channel transport.
870 composite_data_channel_transport_->RemoveTransport(
871 sctp_data_channel_transport_.get());
872 sctp_data_channel_transport_ = nullptr;
873 sctp_transport_ = nullptr;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700874 } else {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700875 composite_data_channel_transport_->RemoveTransport(
876 data_channel_transport_);
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700877 data_channel_transport_ = nullptr;
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700878 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700879 } else if (data_channel_transport_ && !use_datagram_transport_for_data) {
880 // The datagram transport has been rejected without a fallback. We still
881 // need to inform the application and delete it.
882 SignalDataChannelTransportNegotiated(this, nullptr);
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700883 data_channel_transport_ = nullptr;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700884 }
885
886 if (!use_datagram_transport_for_media && !use_datagram_transport_for_data) {
887 // Datagram transport is not being used for anything, so clean it up.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700888 datagram_transport_ = nullptr;
889 }
890}
891
Zhi Huange818b6e2018-02-22 15:26:27 -0800892} // namespace cricket