blob: 5bf74f1e87a6093d09058d3354592bcda8d508e3 [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
Zhi Huange818b6e2018-02-22 15:26:27 -080034JsepTransportDescription::JsepTransportDescription() {}
35
36JsepTransportDescription::JsepTransportDescription(
37 bool rtcp_mux_enabled,
38 const std::vector<CryptoParams>& cryptos,
39 const std::vector<int>& encrypted_header_extension_ids,
Zhi Huange830e682018-03-30 10:48:35 -070040 int rtp_abs_sendtime_extn_id,
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070041 const TransportDescription& transport_desc,
42 absl::optional<std::string> media_alt_protocol,
43 absl::optional<std::string> data_alt_protocol)
Zhi Huange818b6e2018-02-22 15:26:27 -080044 : rtcp_mux_enabled(rtcp_mux_enabled),
45 cryptos(cryptos),
46 encrypted_header_extension_ids(encrypted_header_extension_ids),
Zhi Huange830e682018-03-30 10:48:35 -070047 rtp_abs_sendtime_extn_id(rtp_abs_sendtime_extn_id),
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070048 transport_desc(transport_desc),
49 media_alt_protocol(media_alt_protocol),
50 data_alt_protocol(data_alt_protocol) {}
Zhi Huange818b6e2018-02-22 15:26:27 -080051
52JsepTransportDescription::JsepTransportDescription(
53 const JsepTransportDescription& from)
54 : rtcp_mux_enabled(from.rtcp_mux_enabled),
55 cryptos(from.cryptos),
56 encrypted_header_extension_ids(from.encrypted_header_extension_ids),
Zhi Huange830e682018-03-30 10:48:35 -070057 rtp_abs_sendtime_extn_id(from.rtp_abs_sendtime_extn_id),
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070058 transport_desc(from.transport_desc),
59 media_alt_protocol(from.media_alt_protocol),
60 data_alt_protocol(from.data_alt_protocol) {}
Zhi Huange818b6e2018-02-22 15:26:27 -080061
62JsepTransportDescription::~JsepTransportDescription() = default;
63
64JsepTransportDescription& JsepTransportDescription::operator=(
65 const JsepTransportDescription& from) {
66 if (this == &from) {
67 return *this;
68 }
69 rtcp_mux_enabled = from.rtcp_mux_enabled;
70 cryptos = from.cryptos;
71 encrypted_header_extension_ids = from.encrypted_header_extension_ids;
Zhi Huange830e682018-03-30 10:48:35 -070072 rtp_abs_sendtime_extn_id = from.rtp_abs_sendtime_extn_id;
Zhi Huange818b6e2018-02-22 15:26:27 -080073 transport_desc = from.transport_desc;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070074 media_alt_protocol = from.media_alt_protocol;
75 data_alt_protocol = from.data_alt_protocol;
Zhi Huange818b6e2018-02-22 15:26:27 -080076
77 return *this;
78}
79
Zhi Huang365381f2018-04-13 16:44:34 -070080JsepTransport::JsepTransport(
Zhi Huange818b6e2018-02-22 15:26:27 -080081 const std::string& mid,
82 const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate,
Qingsi Wang25ec8882019-11-15 12:33:05 -080083 rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport,
84 rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -080085 std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport,
86 std::unique_ptr<webrtc::SrtpTransport> sdes_transport,
87 std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport,
Bjorn A Mellem364b2672019-08-20 16:58:03 -070088 std::unique_ptr<webrtc::RtpTransportInternal> datagram_rtp_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -080089 std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
Anton Sukhanov7940da02018-10-10 10:34:49 -070090 std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -070091 std::unique_ptr<SctpTransportInternal> sctp_transport,
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -070092 std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport,
93 webrtc::DataChannelTransportInterface* data_channel_transport)
Harald Alvestrand78a5e962019-04-03 10:42:39 +020094 : network_thread_(rtc::Thread::Current()),
95 mid_(mid),
Zhi Huange818b6e2018-02-22 15:26:27 -080096 local_certificate_(local_certificate),
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -070097 ice_transport_(std::move(ice_transport)),
98 rtcp_ice_transport_(std::move(rtcp_ice_transport)),
Harald Alvestrand78a5e962019-04-03 10:42:39 +020099 unencrypted_rtp_transport_(std::move(unencrypted_rtp_transport)),
100 sdes_transport_(std::move(sdes_transport)),
101 dtls_srtp_transport_(std::move(dtls_srtp_transport)),
Harald Alvestrandad88c882018-11-28 16:47:46 +0100102 rtp_dtls_transport_(
103 rtp_dtls_transport ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
104 std::move(rtp_dtls_transport))
105 : nullptr),
106 rtcp_dtls_transport_(
107 rtcp_dtls_transport
108 ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
109 std::move(rtcp_dtls_transport))
110 : nullptr),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700111 sctp_data_channel_transport_(
112 sctp_transport ? std::make_unique<webrtc::SctpDataChannelTransport>(
113 sctp_transport.get())
114 : nullptr),
115 sctp_transport_(sctp_transport
116 ? new rtc::RefCountedObject<webrtc::SctpTransport>(
117 std::move(sctp_transport))
118 : nullptr),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700119 datagram_transport_(std::move(datagram_transport)),
Bjorn A Mellemfc604aa2019-09-24 14:59:21 -0700120 datagram_rtp_transport_(std::move(datagram_rtp_transport)),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700121 data_channel_transport_(data_channel_transport) {
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700122 RTC_DCHECK(ice_transport_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800123 RTC_DCHECK(rtp_dtls_transport_);
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700124 // |rtcp_ice_transport_| must be present iff |rtcp_dtls_transport_| is
125 // present.
126 RTC_DCHECK_EQ((rtcp_ice_transport_ != nullptr),
127 (rtcp_dtls_transport_ != nullptr));
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200128 // Verify the "only one out of these three can be set" invariant.
129 if (unencrypted_rtp_transport_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800130 RTC_DCHECK(!sdes_transport);
131 RTC_DCHECK(!dtls_srtp_transport);
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200132 } else if (sdes_transport_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800133 RTC_DCHECK(!unencrypted_rtp_transport);
134 RTC_DCHECK(!dtls_srtp_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800135 } else {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200136 RTC_DCHECK(dtls_srtp_transport_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800137 RTC_DCHECK(!unencrypted_rtp_transport);
138 RTC_DCHECK(!sdes_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800139 }
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700140
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700141 if (sctp_transport_) {
142 sctp_transport_->SetDtlsTransport(rtp_dtls_transport_);
143 }
144
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700145 if (datagram_rtp_transport_ && default_rtp_transport()) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200146 composite_rtp_transport_ = std::make_unique<webrtc::CompositeRtpTransport>(
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700147 std::vector<webrtc::RtpTransportInternal*>{
148 datagram_rtp_transport_.get(), default_rtp_transport()});
149 }
150
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700151 if (data_channel_transport_ && sctp_data_channel_transport_) {
152 composite_data_channel_transport_ =
153 std::make_unique<webrtc::CompositeDataChannelTransport>(
154 std::vector<webrtc::DataChannelTransportInterface*>{
155 data_channel_transport_, sctp_data_channel_transport_.get()});
156 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800157}
158
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700159JsepTransport::~JsepTransport() {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700160 if (sctp_transport_) {
161 sctp_transport_->Clear();
162 }
163
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100164 // Clear all DtlsTransports. There may be pointers to these from
165 // other places, so we can't assume they'll be deleted by the destructor.
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100166 rtp_dtls_transport_->Clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100167 if (rtcp_dtls_transport_) {
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100168 rtcp_dtls_transport_->Clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100169 }
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700170
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700171 // ICE will be the last transport to be deleted.
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700172}
Zhi Huange818b6e2018-02-22 15:26:27 -0800173
Zhi Huang365381f2018-04-13 16:44:34 -0700174webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
Zhi Huange818b6e2018-02-22 15:26:27 -0800175 const JsepTransportDescription& jsep_description,
176 SdpType type) {
177 webrtc::RTCError error;
178
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200179 RTC_DCHECK_RUN_ON(network_thread_);
Steve Anton71ff0732020-01-24 16:28:15 -0800180
Jonas Oreland52aea5d2020-03-03 13:21:30 +0100181 IceParameters ice_parameters =
182 jsep_description.transport_desc.GetIceParameters();
183 webrtc::RTCError ice_parameters_result = ice_parameters.Validate();
Steve Anton71ff0732020-01-24 16:28:15 -0800184 if (!ice_parameters_result.ok()) {
185 rtc::StringBuilder sb;
Jonas Oreland52aea5d2020-03-03 13:21:30 +0100186 sb << "Invalid ICE parameters: " << ice_parameters_result.message();
Zhi Huange818b6e2018-02-22 15:26:27 -0800187 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
Steve Anton71ff0732020-01-24 16:28:15 -0800188 sb.Release());
Zhi Huange818b6e2018-02-22 15:26:27 -0800189 }
190
191 if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
192 ContentSource::CS_LOCAL)) {
193 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
194 "Failed to setup RTCP mux.");
195 }
196
197 // If doing SDES, setup the SDES crypto parameters.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700198 {
199 rtc::CritScope scope(&accessor_lock_);
200 if (sdes_transport_) {
201 RTC_DCHECK(!unencrypted_rtp_transport_);
202 RTC_DCHECK(!dtls_srtp_transport_);
203 if (!SetSdes(jsep_description.cryptos,
204 jsep_description.encrypted_header_extension_ids, type,
205 ContentSource::CS_LOCAL)) {
206 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
207 "Failed to setup SDES crypto parameters.");
208 }
209 } else if (dtls_srtp_transport_) {
210 RTC_DCHECK(!unencrypted_rtp_transport_);
211 RTC_DCHECK(!sdes_transport_);
212 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
213 jsep_description.encrypted_header_extension_ids);
Zhi Huange818b6e2018-02-22 15:26:27 -0800214 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800215 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800216 bool ice_restarting =
217 local_description_ != nullptr &&
218 IceCredentialsChanged(local_description_->transport_desc.ice_ufrag,
219 local_description_->transport_desc.ice_pwd,
Steve Anton71ff0732020-01-24 16:28:15 -0800220 ice_parameters.ufrag, ice_parameters.pwd);
Zhi Huange818b6e2018-02-22 15:26:27 -0800221 local_description_.reset(new JsepTransportDescription(jsep_description));
222
223 rtc::SSLFingerprint* local_fp =
224 local_description_->transport_desc.identity_fingerprint.get();
225
226 if (!local_fp) {
227 local_certificate_ = nullptr;
228 } else {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200229 error = VerifyCertificateFingerprint(local_certificate_, local_fp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800230 if (!error.ok()) {
231 local_description_.reset();
232 return error;
233 }
234 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200235 {
236 rtc::CritScope scope(&accessor_lock_);
237 RTC_DCHECK(rtp_dtls_transport_->internal());
Steve Anton71ff0732020-01-24 16:28:15 -0800238 rtp_dtls_transport_->internal()->ice_transport()->SetIceParameters(
239 ice_parameters);
Zhi Huange818b6e2018-02-22 15:26:27 -0800240
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200241 if (rtcp_dtls_transport_) {
242 RTC_DCHECK(rtcp_dtls_transport_->internal());
Steve Anton71ff0732020-01-24 16:28:15 -0800243 rtcp_dtls_transport_->internal()->ice_transport()->SetIceParameters(
244 ice_parameters);
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200245 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800246 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800247 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
248 if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
249 error = NegotiateAndSetDtlsParameters(type);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700250 NegotiateDatagramTransport(type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800251 }
252 if (!error.ok()) {
253 local_description_.reset();
254 return error;
255 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200256 {
257 rtc::CritScope scope(&accessor_lock_);
258 if (needs_ice_restart_ && ice_restarting) {
259 needs_ice_restart_ = false;
260 RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag cleared for transport "
261 << mid();
262 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800263 }
264
265 return webrtc::RTCError::OK();
266}
267
Zhi Huang365381f2018-04-13 16:44:34 -0700268webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription(
Zhi Huange818b6e2018-02-22 15:26:27 -0800269 const JsepTransportDescription& jsep_description,
270 webrtc::SdpType type) {
271 webrtc::RTCError error;
272
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200273 RTC_DCHECK_RUN_ON(network_thread_);
Steve Anton71ff0732020-01-24 16:28:15 -0800274
Jonas Oreland52aea5d2020-03-03 13:21:30 +0100275 IceParameters ice_parameters =
276 jsep_description.transport_desc.GetIceParameters();
277 webrtc::RTCError ice_parameters_result = ice_parameters.Validate();
Steve Anton71ff0732020-01-24 16:28:15 -0800278 if (!ice_parameters_result.ok()) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800279 remote_description_.reset();
Steve Anton71ff0732020-01-24 16:28:15 -0800280 rtc::StringBuilder sb;
Jonas Oreland52aea5d2020-03-03 13:21:30 +0100281 sb << "Invalid ICE parameters: " << ice_parameters_result.message();
Zhi Huange818b6e2018-02-22 15:26:27 -0800282 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
Steve Anton71ff0732020-01-24 16:28:15 -0800283 sb.Release());
Zhi Huange818b6e2018-02-22 15:26:27 -0800284 }
285
286 if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
287 ContentSource::CS_REMOTE)) {
288 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
289 "Failed to setup RTCP mux.");
290 }
291
292 // If doing SDES, setup the SDES crypto parameters.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700293 {
294 rtc::CritScope lock(&accessor_lock_);
295 if (sdes_transport_) {
296 RTC_DCHECK(!unencrypted_rtp_transport_);
297 RTC_DCHECK(!dtls_srtp_transport_);
298 if (!SetSdes(jsep_description.cryptos,
299 jsep_description.encrypted_header_extension_ids, type,
300 ContentSource::CS_REMOTE)) {
301 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
302 "Failed to setup SDES crypto parameters.");
303 }
304 sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
305 jsep_description.rtp_abs_sendtime_extn_id);
306 } else if (dtls_srtp_transport_) {
307 RTC_DCHECK(!unencrypted_rtp_transport_);
308 RTC_DCHECK(!sdes_transport_);
309 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
310 jsep_description.encrypted_header_extension_ids);
311 dtls_srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
312 jsep_description.rtp_abs_sendtime_extn_id);
Zhi Huange818b6e2018-02-22 15:26:27 -0800313 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800314 }
315
316 remote_description_.reset(new JsepTransportDescription(jsep_description));
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200317 RTC_DCHECK(rtp_dtls_transport());
Steve Anton71ff0732020-01-24 16:28:15 -0800318 SetRemoteIceParameters(ice_parameters, rtp_dtls_transport()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800319
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200320 if (rtcp_dtls_transport()) {
Steve Anton71ff0732020-01-24 16:28:15 -0800321 SetRemoteIceParameters(ice_parameters,
322 rtcp_dtls_transport()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800323 }
324
325 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
326 if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
327 error = NegotiateAndSetDtlsParameters(SdpType::kOffer);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700328 NegotiateDatagramTransport(type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800329 }
330 if (!error.ok()) {
331 remote_description_.reset();
332 return error;
333 }
334 return webrtc::RTCError::OK();
335}
336
Zhi Huang365381f2018-04-13 16:44:34 -0700337webrtc::RTCError JsepTransport::AddRemoteCandidates(
Zhi Huange818b6e2018-02-22 15:26:27 -0800338 const Candidates& candidates) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200339 RTC_DCHECK_RUN_ON(network_thread_);
Henrik Boström5d8f8fa2018-04-13 15:22:50 +0000340 if (!local_description_ || !remote_description_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800341 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
342 mid() +
343 " is not ready to use the remote candidate "
Henrik Boström5d8f8fa2018-04-13 15:22:50 +0000344 "because the local or remote description is "
345 "not set.");
Zhi Huange818b6e2018-02-22 15:26:27 -0800346 }
347
348 for (const cricket::Candidate& candidate : candidates) {
349 auto transport =
350 candidate.component() == cricket::ICE_CANDIDATE_COMPONENT_RTP
Harald Alvestrandad88c882018-11-28 16:47:46 +0100351 ? rtp_dtls_transport_
352 : rtcp_dtls_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800353 if (!transport) {
354 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
355 "Candidate has an unknown component: " +
Qingsi Wang20232a92019-09-06 12:51:17 -0700356 candidate.ToSensitiveString() + " for mid " +
357 mid());
Zhi Huange818b6e2018-02-22 15:26:27 -0800358 }
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100359 RTC_DCHECK(transport->internal() && transport->internal()->ice_transport());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100360 transport->internal()->ice_transport()->AddRemoteCandidate(candidate);
Zhi Huange818b6e2018-02-22 15:26:27 -0800361 }
362 return webrtc::RTCError::OK();
363}
364
Zhi Huang365381f2018-04-13 16:44:34 -0700365void JsepTransport::SetNeedsIceRestartFlag() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200366 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800367 if (!needs_ice_restart_) {
368 needs_ice_restart_ = true;
369 RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid();
370 }
371}
372
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200373absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200374 RTC_DCHECK_RUN_ON(network_thread_);
375 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800376 RTC_DCHECK(rtp_dtls_transport_);
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100377 RTC_DCHECK(rtp_dtls_transport_->internal());
Zhi Huange818b6e2018-02-22 15:26:27 -0800378 rtc::SSLRole dtls_role;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100379 if (!rtp_dtls_transport_->internal()->GetDtlsRole(&dtls_role)) {
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200380 return absl::optional<rtc::SSLRole>();
Zhi Huange818b6e2018-02-22 15:26:27 -0800381 }
382
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200383 return absl::optional<rtc::SSLRole>(dtls_role);
Zhi Huange818b6e2018-02-22 15:26:27 -0800384}
385
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700386absl::optional<OpaqueTransportParameters>
387JsepTransport::GetTransportParameters() const {
388 rtc::CritScope scope(&accessor_lock_);
389 if (!datagram_transport()) {
390 return absl::nullopt;
391 }
392
393 OpaqueTransportParameters params;
394 params.parameters = datagram_transport()->GetTransportParameters();
395 return params;
396}
397
Zhi Huang365381f2018-04-13 16:44:34 -0700398bool JsepTransport::GetStats(TransportStats* stats) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200399 RTC_DCHECK_RUN_ON(network_thread_);
400 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800401 stats->transport_name = mid();
402 stats->channel_stats.clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100403 RTC_DCHECK(rtp_dtls_transport_->internal());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100404 bool ret = GetTransportStats(rtp_dtls_transport_->internal(), stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800405 if (rtcp_dtls_transport_) {
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100406 RTC_DCHECK(rtcp_dtls_transport_->internal());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100407 ret &= GetTransportStats(rtcp_dtls_transport_->internal(), stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800408 }
409 return ret;
410}
411
Zhi Huang365381f2018-04-13 16:44:34 -0700412webrtc::RTCError JsepTransport::VerifyCertificateFingerprint(
Zhi Huange818b6e2018-02-22 15:26:27 -0800413 const rtc::RTCCertificate* certificate,
414 const rtc::SSLFingerprint* fingerprint) const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200415 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800416 if (!fingerprint) {
417 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
418 "No fingerprint");
419 }
420 if (!certificate) {
421 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
422 "Fingerprint provided but no identity available.");
423 }
Steve Anton4905edb2018-10-15 19:27:44 -0700424 std::unique_ptr<rtc::SSLFingerprint> fp_tmp =
425 rtc::SSLFingerprint::CreateUnique(fingerprint->algorithm,
426 *certificate->identity());
Zhi Huange818b6e2018-02-22 15:26:27 -0800427 RTC_DCHECK(fp_tmp.get() != NULL);
428 if (*fp_tmp == *fingerprint) {
429 return webrtc::RTCError::OK();
430 }
Zhi Huang365381f2018-04-13 16:44:34 -0700431 char ss_buf[1024];
432 rtc::SimpleStringBuilder desc(ss_buf);
Zhi Huange818b6e2018-02-22 15:26:27 -0800433 desc << "Local fingerprint does not match identity. Expected: ";
434 desc << fp_tmp->ToString();
435 desc << " Got: " << fingerprint->ToString();
Zhi Huang365381f2018-04-13 16:44:34 -0700436 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
437 std::string(desc.str()));
Zhi Huange818b6e2018-02-22 15:26:27 -0800438}
439
Zhi Huangb57e1692018-06-12 11:41:11 -0700440void JsepTransport::SetActiveResetSrtpParams(bool active_reset_srtp_params) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200441 RTC_DCHECK_RUN_ON(network_thread_);
442 rtc::CritScope scope(&accessor_lock_);
Zhi Huangb57e1692018-06-12 11:41:11 -0700443 if (dtls_srtp_transport_) {
444 RTC_LOG(INFO)
445 << "Setting active_reset_srtp_params of DtlsSrtpTransport to: "
446 << active_reset_srtp_params;
447 dtls_srtp_transport_->SetActiveResetSrtpParams(active_reset_srtp_params);
448 }
449}
450
Zhi Huang365381f2018-04-13 16:44:34 -0700451void JsepTransport::SetRemoteIceParameters(
Steve Anton71ff0732020-01-24 16:28:15 -0800452 const IceParameters& ice_parameters,
Zhi Huange818b6e2018-02-22 15:26:27 -0800453 IceTransportInternal* ice_transport) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200454 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800455 RTC_DCHECK(ice_transport);
456 RTC_DCHECK(remote_description_);
Steve Anton71ff0732020-01-24 16:28:15 -0800457 ice_transport->SetRemoteIceParameters(ice_parameters);
Zhi Huange818b6e2018-02-22 15:26:27 -0800458 ice_transport->SetRemoteIceMode(remote_description_->transport_desc.ice_mode);
459}
460
Zhi Huang365381f2018-04-13 16:44:34 -0700461webrtc::RTCError JsepTransport::SetNegotiatedDtlsParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800462 DtlsTransportInternal* dtls_transport,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200463 absl::optional<rtc::SSLRole> dtls_role,
Zhi Huange818b6e2018-02-22 15:26:27 -0800464 rtc::SSLFingerprint* remote_fingerprint) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200465 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800466 RTC_DCHECK(dtls_transport);
467 // Set SSL role. Role must be set before fingerprint is applied, which
468 // initiates DTLS setup.
469 if (dtls_role && !dtls_transport->SetDtlsRole(*dtls_role)) {
470 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
471 "Failed to set SSL role for the transport.");
472 }
473 // Apply remote fingerprint.
474 if (!remote_fingerprint ||
475 !dtls_transport->SetRemoteFingerprint(
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700476 remote_fingerprint->algorithm, remote_fingerprint->digest.cdata(),
Zhi Huange818b6e2018-02-22 15:26:27 -0800477 remote_fingerprint->digest.size())) {
478 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
479 "Failed to apply remote fingerprint.");
480 }
481 return webrtc::RTCError::OK();
482}
483
Zhi Huang365381f2018-04-13 16:44:34 -0700484bool JsepTransport::SetRtcpMux(bool enable,
485 webrtc::SdpType type,
486 ContentSource source) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200487 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800488 bool ret = false;
489 switch (type) {
490 case SdpType::kOffer:
491 ret = rtcp_mux_negotiator_.SetOffer(enable, source);
492 break;
493 case SdpType::kPrAnswer:
494 // This may activate RTCP muxing, but we don't yet destroy the transport
495 // because the final answer may deactivate it.
496 ret = rtcp_mux_negotiator_.SetProvisionalAnswer(enable, source);
497 break;
498 case SdpType::kAnswer:
499 ret = rtcp_mux_negotiator_.SetAnswer(enable, source);
500 if (ret && rtcp_mux_negotiator_.IsActive()) {
501 ActivateRtcpMux();
502 }
503 break;
504 default:
505 RTC_NOTREACHED();
506 }
507
508 if (!ret) {
509 return false;
510 }
511
512 auto transport = rtp_transport();
513 transport->SetRtcpMuxEnabled(rtcp_mux_negotiator_.IsActive());
514 return ret;
515}
516
Zhi Huang365381f2018-04-13 16:44:34 -0700517void JsepTransport::ActivateRtcpMux() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200518 {
519 // Don't hold the network_thread_ lock while calling other functions,
520 // since they might call other functions that call RTC_DCHECK_RUN_ON.
521 // TODO(https://crbug.com/webrtc/10318): Simplify when possible.
522 RTC_DCHECK_RUN_ON(network_thread_);
523 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200524 {
525 rtc::CritScope scope(&accessor_lock_);
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700526 if (unencrypted_rtp_transport_) {
527 RTC_DCHECK(!sdes_transport_);
528 RTC_DCHECK(!dtls_srtp_transport_);
529 unencrypted_rtp_transport_->SetRtcpPacketTransport(nullptr);
530 } else if (sdes_transport_) {
531 RTC_DCHECK(!unencrypted_rtp_transport_);
532 RTC_DCHECK(!dtls_srtp_transport_);
533 sdes_transport_->SetRtcpPacketTransport(nullptr);
534 } else if (dtls_srtp_transport_) {
535 RTC_DCHECK(dtls_srtp_transport_);
536 RTC_DCHECK(!unencrypted_rtp_transport_);
537 RTC_DCHECK(!sdes_transport_);
538 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport(),
539 /*rtcp_dtls_transport=*/nullptr);
540 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200541 rtcp_dtls_transport_ = nullptr; // Destroy this reference.
542 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800543 // Notify the JsepTransportController to update the aggregate states.
544 SignalRtcpMuxActive();
545}
546
Zhi Huang365381f2018-04-13 16:44:34 -0700547bool JsepTransport::SetSdes(const std::vector<CryptoParams>& cryptos,
548 const std::vector<int>& encrypted_extension_ids,
549 webrtc::SdpType type,
550 ContentSource source) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200551 RTC_DCHECK_RUN_ON(network_thread_);
552 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800553 bool ret = false;
554 ret = sdes_negotiator_.Process(cryptos, type, source);
555 if (!ret) {
556 return ret;
557 }
558
559 if (source == ContentSource::CS_LOCAL) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700560 recv_extension_ids_ = encrypted_extension_ids;
Zhi Huange818b6e2018-02-22 15:26:27 -0800561 } else {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700562 send_extension_ids_ = encrypted_extension_ids;
Zhi Huange818b6e2018-02-22 15:26:27 -0800563 }
564
565 // If setting an SDES answer succeeded, apply the negotiated parameters
566 // to the SRTP transport.
567 if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) {
568 if (sdes_negotiator_.send_cipher_suite() &&
569 sdes_negotiator_.recv_cipher_suite()) {
570 RTC_DCHECK(send_extension_ids_);
571 RTC_DCHECK(recv_extension_ids_);
572 ret = sdes_transport_->SetRtpParams(
573 *(sdes_negotiator_.send_cipher_suite()),
574 sdes_negotiator_.send_key().data(),
575 static_cast<int>(sdes_negotiator_.send_key().size()),
576 *(send_extension_ids_), *(sdes_negotiator_.recv_cipher_suite()),
577 sdes_negotiator_.recv_key().data(),
578 static_cast<int>(sdes_negotiator_.recv_key().size()),
579 *(recv_extension_ids_));
580 } else {
581 RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES.";
582 if (type == SdpType::kAnswer) {
583 // Explicitly reset the |sdes_transport_| if no crypto param is
584 // provided in the answer. No need to call |ResetParams()| for
585 // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
586 sdes_transport_->ResetParams();
587 }
588 }
589 }
590 return ret;
591}
592
Zhi Huang365381f2018-04-13 16:44:34 -0700593webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800594 SdpType local_description_type) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200595 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800596 if (!local_description_ || !remote_description_) {
597 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
598 "Applying an answer transport description "
599 "without applying any offer.");
600 }
601 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200602 absl::optional<rtc::SSLRole> negotiated_dtls_role;
Zhi Huange818b6e2018-02-22 15:26:27 -0800603
604 rtc::SSLFingerprint* local_fp =
605 local_description_->transport_desc.identity_fingerprint.get();
606 rtc::SSLFingerprint* remote_fp =
607 remote_description_->transport_desc.identity_fingerprint.get();
608 if (remote_fp && local_fp) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200609 remote_fingerprint = std::make_unique<rtc::SSLFingerprint>(*remote_fp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800610 webrtc::RTCError error =
611 NegotiateDtlsRole(local_description_type,
612 local_description_->transport_desc.connection_role,
613 remote_description_->transport_desc.connection_role,
614 &negotiated_dtls_role);
615 if (!error.ok()) {
616 return error;
617 }
618 } else if (local_fp && (local_description_type == SdpType::kAnswer)) {
619 return webrtc::RTCError(
620 webrtc::RTCErrorType::INVALID_PARAMETER,
621 "Local fingerprint supplied when caller didn't offer DTLS.");
622 } else {
623 // We are not doing DTLS
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200624 remote_fingerprint = std::make_unique<rtc::SSLFingerprint>(
Steve Anton4905edb2018-10-15 19:27:44 -0700625 "", rtc::ArrayView<const uint8_t>());
Zhi Huange818b6e2018-02-22 15:26:27 -0800626 }
627 // Now that we have negotiated everything, push it downward.
628 // Note that we cache the result so that if we have race conditions
629 // between future SetRemote/SetLocal invocations and new transport
630 // creation, we have the negotiation state saved until a new
631 // negotiation happens.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200632 RTC_DCHECK(rtp_dtls_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800633 webrtc::RTCError error = SetNegotiatedDtlsParameters(
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200634 rtp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800635 if (!error.ok()) {
636 return error;
637 }
638
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200639 if (rtcp_dtls_transport()) {
640 error = SetNegotiatedDtlsParameters(
641 rtcp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800642 }
643 return error;
644}
645
Zhi Huang365381f2018-04-13 16:44:34 -0700646webrtc::RTCError JsepTransport::NegotiateDtlsRole(
Zhi Huange818b6e2018-02-22 15:26:27 -0800647 SdpType local_description_type,
648 ConnectionRole local_connection_role,
649 ConnectionRole remote_connection_role,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200650 absl::optional<rtc::SSLRole>* negotiated_dtls_role) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800651 // From RFC 4145, section-4.1, The following are the values that the
652 // 'setup' attribute can take in an offer/answer exchange:
653 // Offer Answer
654 // ________________
655 // active passive / holdconn
656 // passive active / holdconn
657 // actpass active / passive / holdconn
658 // holdconn holdconn
659 //
660 // Set the role that is most conformant with RFC 5763, Section 5, bullet 1
661 // The endpoint MUST use the setup attribute defined in [RFC4145].
662 // The endpoint that is the offerer MUST use the setup attribute
663 // value of setup:actpass and be prepared to receive a client_hello
664 // before it receives the answer. The answerer MUST use either a
665 // setup attribute value of setup:active or setup:passive. Note that
666 // if the answerer uses setup:passive, then the DTLS handshake will
667 // not begin until the answerer is received, which adds additional
668 // latency. setup:active allows the answer and the DTLS handshake to
669 // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever
670 // party is active MUST initiate a DTLS handshake by sending a
671 // ClientHello over each flow (host/port quartet).
672 // IOW - actpass and passive modes should be treated as server and
673 // active as client.
674 bool is_remote_server = false;
675 if (local_description_type == SdpType::kOffer) {
676 if (local_connection_role != CONNECTIONROLE_ACTPASS) {
677 return webrtc::RTCError(
678 webrtc::RTCErrorType::INVALID_PARAMETER,
679 "Offerer must use actpass value for setup attribute.");
680 }
681
682 if (remote_connection_role == CONNECTIONROLE_ACTIVE ||
683 remote_connection_role == CONNECTIONROLE_PASSIVE ||
684 remote_connection_role == CONNECTIONROLE_NONE) {
685 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE);
686 } else {
687 return webrtc::RTCError(
688 webrtc::RTCErrorType::INVALID_PARAMETER,
689 "Answerer must use either active or passive value "
690 "for setup attribute.");
691 }
692 // If remote is NONE or ACTIVE it will act as client.
693 } else {
694 if (remote_connection_role != CONNECTIONROLE_ACTPASS &&
695 remote_connection_role != CONNECTIONROLE_NONE) {
696 // Accept a remote role attribute that's not "actpass", but matches the
697 // current negotiated role. This is allowed by dtls-sdp, though our
698 // implementation will never generate such an offer as it's not
699 // recommended.
700 //
701 // See https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-dtls-sdp,
702 // section 5.5.
703 auto current_dtls_role = GetDtlsRole();
704 if (!current_dtls_role ||
705 (*current_dtls_role == rtc::SSL_CLIENT &&
706 remote_connection_role == CONNECTIONROLE_ACTIVE) ||
707 (*current_dtls_role == rtc::SSL_SERVER &&
708 remote_connection_role == CONNECTIONROLE_PASSIVE)) {
709 return webrtc::RTCError(
710 webrtc::RTCErrorType::INVALID_PARAMETER,
711 "Offerer must use actpass value or current negotiated role for "
712 "setup attribute.");
713 }
714 }
715
716 if (local_connection_role == CONNECTIONROLE_ACTIVE ||
717 local_connection_role == CONNECTIONROLE_PASSIVE) {
718 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE);
719 } else {
720 return webrtc::RTCError(
721 webrtc::RTCErrorType::INVALID_PARAMETER,
722 "Answerer must use either active or passive value "
723 "for setup attribute.");
724 }
725
726 // If local is passive, local will act as server.
727 }
728
Mirko Bonadei05cf6be2019-01-31 21:38:12 +0100729 *negotiated_dtls_role =
730 (is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER);
Zhi Huange818b6e2018-02-22 15:26:27 -0800731 return webrtc::RTCError::OK();
732}
733
Zhi Huang365381f2018-04-13 16:44:34 -0700734bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
735 TransportStats* stats) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200736 RTC_DCHECK_RUN_ON(network_thread_);
737 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800738 RTC_DCHECK(dtls_transport);
739 TransportChannelStats substats;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100740 if (rtcp_dtls_transport_) {
741 substats.component = dtls_transport == rtcp_dtls_transport_->internal()
742 ? ICE_CANDIDATE_COMPONENT_RTCP
743 : ICE_CANDIDATE_COMPONENT_RTP;
744 } else {
745 substats.component = ICE_CANDIDATE_COMPONENT_RTP;
746 }
Harald Alvestrand5cb78072019-10-28 09:51:17 +0100747 dtls_transport->GetSslVersionBytes(&substats.ssl_version_bytes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800748 dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
749 dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
750 substats.dtls_state = dtls_transport->dtls_state();
751 if (!dtls_transport->ice_transport()->GetStats(
Jonas Oreland149dc722019-08-28 08:10:27 +0200752 &substats.ice_transport_stats)) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800753 return false;
754 }
755 stats->channel_stats.push_back(substats);
756 return true;
757}
758
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700759void JsepTransport::NegotiateDatagramTransport(SdpType type) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700760 RTC_DCHECK(type == SdpType::kAnswer || type == SdpType::kPrAnswer);
761 rtc::CritScope lock(&accessor_lock_);
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700762 if (!datagram_transport_) {
763 return; // No need to negotiate the use of datagram transport.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700764 }
765
Bjorn A Mellem0cda7b82020-01-28 17:06:55 -0800766 bool compatible_datagram_transport = false;
767 if (datagram_transport_ &&
768 local_description_->transport_desc.opaque_parameters &&
769 remote_description_->transport_desc.opaque_parameters) {
770 // If both descriptions have datagram transport parameters, and the remote
771 // parameters are accepted by the datagram transport, then use the datagram
772 // transport. Otherwise, fall back to RTP.
773 compatible_datagram_transport =
774 datagram_transport_
775 ->SetRemoteTransportParameters(remote_description_->transport_desc
776 .opaque_parameters->parameters)
777 .ok();
778 }
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700779
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700780 bool use_datagram_transport_for_media =
781 compatible_datagram_transport &&
782 remote_description_->media_alt_protocol ==
783 remote_description_->transport_desc.opaque_parameters->protocol &&
784 remote_description_->media_alt_protocol ==
785 local_description_->media_alt_protocol;
786
787 bool use_datagram_transport_for_data =
788 compatible_datagram_transport &&
789 remote_description_->data_alt_protocol ==
790 remote_description_->transport_desc.opaque_parameters->protocol &&
791 remote_description_->data_alt_protocol ==
792 local_description_->data_alt_protocol;
793
794 RTC_LOG(LS_INFO)
795 << "Negotiating datagram transport, use_datagram_transport_for_media="
796 << use_datagram_transport_for_media
797 << ", use_datagram_transport_for_data=" << use_datagram_transport_for_data
798 << " answer type=" << (type == SdpType::kAnswer ? "answer" : "pr_answer");
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700799
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700800 // A provisional or full or answer lets the peer start sending on one of the
801 // transports.
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700802 if (composite_rtp_transport_) {
803 composite_rtp_transport_->SetSendTransport(
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700804 use_datagram_transport_for_media ? datagram_rtp_transport_.get()
805 : default_rtp_transport());
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700806 }
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700807 if (composite_data_channel_transport_) {
808 composite_data_channel_transport_->SetSendTransport(
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700809 use_datagram_transport_for_data ? data_channel_transport_
810 : sctp_data_channel_transport_.get());
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700811 }
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700812
813 if (type != SdpType::kAnswer) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700814 return;
815 }
816
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700817 if (composite_rtp_transport_) {
818 if (use_datagram_transport_for_media) {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700819 // Negotiated use of datagram transport for RTP, so remove the
820 // non-datagram RTP transport.
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700821 composite_rtp_transport_->RemoveTransport(default_rtp_transport());
822 if (unencrypted_rtp_transport_) {
823 unencrypted_rtp_transport_ = nullptr;
824 } else if (sdes_transport_) {
825 sdes_transport_ = nullptr;
826 } else {
827 dtls_srtp_transport_ = nullptr;
828 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700829 } else {
830 composite_rtp_transport_->RemoveTransport(datagram_rtp_transport_.get());
831 datagram_rtp_transport_ = nullptr;
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700832 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700833 }
834
835 if (composite_data_channel_transport_) {
836 if (use_datagram_transport_for_data) {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700837 // Negotiated use of datagram transport for data channels, so remove the
838 // non-datagram data channel transport.
839 composite_data_channel_transport_->RemoveTransport(
840 sctp_data_channel_transport_.get());
841 sctp_data_channel_transport_ = nullptr;
842 sctp_transport_ = nullptr;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700843 } else {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700844 composite_data_channel_transport_->RemoveTransport(
845 data_channel_transport_);
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700846 data_channel_transport_ = nullptr;
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700847 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700848 } else if (data_channel_transport_ && !use_datagram_transport_for_data) {
849 // The datagram transport has been rejected without a fallback. We still
850 // need to inform the application and delete it.
851 SignalDataChannelTransportNegotiated(this, nullptr);
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700852 data_channel_transport_ = nullptr;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700853 }
854
855 if (!use_datagram_transport_for_media && !use_datagram_transport_for_data) {
856 // Datagram transport is not being used for anything, so clean it up.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700857 datagram_transport_ = nullptr;
858 }
859}
860
Zhi Huange818b6e2018-02-22 15:26:27 -0800861} // namespace cricket