blob: 9380341a57d28321372e5293df710a2e59f96a32 [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>
Zhi Huange818b6e2018-02-22 15:26:27 -080015#include <memory>
Yves Gerey3e707812018-11-28 16:47:49 +010016#include <type_traits>
Zhi Huange818b6e2018-02-22 15:26:27 -080017#include <utility> // for std::pair
18
Yves Gerey3e707812018-11-28 16:47:49 +010019#include "absl/memory/memory.h"
20#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"
Zhi Huange818b6e2018-02-22 15:26:27 -080024#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/copy_on_write_buffer.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080026#include "rtc_base/logging.h"
Zhi Huang365381f2018-04-13 16:44:34 -070027#include "rtc_base/strings/string_builder.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080028
29using webrtc::SdpType;
30
31namespace cricket {
32
33static bool VerifyIceParams(const JsepTransportDescription& jsep_description) {
34 // For legacy protocols.
35 // TODO(zhihuang): Remove this once the legacy protocol is no longer
36 // supported.
37 if (jsep_description.transport_desc.ice_ufrag.empty() &&
38 jsep_description.transport_desc.ice_pwd.empty()) {
39 return true;
40 }
41
42 if (jsep_description.transport_desc.ice_ufrag.length() <
43 ICE_UFRAG_MIN_LENGTH ||
44 jsep_description.transport_desc.ice_ufrag.length() >
45 ICE_UFRAG_MAX_LENGTH) {
46 return false;
47 }
48 if (jsep_description.transport_desc.ice_pwd.length() < ICE_PWD_MIN_LENGTH ||
49 jsep_description.transport_desc.ice_pwd.length() > ICE_PWD_MAX_LENGTH) {
50 return false;
51 }
52 return true;
53}
54
55JsepTransportDescription::JsepTransportDescription() {}
56
57JsepTransportDescription::JsepTransportDescription(
58 bool rtcp_mux_enabled,
59 const std::vector<CryptoParams>& cryptos,
60 const std::vector<int>& encrypted_header_extension_ids,
Zhi Huange830e682018-03-30 10:48:35 -070061 int rtp_abs_sendtime_extn_id,
Zhi Huange818b6e2018-02-22 15:26:27 -080062 const TransportDescription& transport_desc)
63 : rtcp_mux_enabled(rtcp_mux_enabled),
64 cryptos(cryptos),
65 encrypted_header_extension_ids(encrypted_header_extension_ids),
Zhi Huange830e682018-03-30 10:48:35 -070066 rtp_abs_sendtime_extn_id(rtp_abs_sendtime_extn_id),
Zhi Huange818b6e2018-02-22 15:26:27 -080067 transport_desc(transport_desc) {}
68
69JsepTransportDescription::JsepTransportDescription(
70 const JsepTransportDescription& from)
71 : rtcp_mux_enabled(from.rtcp_mux_enabled),
72 cryptos(from.cryptos),
73 encrypted_header_extension_ids(from.encrypted_header_extension_ids),
Zhi Huange830e682018-03-30 10:48:35 -070074 rtp_abs_sendtime_extn_id(from.rtp_abs_sendtime_extn_id),
Zhi Huange818b6e2018-02-22 15:26:27 -080075 transport_desc(from.transport_desc) {}
76
77JsepTransportDescription::~JsepTransportDescription() = default;
78
79JsepTransportDescription& JsepTransportDescription::operator=(
80 const JsepTransportDescription& from) {
81 if (this == &from) {
82 return *this;
83 }
84 rtcp_mux_enabled = from.rtcp_mux_enabled;
85 cryptos = from.cryptos;
86 encrypted_header_extension_ids = from.encrypted_header_extension_ids;
Zhi Huange830e682018-03-30 10:48:35 -070087 rtp_abs_sendtime_extn_id = from.rtp_abs_sendtime_extn_id;
Zhi Huange818b6e2018-02-22 15:26:27 -080088 transport_desc = from.transport_desc;
89
90 return *this;
91}
92
Zhi Huang365381f2018-04-13 16:44:34 -070093JsepTransport::JsepTransport(
Zhi Huange818b6e2018-02-22 15:26:27 -080094 const std::string& mid,
95 const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate,
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -070096 std::unique_ptr<cricket::IceTransportInternal> ice_transport,
97 std::unique_ptr<cricket::IceTransportInternal> rtcp_ice_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -080098 std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport,
99 std::unique_ptr<webrtc::SrtpTransport> sdes_transport,
100 std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport,
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700101 std::unique_ptr<webrtc::RtpTransport> datagram_rtp_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -0800102 std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
Anton Sukhanov7940da02018-10-10 10:34:49 -0700103 std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700104 std::unique_ptr<DtlsTransportInternal> datagram_dtls_transport,
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700105 std::unique_ptr<webrtc::MediaTransportInterface> media_transport,
106 std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport)
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200107 : network_thread_(rtc::Thread::Current()),
108 mid_(mid),
Zhi Huange818b6e2018-02-22 15:26:27 -0800109 local_certificate_(local_certificate),
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700110 ice_transport_(std::move(ice_transport)),
111 rtcp_ice_transport_(std::move(rtcp_ice_transport)),
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200112 unencrypted_rtp_transport_(std::move(unencrypted_rtp_transport)),
113 sdes_transport_(std::move(sdes_transport)),
114 dtls_srtp_transport_(std::move(dtls_srtp_transport)),
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700115 datagram_rtp_transport_(std::move(datagram_rtp_transport)),
Harald Alvestrandad88c882018-11-28 16:47:46 +0100116 rtp_dtls_transport_(
117 rtp_dtls_transport ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
118 std::move(rtp_dtls_transport))
119 : nullptr),
120 rtcp_dtls_transport_(
121 rtcp_dtls_transport
122 ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
123 std::move(rtcp_dtls_transport))
124 : nullptr),
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700125 datagram_dtls_transport_(
126 datagram_dtls_transport
127 ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
128 std::move(datagram_dtls_transport))
129 : nullptr),
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700130 media_transport_(std::move(media_transport)),
131 datagram_transport_(std::move(datagram_transport)) {
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700132 RTC_DCHECK(ice_transport_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800133 RTC_DCHECK(rtp_dtls_transport_);
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700134 // |rtcp_ice_transport_| must be present iff |rtcp_dtls_transport_| is
135 // present.
136 RTC_DCHECK_EQ((rtcp_ice_transport_ != nullptr),
137 (rtcp_dtls_transport_ != nullptr));
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700138 RTC_DCHECK(!datagram_transport_ || !media_transport_);
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200139 // Verify the "only one out of these three can be set" invariant.
140 if (unencrypted_rtp_transport_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800141 RTC_DCHECK(!sdes_transport);
142 RTC_DCHECK(!dtls_srtp_transport);
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200143 } else if (sdes_transport_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800144 RTC_DCHECK(!unencrypted_rtp_transport);
145 RTC_DCHECK(!dtls_srtp_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800146 } else {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200147 RTC_DCHECK(dtls_srtp_transport_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800148 RTC_DCHECK(!unencrypted_rtp_transport);
149 RTC_DCHECK(!sdes_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800150 }
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700151
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700152 if (datagram_rtp_transport_ && default_rtp_transport()) {
153 composite_rtp_transport_ = absl::make_unique<webrtc::CompositeRtpTransport>(
154 std::vector<webrtc::RtpTransportInternal*>{
155 datagram_rtp_transport_.get(), default_rtp_transport()});
156 }
157
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700158 if (media_transport_) {
159 media_transport_->SetMediaTransportStateCallback(this);
160 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800161}
162
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700163JsepTransport::~JsepTransport() {
Anton Sukhanov316f3ac2019-05-23 15:50:38 -0700164 // Disconnect media transport state callbacks and make sure we delete media
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700165 // transport before ICE.
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700166 if (media_transport_) {
167 media_transport_->SetMediaTransportStateCallback(nullptr);
Anton Sukhanovd644feb2018-12-06 09:00:39 -0800168 media_transport_.reset();
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700169 }
Anton Sukhanov316f3ac2019-05-23 15:50:38 -0700170
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100171 // Clear all DtlsTransports. There may be pointers to these from
172 // other places, so we can't assume they'll be deleted by the destructor.
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100173 rtp_dtls_transport_->Clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100174 if (rtcp_dtls_transport_) {
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100175 rtcp_dtls_transport_->Clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100176 }
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700177
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700178 // Datagram dtls transport must be disconnected before the datagram transport
179 // is released.
180 if (datagram_dtls_transport_) {
181 datagram_dtls_transport_->Clear();
182 }
183
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700184 // Delete datagram transport before ICE, but after DTLS transport.
185 datagram_transport_.reset();
186
187 // ICE will be the last transport to be deleted.
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700188}
Zhi Huange818b6e2018-02-22 15:26:27 -0800189
Zhi Huang365381f2018-04-13 16:44:34 -0700190webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
Zhi Huange818b6e2018-02-22 15:26:27 -0800191 const JsepTransportDescription& jsep_description,
192 SdpType type) {
193 webrtc::RTCError error;
194
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200195 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800196 if (!VerifyIceParams(jsep_description)) {
197 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
198 "Invalid ice-ufrag or ice-pwd length.");
199 }
200
201 if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
202 ContentSource::CS_LOCAL)) {
203 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
204 "Failed to setup RTCP mux.");
205 }
206
207 // If doing SDES, setup the SDES crypto parameters.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700208 {
209 rtc::CritScope scope(&accessor_lock_);
210 if (sdes_transport_) {
211 RTC_DCHECK(!unencrypted_rtp_transport_);
212 RTC_DCHECK(!dtls_srtp_transport_);
213 if (!SetSdes(jsep_description.cryptos,
214 jsep_description.encrypted_header_extension_ids, type,
215 ContentSource::CS_LOCAL)) {
216 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
217 "Failed to setup SDES crypto parameters.");
218 }
219 } else if (dtls_srtp_transport_) {
220 RTC_DCHECK(!unencrypted_rtp_transport_);
221 RTC_DCHECK(!sdes_transport_);
222 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
223 jsep_description.encrypted_header_extension_ids);
Zhi Huange818b6e2018-02-22 15:26:27 -0800224 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800225 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800226 bool ice_restarting =
227 local_description_ != nullptr &&
228 IceCredentialsChanged(local_description_->transport_desc.ice_ufrag,
229 local_description_->transport_desc.ice_pwd,
230 jsep_description.transport_desc.ice_ufrag,
231 jsep_description.transport_desc.ice_pwd);
232 local_description_.reset(new JsepTransportDescription(jsep_description));
233
234 rtc::SSLFingerprint* local_fp =
235 local_description_->transport_desc.identity_fingerprint.get();
236
237 if (!local_fp) {
238 local_certificate_ = nullptr;
239 } else {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200240 error = VerifyCertificateFingerprint(local_certificate_, local_fp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800241 if (!error.ok()) {
242 local_description_.reset();
243 return error;
244 }
245 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200246 {
247 rtc::CritScope scope(&accessor_lock_);
248 RTC_DCHECK(rtp_dtls_transport_->internal());
249 SetLocalIceParameters(rtp_dtls_transport_->internal()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800250
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200251 if (rtcp_dtls_transport_) {
252 RTC_DCHECK(rtcp_dtls_transport_->internal());
253 SetLocalIceParameters(rtcp_dtls_transport_->internal()->ice_transport());
254 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800255 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800256 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
257 if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
258 error = NegotiateAndSetDtlsParameters(type);
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700259 NegotiateRtpTransport(type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800260 }
261 if (!error.ok()) {
262 local_description_.reset();
263 return error;
264 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200265 {
266 rtc::CritScope scope(&accessor_lock_);
267 if (needs_ice_restart_ && ice_restarting) {
268 needs_ice_restart_ = false;
269 RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag cleared for transport "
270 << mid();
271 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800272 }
273
274 return webrtc::RTCError::OK();
275}
276
Zhi Huang365381f2018-04-13 16:44:34 -0700277webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription(
Zhi Huange818b6e2018-02-22 15:26:27 -0800278 const JsepTransportDescription& jsep_description,
279 webrtc::SdpType type) {
280 webrtc::RTCError error;
281
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200282 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800283 if (!VerifyIceParams(jsep_description)) {
284 remote_description_.reset();
285 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
286 "Invalid ice-ufrag or ice-pwd length.");
287 }
288
289 if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
290 ContentSource::CS_REMOTE)) {
291 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
292 "Failed to setup RTCP mux.");
293 }
294
295 // If doing SDES, setup the SDES crypto parameters.
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700296 {
297 rtc::CritScope lock(&accessor_lock_);
298 if (sdes_transport_) {
299 RTC_DCHECK(!unencrypted_rtp_transport_);
300 RTC_DCHECK(!dtls_srtp_transport_);
301 if (!SetSdes(jsep_description.cryptos,
302 jsep_description.encrypted_header_extension_ids, type,
303 ContentSource::CS_REMOTE)) {
304 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
305 "Failed to setup SDES crypto parameters.");
306 }
307 sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
308 jsep_description.rtp_abs_sendtime_extn_id);
309 } else if (dtls_srtp_transport_) {
310 RTC_DCHECK(!unencrypted_rtp_transport_);
311 RTC_DCHECK(!sdes_transport_);
312 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
313 jsep_description.encrypted_header_extension_ids);
314 dtls_srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
315 jsep_description.rtp_abs_sendtime_extn_id);
Zhi Huange818b6e2018-02-22 15:26:27 -0800316 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800317 }
318
319 remote_description_.reset(new JsepTransportDescription(jsep_description));
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200320 RTC_DCHECK(rtp_dtls_transport());
321 SetRemoteIceParameters(rtp_dtls_transport()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800322
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200323 if (rtcp_dtls_transport()) {
324 SetRemoteIceParameters(rtcp_dtls_transport()->ice_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800325 }
326
327 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
328 if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
329 error = NegotiateAndSetDtlsParameters(SdpType::kOffer);
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700330 NegotiateRtpTransport(type);
Zhi Huange818b6e2018-02-22 15:26:27 -0800331 }
332 if (!error.ok()) {
333 remote_description_.reset();
334 return error;
335 }
336 return webrtc::RTCError::OK();
337}
338
Zhi Huang365381f2018-04-13 16:44:34 -0700339webrtc::RTCError JsepTransport::AddRemoteCandidates(
Zhi Huange818b6e2018-02-22 15:26:27 -0800340 const Candidates& candidates) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200341 RTC_DCHECK_RUN_ON(network_thread_);
Henrik Boström5d8f8fa2018-04-13 15:22:50 +0000342 if (!local_description_ || !remote_description_) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800343 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
344 mid() +
345 " is not ready to use the remote candidate "
Henrik Boström5d8f8fa2018-04-13 15:22:50 +0000346 "because the local or remote description is "
347 "not set.");
Zhi Huange818b6e2018-02-22 15:26:27 -0800348 }
349
350 for (const cricket::Candidate& candidate : candidates) {
351 auto transport =
352 candidate.component() == cricket::ICE_CANDIDATE_COMPONENT_RTP
Harald Alvestrandad88c882018-11-28 16:47:46 +0100353 ? rtp_dtls_transport_
354 : rtcp_dtls_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800355 if (!transport) {
356 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
357 "Candidate has an unknown component: " +
358 candidate.ToString() + " for mid " + mid());
359 }
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100360 RTC_DCHECK(transport->internal() && transport->internal()->ice_transport());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100361 transport->internal()->ice_transport()->AddRemoteCandidate(candidate);
Zhi Huange818b6e2018-02-22 15:26:27 -0800362 }
363 return webrtc::RTCError::OK();
364}
365
Zhi Huang365381f2018-04-13 16:44:34 -0700366void JsepTransport::SetNeedsIceRestartFlag() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200367 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800368 if (!needs_ice_restart_) {
369 needs_ice_restart_ = true;
370 RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid();
371 }
372}
373
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200374absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200375 RTC_DCHECK_RUN_ON(network_thread_);
376 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800377 RTC_DCHECK(rtp_dtls_transport_);
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100378 RTC_DCHECK(rtp_dtls_transport_->internal());
Zhi Huange818b6e2018-02-22 15:26:27 -0800379 rtc::SSLRole dtls_role;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100380 if (!rtp_dtls_transport_->internal()->GetDtlsRole(&dtls_role)) {
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200381 return absl::optional<rtc::SSLRole>();
Zhi Huange818b6e2018-02-22 15:26:27 -0800382 }
383
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200384 return absl::optional<rtc::SSLRole>(dtls_role);
Zhi Huange818b6e2018-02-22 15:26:27 -0800385}
386
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700387absl::optional<OpaqueTransportParameters>
388JsepTransport::GetTransportParameters() const {
389 rtc::CritScope scope(&accessor_lock_);
390 if (!datagram_transport()) {
391 return absl::nullopt;
392 }
393
394 OpaqueTransportParameters params;
395 params.parameters = datagram_transport()->GetTransportParameters();
396 return params;
397}
398
Zhi Huang365381f2018-04-13 16:44:34 -0700399bool JsepTransport::GetStats(TransportStats* stats) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200400 RTC_DCHECK_RUN_ON(network_thread_);
401 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800402 stats->transport_name = mid();
403 stats->channel_stats.clear();
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100404 RTC_DCHECK(rtp_dtls_transport_->internal());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100405 bool ret = GetTransportStats(rtp_dtls_transport_->internal(), stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800406 if (rtcp_dtls_transport_) {
Harald Alvestrand628f37a2018-12-06 10:55:20 +0100407 RTC_DCHECK(rtcp_dtls_transport_->internal());
Harald Alvestrandad88c882018-11-28 16:47:46 +0100408 ret &= GetTransportStats(rtcp_dtls_transport_->internal(), stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800409 }
410 return ret;
411}
412
Zhi Huang365381f2018-04-13 16:44:34 -0700413webrtc::RTCError JsepTransport::VerifyCertificateFingerprint(
Zhi Huange818b6e2018-02-22 15:26:27 -0800414 const rtc::RTCCertificate* certificate,
415 const rtc::SSLFingerprint* fingerprint) const {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200416 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800417 if (!fingerprint) {
418 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
419 "No fingerprint");
420 }
421 if (!certificate) {
422 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
423 "Fingerprint provided but no identity available.");
424 }
Steve Anton4905edb2018-10-15 19:27:44 -0700425 std::unique_ptr<rtc::SSLFingerprint> fp_tmp =
426 rtc::SSLFingerprint::CreateUnique(fingerprint->algorithm,
427 *certificate->identity());
Zhi Huange818b6e2018-02-22 15:26:27 -0800428 RTC_DCHECK(fp_tmp.get() != NULL);
429 if (*fp_tmp == *fingerprint) {
430 return webrtc::RTCError::OK();
431 }
Zhi Huang365381f2018-04-13 16:44:34 -0700432 char ss_buf[1024];
433 rtc::SimpleStringBuilder desc(ss_buf);
Zhi Huange818b6e2018-02-22 15:26:27 -0800434 desc << "Local fingerprint does not match identity. Expected: ";
435 desc << fp_tmp->ToString();
436 desc << " Got: " << fingerprint->ToString();
Zhi Huang365381f2018-04-13 16:44:34 -0700437 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
438 std::string(desc.str()));
Zhi Huange818b6e2018-02-22 15:26:27 -0800439}
440
Zhi Huangb57e1692018-06-12 11:41:11 -0700441void JsepTransport::SetActiveResetSrtpParams(bool active_reset_srtp_params) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200442 RTC_DCHECK_RUN_ON(network_thread_);
443 rtc::CritScope scope(&accessor_lock_);
Zhi Huangb57e1692018-06-12 11:41:11 -0700444 if (dtls_srtp_transport_) {
445 RTC_LOG(INFO)
446 << "Setting active_reset_srtp_params of DtlsSrtpTransport to: "
447 << active_reset_srtp_params;
448 dtls_srtp_transport_->SetActiveResetSrtpParams(active_reset_srtp_params);
449 }
450}
451
Zhi Huang365381f2018-04-13 16:44:34 -0700452void JsepTransport::SetLocalIceParameters(IceTransportInternal* ice_transport) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200453 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800454 RTC_DCHECK(ice_transport);
455 RTC_DCHECK(local_description_);
456 ice_transport->SetIceParameters(
457 local_description_->transport_desc.GetIceParameters());
458}
459
Zhi Huang365381f2018-04-13 16:44:34 -0700460void JsepTransport::SetRemoteIceParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800461 IceTransportInternal* ice_transport) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200462 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800463 RTC_DCHECK(ice_transport);
464 RTC_DCHECK(remote_description_);
465 ice_transport->SetRemoteIceParameters(
466 remote_description_->transport_desc.GetIceParameters());
467 ice_transport->SetRemoteIceMode(remote_description_->transport_desc.ice_mode);
468}
469
Zhi Huang365381f2018-04-13 16:44:34 -0700470webrtc::RTCError JsepTransport::SetNegotiatedDtlsParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800471 DtlsTransportInternal* dtls_transport,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200472 absl::optional<rtc::SSLRole> dtls_role,
Zhi Huange818b6e2018-02-22 15:26:27 -0800473 rtc::SSLFingerprint* remote_fingerprint) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200474 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800475 RTC_DCHECK(dtls_transport);
476 // Set SSL role. Role must be set before fingerprint is applied, which
477 // initiates DTLS setup.
478 if (dtls_role && !dtls_transport->SetDtlsRole(*dtls_role)) {
479 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
480 "Failed to set SSL role for the transport.");
481 }
482 // Apply remote fingerprint.
483 if (!remote_fingerprint ||
484 !dtls_transport->SetRemoteFingerprint(
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700485 remote_fingerprint->algorithm, remote_fingerprint->digest.cdata(),
Zhi Huange818b6e2018-02-22 15:26:27 -0800486 remote_fingerprint->digest.size())) {
487 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
488 "Failed to apply remote fingerprint.");
489 }
490 return webrtc::RTCError::OK();
491}
492
Zhi Huang365381f2018-04-13 16:44:34 -0700493bool JsepTransport::SetRtcpMux(bool enable,
494 webrtc::SdpType type,
495 ContentSource source) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200496 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800497 bool ret = false;
498 switch (type) {
499 case SdpType::kOffer:
500 ret = rtcp_mux_negotiator_.SetOffer(enable, source);
501 break;
502 case SdpType::kPrAnswer:
503 // This may activate RTCP muxing, but we don't yet destroy the transport
504 // because the final answer may deactivate it.
505 ret = rtcp_mux_negotiator_.SetProvisionalAnswer(enable, source);
506 break;
507 case SdpType::kAnswer:
508 ret = rtcp_mux_negotiator_.SetAnswer(enable, source);
509 if (ret && rtcp_mux_negotiator_.IsActive()) {
510 ActivateRtcpMux();
511 }
512 break;
513 default:
514 RTC_NOTREACHED();
515 }
516
517 if (!ret) {
518 return false;
519 }
520
521 auto transport = rtp_transport();
522 transport->SetRtcpMuxEnabled(rtcp_mux_negotiator_.IsActive());
523 return ret;
524}
525
Zhi Huang365381f2018-04-13 16:44:34 -0700526void JsepTransport::ActivateRtcpMux() {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200527 {
528 // Don't hold the network_thread_ lock while calling other functions,
529 // since they might call other functions that call RTC_DCHECK_RUN_ON.
530 // TODO(https://crbug.com/webrtc/10318): Simplify when possible.
531 RTC_DCHECK_RUN_ON(network_thread_);
532 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200533 {
534 rtc::CritScope scope(&accessor_lock_);
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700535 if (datagram_rtp_transport_) {
536 datagram_rtp_transport_->SetRtcpPacketTransport(nullptr);
537 }
538 if (unencrypted_rtp_transport_) {
539 RTC_DCHECK(!sdes_transport_);
540 RTC_DCHECK(!dtls_srtp_transport_);
541 unencrypted_rtp_transport_->SetRtcpPacketTransport(nullptr);
542 } else if (sdes_transport_) {
543 RTC_DCHECK(!unencrypted_rtp_transport_);
544 RTC_DCHECK(!dtls_srtp_transport_);
545 sdes_transport_->SetRtcpPacketTransport(nullptr);
546 } else if (dtls_srtp_transport_) {
547 RTC_DCHECK(dtls_srtp_transport_);
548 RTC_DCHECK(!unencrypted_rtp_transport_);
549 RTC_DCHECK(!sdes_transport_);
550 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport(),
551 /*rtcp_dtls_transport=*/nullptr);
552 }
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200553 rtcp_dtls_transport_ = nullptr; // Destroy this reference.
554 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800555 // Notify the JsepTransportController to update the aggregate states.
556 SignalRtcpMuxActive();
557}
558
Zhi Huang365381f2018-04-13 16:44:34 -0700559bool JsepTransport::SetSdes(const std::vector<CryptoParams>& cryptos,
560 const std::vector<int>& encrypted_extension_ids,
561 webrtc::SdpType type,
562 ContentSource source) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200563 RTC_DCHECK_RUN_ON(network_thread_);
564 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800565 bool ret = false;
566 ret = sdes_negotiator_.Process(cryptos, type, source);
567 if (!ret) {
568 return ret;
569 }
570
571 if (source == ContentSource::CS_LOCAL) {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700572 recv_extension_ids_ = encrypted_extension_ids;
Zhi Huange818b6e2018-02-22 15:26:27 -0800573 } else {
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700574 send_extension_ids_ = encrypted_extension_ids;
Zhi Huange818b6e2018-02-22 15:26:27 -0800575 }
576
577 // If setting an SDES answer succeeded, apply the negotiated parameters
578 // to the SRTP transport.
579 if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) {
580 if (sdes_negotiator_.send_cipher_suite() &&
581 sdes_negotiator_.recv_cipher_suite()) {
582 RTC_DCHECK(send_extension_ids_);
583 RTC_DCHECK(recv_extension_ids_);
584 ret = sdes_transport_->SetRtpParams(
585 *(sdes_negotiator_.send_cipher_suite()),
586 sdes_negotiator_.send_key().data(),
587 static_cast<int>(sdes_negotiator_.send_key().size()),
588 *(send_extension_ids_), *(sdes_negotiator_.recv_cipher_suite()),
589 sdes_negotiator_.recv_key().data(),
590 static_cast<int>(sdes_negotiator_.recv_key().size()),
591 *(recv_extension_ids_));
592 } else {
593 RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES.";
594 if (type == SdpType::kAnswer) {
595 // Explicitly reset the |sdes_transport_| if no crypto param is
596 // provided in the answer. No need to call |ResetParams()| for
597 // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
598 sdes_transport_->ResetParams();
599 }
600 }
601 }
602 return ret;
603}
604
Zhi Huang365381f2018-04-13 16:44:34 -0700605webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters(
Zhi Huange818b6e2018-02-22 15:26:27 -0800606 SdpType local_description_type) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200607 RTC_DCHECK_RUN_ON(network_thread_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800608 if (!local_description_ || !remote_description_) {
609 return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
610 "Applying an answer transport description "
611 "without applying any offer.");
612 }
613 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200614 absl::optional<rtc::SSLRole> negotiated_dtls_role;
Zhi Huange818b6e2018-02-22 15:26:27 -0800615
616 rtc::SSLFingerprint* local_fp =
617 local_description_->transport_desc.identity_fingerprint.get();
618 rtc::SSLFingerprint* remote_fp =
619 remote_description_->transport_desc.identity_fingerprint.get();
620 if (remote_fp && local_fp) {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200621 remote_fingerprint = absl::make_unique<rtc::SSLFingerprint>(*remote_fp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800622 webrtc::RTCError error =
623 NegotiateDtlsRole(local_description_type,
624 local_description_->transport_desc.connection_role,
625 remote_description_->transport_desc.connection_role,
626 &negotiated_dtls_role);
627 if (!error.ok()) {
628 return error;
629 }
630 } else if (local_fp && (local_description_type == SdpType::kAnswer)) {
631 return webrtc::RTCError(
632 webrtc::RTCErrorType::INVALID_PARAMETER,
633 "Local fingerprint supplied when caller didn't offer DTLS.");
634 } else {
635 // We are not doing DTLS
Steve Anton4905edb2018-10-15 19:27:44 -0700636 remote_fingerprint = absl::make_unique<rtc::SSLFingerprint>(
637 "", rtc::ArrayView<const uint8_t>());
Zhi Huange818b6e2018-02-22 15:26:27 -0800638 }
639 // Now that we have negotiated everything, push it downward.
640 // Note that we cache the result so that if we have race conditions
641 // between future SetRemote/SetLocal invocations and new transport
642 // creation, we have the negotiation state saved until a new
643 // negotiation happens.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200644 RTC_DCHECK(rtp_dtls_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800645 webrtc::RTCError error = SetNegotiatedDtlsParameters(
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200646 rtp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800647 if (!error.ok()) {
648 return error;
649 }
650
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200651 if (rtcp_dtls_transport()) {
652 error = SetNegotiatedDtlsParameters(
653 rtcp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800654 }
655 return error;
656}
657
Zhi Huang365381f2018-04-13 16:44:34 -0700658webrtc::RTCError JsepTransport::NegotiateDtlsRole(
Zhi Huange818b6e2018-02-22 15:26:27 -0800659 SdpType local_description_type,
660 ConnectionRole local_connection_role,
661 ConnectionRole remote_connection_role,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200662 absl::optional<rtc::SSLRole>* negotiated_dtls_role) {
Zhi Huange818b6e2018-02-22 15:26:27 -0800663 // From RFC 4145, section-4.1, The following are the values that the
664 // 'setup' attribute can take in an offer/answer exchange:
665 // Offer Answer
666 // ________________
667 // active passive / holdconn
668 // passive active / holdconn
669 // actpass active / passive / holdconn
670 // holdconn holdconn
671 //
672 // Set the role that is most conformant with RFC 5763, Section 5, bullet 1
673 // The endpoint MUST use the setup attribute defined in [RFC4145].
674 // The endpoint that is the offerer MUST use the setup attribute
675 // value of setup:actpass and be prepared to receive a client_hello
676 // before it receives the answer. The answerer MUST use either a
677 // setup attribute value of setup:active or setup:passive. Note that
678 // if the answerer uses setup:passive, then the DTLS handshake will
679 // not begin until the answerer is received, which adds additional
680 // latency. setup:active allows the answer and the DTLS handshake to
681 // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever
682 // party is active MUST initiate a DTLS handshake by sending a
683 // ClientHello over each flow (host/port quartet).
684 // IOW - actpass and passive modes should be treated as server and
685 // active as client.
686 bool is_remote_server = false;
687 if (local_description_type == SdpType::kOffer) {
688 if (local_connection_role != CONNECTIONROLE_ACTPASS) {
689 return webrtc::RTCError(
690 webrtc::RTCErrorType::INVALID_PARAMETER,
691 "Offerer must use actpass value for setup attribute.");
692 }
693
694 if (remote_connection_role == CONNECTIONROLE_ACTIVE ||
695 remote_connection_role == CONNECTIONROLE_PASSIVE ||
696 remote_connection_role == CONNECTIONROLE_NONE) {
697 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE);
698 } else {
699 return webrtc::RTCError(
700 webrtc::RTCErrorType::INVALID_PARAMETER,
701 "Answerer must use either active or passive value "
702 "for setup attribute.");
703 }
704 // If remote is NONE or ACTIVE it will act as client.
705 } else {
706 if (remote_connection_role != CONNECTIONROLE_ACTPASS &&
707 remote_connection_role != CONNECTIONROLE_NONE) {
708 // Accept a remote role attribute that's not "actpass", but matches the
709 // current negotiated role. This is allowed by dtls-sdp, though our
710 // implementation will never generate such an offer as it's not
711 // recommended.
712 //
713 // See https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-dtls-sdp,
714 // section 5.5.
715 auto current_dtls_role = GetDtlsRole();
716 if (!current_dtls_role ||
717 (*current_dtls_role == rtc::SSL_CLIENT &&
718 remote_connection_role == CONNECTIONROLE_ACTIVE) ||
719 (*current_dtls_role == rtc::SSL_SERVER &&
720 remote_connection_role == CONNECTIONROLE_PASSIVE)) {
721 return webrtc::RTCError(
722 webrtc::RTCErrorType::INVALID_PARAMETER,
723 "Offerer must use actpass value or current negotiated role for "
724 "setup attribute.");
725 }
726 }
727
728 if (local_connection_role == CONNECTIONROLE_ACTIVE ||
729 local_connection_role == CONNECTIONROLE_PASSIVE) {
730 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE);
731 } else {
732 return webrtc::RTCError(
733 webrtc::RTCErrorType::INVALID_PARAMETER,
734 "Answerer must use either active or passive value "
735 "for setup attribute.");
736 }
737
738 // If local is passive, local will act as server.
739 }
740
Mirko Bonadei05cf6be2019-01-31 21:38:12 +0100741 *negotiated_dtls_role =
742 (is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER);
Zhi Huange818b6e2018-02-22 15:26:27 -0800743 return webrtc::RTCError::OK();
744}
745
Zhi Huang365381f2018-04-13 16:44:34 -0700746bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
747 TransportStats* stats) {
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200748 RTC_DCHECK_RUN_ON(network_thread_);
749 rtc::CritScope scope(&accessor_lock_);
Zhi Huange818b6e2018-02-22 15:26:27 -0800750 RTC_DCHECK(dtls_transport);
751 TransportChannelStats substats;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100752 if (rtcp_dtls_transport_) {
753 substats.component = dtls_transport == rtcp_dtls_transport_->internal()
754 ? ICE_CANDIDATE_COMPONENT_RTCP
755 : ICE_CANDIDATE_COMPONENT_RTP;
756 } else {
757 substats.component = ICE_CANDIDATE_COMPONENT_RTP;
758 }
Zhi Huange818b6e2018-02-22 15:26:27 -0800759 dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
760 dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
761 substats.dtls_state = dtls_transport->dtls_state();
762 if (!dtls_transport->ice_transport()->GetStats(
763 &substats.connection_infos, &substats.candidate_stats_list)) {
764 return false;
765 }
766 stats->channel_stats.push_back(substats);
767 return true;
768}
769
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700770void JsepTransport::OnStateChanged(webrtc::MediaTransportState state) {
771 // TODO(bugs.webrtc.org/9719) This method currently fires on the network
772 // thread, but media transport does not make such guarantees. We need to make
773 // sure this callback is guaranteed to be executed on the network thread.
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200774 RTC_DCHECK_RUN_ON(network_thread_);
775 {
776 rtc::CritScope scope(&accessor_lock_);
777 media_transport_state_ = state;
778 }
Piotr (Peter) Slatala4eb41122018-11-01 07:26:03 -0700779 SignalMediaTransportStateChanged();
780}
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700781
782void JsepTransport::NegotiateRtpTransport(SdpType type) {
783 RTC_DCHECK(type == SdpType::kAnswer || type == SdpType::kPrAnswer);
784 rtc::CritScope lock(&accessor_lock_);
785 if (!composite_rtp_transport_) {
786 return; // No need to negotiate which RTP transport to use.
787 }
788
789 bool use_datagram_transport =
790 remote_description_->transport_desc.opaque_parameters &&
791 remote_description_->transport_desc.opaque_parameters ==
792 local_description_->transport_desc.opaque_parameters;
793
794 if (use_datagram_transport) {
795 RTC_LOG(INFO) << "Datagram transport provisionally activated";
796 composite_rtp_transport_->SetSendTransport(datagram_rtp_transport_.get());
797 } else {
798 RTC_LOG(INFO) << "Datagram transport provisionally rejected";
799 composite_rtp_transport_->SetSendTransport(default_rtp_transport());
800 }
801
802 if (type != SdpType::kAnswer) {
803 // A provisional answer lets the peer start sending on the chosen
804 // transport, but does not allow it to destroy other transports yet.
805 return;
806 }
807
808 // A full answer lets the peer send on the chosen transport and delete the
809 // rest.
810 if (use_datagram_transport) {
811 RTC_LOG(INFO) << "Datagram transport activated";
812 composite_rtp_transport_->RemoveTransport(default_rtp_transport());
813 if (unencrypted_rtp_transport_) {
814 unencrypted_rtp_transport_ = nullptr;
815 } else if (sdes_transport_) {
816 sdes_transport_ = nullptr;
817 } else {
818 dtls_srtp_transport_ = nullptr;
819 }
820 } else {
821 RTC_LOG(INFO) << "Datagram transport rejected";
822 composite_rtp_transport_->RemoveTransport(datagram_rtp_transport_.get());
823 datagram_rtp_transport_ = nullptr;
824 // This one is ref-counted, so it can't be deleted directly.
825 datagram_dtls_transport_->Clear();
826 datagram_dtls_transport_ = nullptr;
827 datagram_transport_ = nullptr;
828 }
829}
830
Zhi Huange818b6e2018-02-22 15:26:27 -0800831} // namespace cricket