blob: 37f31628dd7c76e618fb55706d8a2531e7899431 [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,
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700114 std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport,
115 webrtc::DataChannelTransportInterface* data_channel_transport)
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200116 : network_thread_(rtc::Thread::Current()),
117 mid_(mid),
Zhi Huange818b6e2018-02-22 15:26:27 -0800118 local_certificate_(local_certificate),
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700119 ice_transport_(std::move(ice_transport)),
120 rtcp_ice_transport_(std::move(rtcp_ice_transport)),
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200121 unencrypted_rtp_transport_(std::move(unencrypted_rtp_transport)),
122 sdes_transport_(std::move(sdes_transport)),
123 dtls_srtp_transport_(std::move(dtls_srtp_transport)),
Harald Alvestrandad88c882018-11-28 16:47:46 +0100124 rtp_dtls_transport_(
125 rtp_dtls_transport ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
126 std::move(rtp_dtls_transport))
127 : nullptr),
128 rtcp_dtls_transport_(
129 rtcp_dtls_transport
130 ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
131 std::move(rtcp_dtls_transport))
132 : nullptr),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700133 sctp_data_channel_transport_(
134 sctp_transport ? std::make_unique<webrtc::SctpDataChannelTransport>(
135 sctp_transport.get())
136 : nullptr),
137 sctp_transport_(sctp_transport
138 ? new rtc::RefCountedObject<webrtc::SctpTransport>(
139 std::move(sctp_transport))
140 : nullptr),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700141 datagram_transport_(std::move(datagram_transport)),
Bjorn A Mellemfc604aa2019-09-24 14:59:21 -0700142 datagram_rtp_transport_(std::move(datagram_rtp_transport)),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700143 data_channel_transport_(data_channel_transport) {
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700144 RTC_DCHECK(ice_transport_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800145 RTC_DCHECK(rtp_dtls_transport_);
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700146 // |rtcp_ice_transport_| must be present iff |rtcp_dtls_transport_| is
147 // present.
148 RTC_DCHECK_EQ((rtcp_ice_transport_ != nullptr),
149 (rtcp_dtls_transport_ != nullptr));
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200150 // Verify the "only one out of these three can be set" invariant.
151 if (unencrypted_rtp_transport_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800152 RTC_DCHECK(!sdes_transport);
153 RTC_DCHECK(!dtls_srtp_transport);
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200154 } else if (sdes_transport_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800155 RTC_DCHECK(!unencrypted_rtp_transport);
156 RTC_DCHECK(!dtls_srtp_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800157 } else {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200158 RTC_DCHECK(dtls_srtp_transport_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800159 RTC_DCHECK(!unencrypted_rtp_transport);
160 RTC_DCHECK(!sdes_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800161 }
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700162
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700163 if (sctp_transport_) {
164 sctp_transport_->SetDtlsTransport(rtp_dtls_transport_);
165 }
166
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700167 if (datagram_rtp_transport_ && default_rtp_transport()) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200168 composite_rtp_transport_ = std::make_unique<webrtc::CompositeRtpTransport>(
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700169 std::vector<webrtc::RtpTransportInternal*>{
170 datagram_rtp_transport_.get(), default_rtp_transport()});
171 }
172
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700173 if (data_channel_transport_ && sctp_data_channel_transport_) {
174 composite_data_channel_transport_ =
175 std::make_unique<webrtc::CompositeDataChannelTransport>(
176 std::vector<webrtc::DataChannelTransportInterface*>{
177 data_channel_transport_, sctp_data_channel_transport_.get()});
178 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800179}
180
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700181JsepTransport::~JsepTransport() {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700182 if (sctp_transport_) {
183 sctp_transport_->Clear();
184 }
185
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100186 // Clear all DtlsTransports. There may be pointers to these from
187 // other places, so we can't assume they'll be deleted by the destructor.
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100188 rtp_dtls_transport_->Clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100189 if (rtcp_dtls_transport_) {
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100190 rtcp_dtls_transport_->Clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100191 }
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700192
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700193 // ICE will be the last transport to be deleted.
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700194}
Zhi Huange818b6e2018-02-22 15:26:27 -0800195
Zhi Huang365381f2018-04-13 16:44:34 -0700196webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
Zhi Huange818b6e2018-02-22 15:26:27 -0800197 const JsepTransportDescription& jsep_description,
198 SdpType type) {
199 webrtc::RTCError error;
200
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200201 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800202 if (!VerifyIceParams(jsep_description)) {
203 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
204 "Invalid ice-ufrag or ice-pwd length.");
205 }
206
207 if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
208 ContentSource::CS_LOCAL)) {
209 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
210 "Failed to setup RTCP mux.");
211 }
212
213 // If doing SDES, setup the SDES crypto parameters.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700214 {
215 rtc::CritScope scope(&accessor_lock_);
216 if (sdes_transport_) {
217 RTC_DCHECK(!unencrypted_rtp_transport_);
218 RTC_DCHECK(!dtls_srtp_transport_);
219 if (!SetSdes(jsep_description.cryptos,
220 jsep_description.encrypted_header_extension_ids, type,
221 ContentSource::CS_LOCAL)) {
222 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
223 "Failed to setup SDES crypto parameters.");
224 }
225 } else if (dtls_srtp_transport_) {
226 RTC_DCHECK(!unencrypted_rtp_transport_);
227 RTC_DCHECK(!sdes_transport_);
228 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
229 jsep_description.encrypted_header_extension_ids);
Zhi Huange818b6e2018-02-22 15:26:27 -0800230 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800231 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800232 bool ice_restarting =
233 local_description_ != nullptr &&
234 IceCredentialsChanged(local_description_->transport_desc.ice_ufrag,
235 local_description_->transport_desc.ice_pwd,
236 jsep_description.transport_desc.ice_ufrag,
237 jsep_description.transport_desc.ice_pwd);
238 local_description_.reset(new JsepTransportDescription(jsep_description));
239
240 rtc::SSLFingerprint* local_fp =
241 local_description_->transport_desc.identity_fingerprint.get();
242
243 if (!local_fp) {
244 local_certificate_ = nullptr;
245 } else {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200246 error = VerifyCertificateFingerprint(local_certificate_, local_fp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800247 if (!error.ok()) {
248 local_description_.reset();
249 return error;
250 }
251 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200252 {
253 rtc::CritScope scope(&accessor_lock_);
254 RTC_DCHECK(rtp_dtls_transport_->internal());
255 SetLocalIceParameters(rtp_dtls_transport_->internal()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800256
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200257 if (rtcp_dtls_transport_) {
258 RTC_DCHECK(rtcp_dtls_transport_->internal());
259 SetLocalIceParameters(rtcp_dtls_transport_->internal()->ice_transport());
260 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800261 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800262 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
263 if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
264 error = NegotiateAndSetDtlsParameters(type);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700265 NegotiateDatagramTransport(type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800266 }
267 if (!error.ok()) {
268 local_description_.reset();
269 return error;
270 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200271 {
272 rtc::CritScope scope(&accessor_lock_);
273 if (needs_ice_restart_ && ice_restarting) {
274 needs_ice_restart_ = false;
275 RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag cleared for transport "
276 << mid();
277 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800278 }
279
280 return webrtc::RTCError::OK();
281}
282
Zhi Huang365381f2018-04-13 16:44:34 -0700283webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription(
Zhi Huange818b6e2018-02-22 15:26:27 -0800284 const JsepTransportDescription& jsep_description,
285 webrtc::SdpType type) {
286 webrtc::RTCError error;
287
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200288 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800289 if (!VerifyIceParams(jsep_description)) {
290 remote_description_.reset();
291 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
292 "Invalid ice-ufrag or ice-pwd length.");
293 }
294
295 if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
296 ContentSource::CS_REMOTE)) {
297 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
298 "Failed to setup RTCP mux.");
299 }
300
301 // If doing SDES, setup the SDES crypto parameters.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700302 {
303 rtc::CritScope lock(&accessor_lock_);
304 if (sdes_transport_) {
305 RTC_DCHECK(!unencrypted_rtp_transport_);
306 RTC_DCHECK(!dtls_srtp_transport_);
307 if (!SetSdes(jsep_description.cryptos,
308 jsep_description.encrypted_header_extension_ids, type,
309 ContentSource::CS_REMOTE)) {
310 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
311 "Failed to setup SDES crypto parameters.");
312 }
313 sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
314 jsep_description.rtp_abs_sendtime_extn_id);
315 } else if (dtls_srtp_transport_) {
316 RTC_DCHECK(!unencrypted_rtp_transport_);
317 RTC_DCHECK(!sdes_transport_);
318 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
319 jsep_description.encrypted_header_extension_ids);
320 dtls_srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
321 jsep_description.rtp_abs_sendtime_extn_id);
Zhi Huange818b6e2018-02-22 15:26:27 -0800322 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800323 }
324
325 remote_description_.reset(new JsepTransportDescription(jsep_description));
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200326 RTC_DCHECK(rtp_dtls_transport());
327 SetRemoteIceParameters(rtp_dtls_transport()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800328
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200329 if (rtcp_dtls_transport()) {
330 SetRemoteIceParameters(rtcp_dtls_transport()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800331 }
332
333 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
334 if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
335 error = NegotiateAndSetDtlsParameters(SdpType::kOffer);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700336 NegotiateDatagramTransport(type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800337 }
338 if (!error.ok()) {
339 remote_description_.reset();
340 return error;
341 }
342 return webrtc::RTCError::OK();
343}
344
Zhi Huang365381f2018-04-13 16:44:34 -0700345webrtc::RTCError JsepTransport::AddRemoteCandidates(
Zhi Huange818b6e2018-02-22 15:26:27 -0800346 const Candidates& candidates) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200347 RTC_DCHECK_RUN_ON(network_thread_);
Henrik Boström5d8f8fa2018-04-13 15:22:50 +0000348 if (!local_description_ || !remote_description_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800349 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
350 mid() +
351 " is not ready to use the remote candidate "
Henrik Boström5d8f8fa2018-04-13 15:22:50 +0000352 "because the local or remote description is "
353 "not set.");
Zhi Huange818b6e2018-02-22 15:26:27 -0800354 }
355
356 for (const cricket::Candidate& candidate : candidates) {
357 auto transport =
358 candidate.component() == cricket::ICE_CANDIDATE_COMPONENT_RTP
Harald Alvestrandad88c882018-11-28 16:47:46 +0100359 ? rtp_dtls_transport_
360 : rtcp_dtls_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800361 if (!transport) {
362 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
363 "Candidate has an unknown component: " +
Qingsi Wang20232a92019-09-06 12:51:17 -0700364 candidate.ToSensitiveString() + " for mid " +
365 mid());
Zhi Huange818b6e2018-02-22 15:26:27 -0800366 }
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100367 RTC_DCHECK(transport->internal() && transport->internal()->ice_transport());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100368 transport->internal()->ice_transport()->AddRemoteCandidate(candidate);
Zhi Huange818b6e2018-02-22 15:26:27 -0800369 }
370 return webrtc::RTCError::OK();
371}
372
Zhi Huang365381f2018-04-13 16:44:34 -0700373void JsepTransport::SetNeedsIceRestartFlag() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200374 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800375 if (!needs_ice_restart_) {
376 needs_ice_restart_ = true;
377 RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid();
378 }
379}
380
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200381absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200382 RTC_DCHECK_RUN_ON(network_thread_);
383 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800384 RTC_DCHECK(rtp_dtls_transport_);
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100385 RTC_DCHECK(rtp_dtls_transport_->internal());
Zhi Huange818b6e2018-02-22 15:26:27 -0800386 rtc::SSLRole dtls_role;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100387 if (!rtp_dtls_transport_->internal()->GetDtlsRole(&dtls_role)) {
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200388 return absl::optional<rtc::SSLRole>();
Zhi Huange818b6e2018-02-22 15:26:27 -0800389 }
390
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200391 return absl::optional<rtc::SSLRole>(dtls_role);
Zhi Huange818b6e2018-02-22 15:26:27 -0800392}
393
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700394absl::optional<OpaqueTransportParameters>
395JsepTransport::GetTransportParameters() const {
396 rtc::CritScope scope(&accessor_lock_);
397 if (!datagram_transport()) {
398 return absl::nullopt;
399 }
400
401 OpaqueTransportParameters params;
402 params.parameters = datagram_transport()->GetTransportParameters();
403 return params;
404}
405
Zhi Huang365381f2018-04-13 16:44:34 -0700406bool JsepTransport::GetStats(TransportStats* stats) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200407 RTC_DCHECK_RUN_ON(network_thread_);
408 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800409 stats->transport_name = mid();
410 stats->channel_stats.clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100411 RTC_DCHECK(rtp_dtls_transport_->internal());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100412 bool ret = GetTransportStats(rtp_dtls_transport_->internal(), stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800413 if (rtcp_dtls_transport_) {
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100414 RTC_DCHECK(rtcp_dtls_transport_->internal());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100415 ret &= GetTransportStats(rtcp_dtls_transport_->internal(), stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800416 }
417 return ret;
418}
419
Zhi Huang365381f2018-04-13 16:44:34 -0700420webrtc::RTCError JsepTransport::VerifyCertificateFingerprint(
Zhi Huange818b6e2018-02-22 15:26:27 -0800421 const rtc::RTCCertificate* certificate,
422 const rtc::SSLFingerprint* fingerprint) const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200423 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800424 if (!fingerprint) {
425 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
426 "No fingerprint");
427 }
428 if (!certificate) {
429 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
430 "Fingerprint provided but no identity available.");
431 }
Steve Anton4905edb2018-10-15 19:27:44 -0700432 std::unique_ptr<rtc::SSLFingerprint> fp_tmp =
433 rtc::SSLFingerprint::CreateUnique(fingerprint->algorithm,
434 *certificate->identity());
Zhi Huange818b6e2018-02-22 15:26:27 -0800435 RTC_DCHECK(fp_tmp.get() != NULL);
436 if (*fp_tmp == *fingerprint) {
437 return webrtc::RTCError::OK();
438 }
Zhi Huang365381f2018-04-13 16:44:34 -0700439 char ss_buf[1024];
440 rtc::SimpleStringBuilder desc(ss_buf);
Zhi Huange818b6e2018-02-22 15:26:27 -0800441 desc << "Local fingerprint does not match identity. Expected: ";
442 desc << fp_tmp->ToString();
443 desc << " Got: " << fingerprint->ToString();
Zhi Huang365381f2018-04-13 16:44:34 -0700444 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
445 std::string(desc.str()));
Zhi Huange818b6e2018-02-22 15:26:27 -0800446}
447
Zhi Huangb57e1692018-06-12 11:41:11 -0700448void JsepTransport::SetActiveResetSrtpParams(bool active_reset_srtp_params) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200449 RTC_DCHECK_RUN_ON(network_thread_);
450 rtc::CritScope scope(&accessor_lock_);
Zhi Huangb57e1692018-06-12 11:41:11 -0700451 if (dtls_srtp_transport_) {
452 RTC_LOG(INFO)
453 << "Setting active_reset_srtp_params of DtlsSrtpTransport to: "
454 << active_reset_srtp_params;
455 dtls_srtp_transport_->SetActiveResetSrtpParams(active_reset_srtp_params);
456 }
457}
458
Zhi Huang365381f2018-04-13 16:44:34 -0700459void JsepTransport::SetLocalIceParameters(IceTransportInternal* ice_transport) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200460 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800461 RTC_DCHECK(ice_transport);
462 RTC_DCHECK(local_description_);
463 ice_transport->SetIceParameters(
464 local_description_->transport_desc.GetIceParameters());
465}
466
Zhi Huang365381f2018-04-13 16:44:34 -0700467void JsepTransport::SetRemoteIceParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800468 IceTransportInternal* ice_transport) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200469 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800470 RTC_DCHECK(ice_transport);
471 RTC_DCHECK(remote_description_);
472 ice_transport->SetRemoteIceParameters(
473 remote_description_->transport_desc.GetIceParameters());
474 ice_transport->SetRemoteIceMode(remote_description_->transport_desc.ice_mode);
475}
476
Zhi Huang365381f2018-04-13 16:44:34 -0700477webrtc::RTCError JsepTransport::SetNegotiatedDtlsParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800478 DtlsTransportInternal* dtls_transport,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200479 absl::optional<rtc::SSLRole> dtls_role,
Zhi Huange818b6e2018-02-22 15:26:27 -0800480 rtc::SSLFingerprint* remote_fingerprint) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200481 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800482 RTC_DCHECK(dtls_transport);
483 // Set SSL role. Role must be set before fingerprint is applied, which
484 // initiates DTLS setup.
485 if (dtls_role && !dtls_transport->SetDtlsRole(*dtls_role)) {
486 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
487 "Failed to set SSL role for the transport.");
488 }
489 // Apply remote fingerprint.
490 if (!remote_fingerprint ||
491 !dtls_transport->SetRemoteFingerprint(
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700492 remote_fingerprint->algorithm, remote_fingerprint->digest.cdata(),
Zhi Huange818b6e2018-02-22 15:26:27 -0800493 remote_fingerprint->digest.size())) {
494 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
495 "Failed to apply remote fingerprint.");
496 }
497 return webrtc::RTCError::OK();
498}
499
Zhi Huang365381f2018-04-13 16:44:34 -0700500bool JsepTransport::SetRtcpMux(bool enable,
501 webrtc::SdpType type,
502 ContentSource source) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200503 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800504 bool ret = false;
505 switch (type) {
506 case SdpType::kOffer:
507 ret = rtcp_mux_negotiator_.SetOffer(enable, source);
508 break;
509 case SdpType::kPrAnswer:
510 // This may activate RTCP muxing, but we don't yet destroy the transport
511 // because the final answer may deactivate it.
512 ret = rtcp_mux_negotiator_.SetProvisionalAnswer(enable, source);
513 break;
514 case SdpType::kAnswer:
515 ret = rtcp_mux_negotiator_.SetAnswer(enable, source);
516 if (ret && rtcp_mux_negotiator_.IsActive()) {
517 ActivateRtcpMux();
518 }
519 break;
520 default:
521 RTC_NOTREACHED();
522 }
523
524 if (!ret) {
525 return false;
526 }
527
528 auto transport = rtp_transport();
529 transport->SetRtcpMuxEnabled(rtcp_mux_negotiator_.IsActive());
530 return ret;
531}
532
Zhi Huang365381f2018-04-13 16:44:34 -0700533void JsepTransport::ActivateRtcpMux() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200534 {
535 // Don't hold the network_thread_ lock while calling other functions,
536 // since they might call other functions that call RTC_DCHECK_RUN_ON.
537 // TODO(https://crbug.com/webrtc/10318): Simplify when possible.
538 RTC_DCHECK_RUN_ON(network_thread_);
539 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200540 {
541 rtc::CritScope scope(&accessor_lock_);
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700542 if (unencrypted_rtp_transport_) {
543 RTC_DCHECK(!sdes_transport_);
544 RTC_DCHECK(!dtls_srtp_transport_);
545 unencrypted_rtp_transport_->SetRtcpPacketTransport(nullptr);
546 } else if (sdes_transport_) {
547 RTC_DCHECK(!unencrypted_rtp_transport_);
548 RTC_DCHECK(!dtls_srtp_transport_);
549 sdes_transport_->SetRtcpPacketTransport(nullptr);
550 } else if (dtls_srtp_transport_) {
551 RTC_DCHECK(dtls_srtp_transport_);
552 RTC_DCHECK(!unencrypted_rtp_transport_);
553 RTC_DCHECK(!sdes_transport_);
554 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport(),
555 /*rtcp_dtls_transport=*/nullptr);
556 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200557 rtcp_dtls_transport_ = nullptr; // Destroy this reference.
558 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800559 // Notify the JsepTransportController to update the aggregate states.
560 SignalRtcpMuxActive();
561}
562
Zhi Huang365381f2018-04-13 16:44:34 -0700563bool JsepTransport::SetSdes(const std::vector<CryptoParams>& cryptos,
564 const std::vector<int>& encrypted_extension_ids,
565 webrtc::SdpType type,
566 ContentSource source) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200567 RTC_DCHECK_RUN_ON(network_thread_);
568 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800569 bool ret = false;
570 ret = sdes_negotiator_.Process(cryptos, type, source);
571 if (!ret) {
572 return ret;
573 }
574
575 if (source == ContentSource::CS_LOCAL) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700576 recv_extension_ids_ = encrypted_extension_ids;
Zhi Huange818b6e2018-02-22 15:26:27 -0800577 } else {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700578 send_extension_ids_ = encrypted_extension_ids;
Zhi Huange818b6e2018-02-22 15:26:27 -0800579 }
580
581 // If setting an SDES answer succeeded, apply the negotiated parameters
582 // to the SRTP transport.
583 if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) {
584 if (sdes_negotiator_.send_cipher_suite() &&
585 sdes_negotiator_.recv_cipher_suite()) {
586 RTC_DCHECK(send_extension_ids_);
587 RTC_DCHECK(recv_extension_ids_);
588 ret = sdes_transport_->SetRtpParams(
589 *(sdes_negotiator_.send_cipher_suite()),
590 sdes_negotiator_.send_key().data(),
591 static_cast<int>(sdes_negotiator_.send_key().size()),
592 *(send_extension_ids_), *(sdes_negotiator_.recv_cipher_suite()),
593 sdes_negotiator_.recv_key().data(),
594 static_cast<int>(sdes_negotiator_.recv_key().size()),
595 *(recv_extension_ids_));
596 } else {
597 RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES.";
598 if (type == SdpType::kAnswer) {
599 // Explicitly reset the |sdes_transport_| if no crypto param is
600 // provided in the answer. No need to call |ResetParams()| for
601 // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
602 sdes_transport_->ResetParams();
603 }
604 }
605 }
606 return ret;
607}
608
Zhi Huang365381f2018-04-13 16:44:34 -0700609webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800610 SdpType local_description_type) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200611 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800612 if (!local_description_ || !remote_description_) {
613 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
614 "Applying an answer transport description "
615 "without applying any offer.");
616 }
617 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200618 absl::optional<rtc::SSLRole> negotiated_dtls_role;
Zhi Huange818b6e2018-02-22 15:26:27 -0800619
620 rtc::SSLFingerprint* local_fp =
621 local_description_->transport_desc.identity_fingerprint.get();
622 rtc::SSLFingerprint* remote_fp =
623 remote_description_->transport_desc.identity_fingerprint.get();
624 if (remote_fp && local_fp) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200625 remote_fingerprint = std::make_unique<rtc::SSLFingerprint>(*remote_fp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800626 webrtc::RTCError error =
627 NegotiateDtlsRole(local_description_type,
628 local_description_->transport_desc.connection_role,
629 remote_description_->transport_desc.connection_role,
630 &negotiated_dtls_role);
631 if (!error.ok()) {
632 return error;
633 }
634 } else if (local_fp && (local_description_type == SdpType::kAnswer)) {
635 return webrtc::RTCError(
636 webrtc::RTCErrorType::INVALID_PARAMETER,
637 "Local fingerprint supplied when caller didn't offer DTLS.");
638 } else {
639 // We are not doing DTLS
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200640 remote_fingerprint = std::make_unique<rtc::SSLFingerprint>(
Steve Anton4905edb2018-10-15 19:27:44 -0700641 "", rtc::ArrayView<const uint8_t>());
Zhi Huange818b6e2018-02-22 15:26:27 -0800642 }
643 // Now that we have negotiated everything, push it downward.
644 // Note that we cache the result so that if we have race conditions
645 // between future SetRemote/SetLocal invocations and new transport
646 // creation, we have the negotiation state saved until a new
647 // negotiation happens.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200648 RTC_DCHECK(rtp_dtls_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800649 webrtc::RTCError error = SetNegotiatedDtlsParameters(
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200650 rtp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800651 if (!error.ok()) {
652 return error;
653 }
654
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200655 if (rtcp_dtls_transport()) {
656 error = SetNegotiatedDtlsParameters(
657 rtcp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800658 }
659 return error;
660}
661
Zhi Huang365381f2018-04-13 16:44:34 -0700662webrtc::RTCError JsepTransport::NegotiateDtlsRole(
Zhi Huange818b6e2018-02-22 15:26:27 -0800663 SdpType local_description_type,
664 ConnectionRole local_connection_role,
665 ConnectionRole remote_connection_role,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200666 absl::optional<rtc::SSLRole>* negotiated_dtls_role) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800667 // From RFC 4145, section-4.1, The following are the values that the
668 // 'setup' attribute can take in an offer/answer exchange:
669 // Offer Answer
670 // ________________
671 // active passive / holdconn
672 // passive active / holdconn
673 // actpass active / passive / holdconn
674 // holdconn holdconn
675 //
676 // Set the role that is most conformant with RFC 5763, Section 5, bullet 1
677 // The endpoint MUST use the setup attribute defined in [RFC4145].
678 // The endpoint that is the offerer MUST use the setup attribute
679 // value of setup:actpass and be prepared to receive a client_hello
680 // before it receives the answer. The answerer MUST use either a
681 // setup attribute value of setup:active or setup:passive. Note that
682 // if the answerer uses setup:passive, then the DTLS handshake will
683 // not begin until the answerer is received, which adds additional
684 // latency. setup:active allows the answer and the DTLS handshake to
685 // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever
686 // party is active MUST initiate a DTLS handshake by sending a
687 // ClientHello over each flow (host/port quartet).
688 // IOW - actpass and passive modes should be treated as server and
689 // active as client.
690 bool is_remote_server = false;
691 if (local_description_type == SdpType::kOffer) {
692 if (local_connection_role != CONNECTIONROLE_ACTPASS) {
693 return webrtc::RTCError(
694 webrtc::RTCErrorType::INVALID_PARAMETER,
695 "Offerer must use actpass value for setup attribute.");
696 }
697
698 if (remote_connection_role == CONNECTIONROLE_ACTIVE ||
699 remote_connection_role == CONNECTIONROLE_PASSIVE ||
700 remote_connection_role == CONNECTIONROLE_NONE) {
701 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE);
702 } else {
703 return webrtc::RTCError(
704 webrtc::RTCErrorType::INVALID_PARAMETER,
705 "Answerer must use either active or passive value "
706 "for setup attribute.");
707 }
708 // If remote is NONE or ACTIVE it will act as client.
709 } else {
710 if (remote_connection_role != CONNECTIONROLE_ACTPASS &&
711 remote_connection_role != CONNECTIONROLE_NONE) {
712 // Accept a remote role attribute that's not "actpass", but matches the
713 // current negotiated role. This is allowed by dtls-sdp, though our
714 // implementation will never generate such an offer as it's not
715 // recommended.
716 //
717 // See https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-dtls-sdp,
718 // section 5.5.
719 auto current_dtls_role = GetDtlsRole();
720 if (!current_dtls_role ||
721 (*current_dtls_role == rtc::SSL_CLIENT &&
722 remote_connection_role == CONNECTIONROLE_ACTIVE) ||
723 (*current_dtls_role == rtc::SSL_SERVER &&
724 remote_connection_role == CONNECTIONROLE_PASSIVE)) {
725 return webrtc::RTCError(
726 webrtc::RTCErrorType::INVALID_PARAMETER,
727 "Offerer must use actpass value or current negotiated role for "
728 "setup attribute.");
729 }
730 }
731
732 if (local_connection_role == CONNECTIONROLE_ACTIVE ||
733 local_connection_role == CONNECTIONROLE_PASSIVE) {
734 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE);
735 } else {
736 return webrtc::RTCError(
737 webrtc::RTCErrorType::INVALID_PARAMETER,
738 "Answerer must use either active or passive value "
739 "for setup attribute.");
740 }
741
742 // If local is passive, local will act as server.
743 }
744
Mirko Bonadei05cf6be2019-01-31 21:38:12 +0100745 *negotiated_dtls_role =
746 (is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER);
Zhi Huange818b6e2018-02-22 15:26:27 -0800747 return webrtc::RTCError::OK();
748}
749
Zhi Huang365381f2018-04-13 16:44:34 -0700750bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
751 TransportStats* stats) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200752 RTC_DCHECK_RUN_ON(network_thread_);
753 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800754 RTC_DCHECK(dtls_transport);
755 TransportChannelStats substats;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100756 if (rtcp_dtls_transport_) {
757 substats.component = dtls_transport == rtcp_dtls_transport_->internal()
758 ? ICE_CANDIDATE_COMPONENT_RTCP
759 : ICE_CANDIDATE_COMPONENT_RTP;
760 } else {
761 substats.component = ICE_CANDIDATE_COMPONENT_RTP;
762 }
Harald Alvestrand5cb78072019-10-28 09:51:17 +0100763 dtls_transport->GetSslVersionBytes(&substats.ssl_version_bytes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800764 dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
765 dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
766 substats.dtls_state = dtls_transport->dtls_state();
767 if (!dtls_transport->ice_transport()->GetStats(
Jonas Oreland149dc722019-08-28 08:10:27 +0200768 &substats.ice_transport_stats)) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800769 return false;
770 }
771 stats->channel_stats.push_back(substats);
772 return true;
773}
774
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700775void JsepTransport::NegotiateDatagramTransport(SdpType type) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700776 RTC_DCHECK(type == SdpType::kAnswer || type == SdpType::kPrAnswer);
777 rtc::CritScope lock(&accessor_lock_);
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700778 if (!datagram_transport_) {
779 return; // No need to negotiate the use of datagram transport.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700780 }
781
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700782 bool compatible_datagram_transport =
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700783 remote_description_->transport_desc.opaque_parameters &&
784 remote_description_->transport_desc.opaque_parameters ==
785 local_description_->transport_desc.opaque_parameters;
786
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700787 bool use_datagram_transport_for_media =
788 compatible_datagram_transport &&
789 remote_description_->media_alt_protocol ==
790 remote_description_->transport_desc.opaque_parameters->protocol &&
791 remote_description_->media_alt_protocol ==
792 local_description_->media_alt_protocol;
793
794 bool use_datagram_transport_for_data =
795 compatible_datagram_transport &&
796 remote_description_->data_alt_protocol ==
797 remote_description_->transport_desc.opaque_parameters->protocol &&
798 remote_description_->data_alt_protocol ==
799 local_description_->data_alt_protocol;
800
801 RTC_LOG(LS_INFO)
802 << "Negotiating datagram transport, use_datagram_transport_for_media="
803 << use_datagram_transport_for_media
804 << ", use_datagram_transport_for_data=" << use_datagram_transport_for_data
805 << " answer type=" << (type == SdpType::kAnswer ? "answer" : "pr_answer");
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700806
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700807 // A provisional or full or answer lets the peer start sending on one of the
808 // transports.
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700809 if (composite_rtp_transport_) {
810 composite_rtp_transport_->SetSendTransport(
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700811 use_datagram_transport_for_media ? datagram_rtp_transport_.get()
812 : default_rtp_transport());
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700813 }
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700814 if (composite_data_channel_transport_) {
815 composite_data_channel_transport_->SetSendTransport(
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700816 use_datagram_transport_for_data ? data_channel_transport_
817 : sctp_data_channel_transport_.get());
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700818 }
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700819
820 if (type != SdpType::kAnswer) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700821 return;
822 }
823
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700824 if (composite_rtp_transport_) {
825 if (use_datagram_transport_for_media) {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700826 // Negotiated use of datagram transport for RTP, so remove the
827 // non-datagram RTP transport.
Bjorn A Mellem703ea952019-08-23 10:31:11 -0700828 composite_rtp_transport_->RemoveTransport(default_rtp_transport());
829 if (unencrypted_rtp_transport_) {
830 unencrypted_rtp_transport_ = nullptr;
831 } else if (sdes_transport_) {
832 sdes_transport_ = nullptr;
833 } else {
834 dtls_srtp_transport_ = nullptr;
835 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700836 } else {
837 composite_rtp_transport_->RemoveTransport(datagram_rtp_transport_.get());
838 datagram_rtp_transport_ = nullptr;
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700839 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700840 }
841
842 if (composite_data_channel_transport_) {
843 if (use_datagram_transport_for_data) {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700844 // Negotiated use of datagram transport for data channels, so remove the
845 // non-datagram data channel transport.
846 composite_data_channel_transport_->RemoveTransport(
847 sctp_data_channel_transport_.get());
848 sctp_data_channel_transport_ = nullptr;
849 sctp_transport_ = nullptr;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700850 } else {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700851 composite_data_channel_transport_->RemoveTransport(
852 data_channel_transport_);
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700853 data_channel_transport_ = nullptr;
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700854 }
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700855 } else if (data_channel_transport_ && !use_datagram_transport_for_data) {
856 // The datagram transport has been rejected without a fallback. We still
857 // need to inform the application and delete it.
858 SignalDataChannelTransportNegotiated(this, nullptr);
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700859 data_channel_transport_ = nullptr;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700860 }
861
862 if (!use_datagram_transport_for_media && !use_datagram_transport_for_data) {
863 // Datagram transport is not being used for anything, so clean it up.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700864 datagram_transport_ = nullptr;
865 }
866}
867
Zhi Huange818b6e2018-02-22 15:26:27 -0800868} // namespace cricket