blob: f14f51fb168802bac60a4862a8238cfb304b46d4 [file] [log] [blame]
Harald Alvestrandad88c882018-11-28 15:47:461/*
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 17:11:0011#include "pc/dtls_transport.h"
Harald Alvestrandad88c882018-11-28 15:47:4612
Florent Castelli8037fc62024-08-29 13:00:4013#include <optional>
Harald Alvestrandad88c882018-11-28 15:47:4614#include <utility>
15
Mirko Bonadei9f6808b2021-05-21 18:46:0916#include "api/dtls_transport_interface.h"
Niels Möller105711e2022-06-14 13:48:2617#include "api/make_ref_counted.h"
Artem Titovd15a5752021-02-10 13:31:2418#include "api/sequence_checker.h"
Harald Alvestrand98462622019-01-30 13:57:0319#include "pc/ice_transport.h"
Harald Alvestrand5761e7b2021-01-29 14:45:0820#include "rtc_base/checks.h"
21#include "rtc_base/logging.h"
Harald Alvestrandc24a2182022-02-23 13:44:5922#include "rtc_base/ssl_stream_adapter.h"
Harald Alvestrand98462622019-01-30 13:57:0323
Harald Alvestrandad88c882018-11-28 15:47:4624namespace webrtc {
25
Harald Alvestrandd02541e2019-01-03 11:43:2826// Implementation of DtlsTransportInterface
Harald Alvestrandad88c882018-11-28 15:47:4627DtlsTransport::DtlsTransport(
28 std::unique_ptr<cricket::DtlsTransportInternal> internal)
Harald Alvestrand69fb6c82019-02-13 18:40:1129 : owner_thread_(rtc::Thread::Current()),
30 info_(DtlsTransportState::kNew),
Harald Alvestrand26451932019-02-21 10:27:1531 internal_dtls_transport_(std::move(internal)),
Tommi87f70902021-04-27 12:43:0832 ice_transport_(rtc::make_ref_counted<IceTransportWithPointer>(
Harald Alvestrand26451932019-02-21 10:27:1533 internal_dtls_transport_->ice_transport())) {
Harald Alvestrandad88c882018-11-28 15:47:4634 RTC_DCHECK(internal_dtls_transport_.get());
Mirko Bonadei9f6808b2021-05-21 18:46:0935 internal_dtls_transport_->SubscribeDtlsTransportState(
Lahiru Ginnaliya Gamathige60c0b442021-02-16 15:29:0836 [this](cricket::DtlsTransportInternal* transport,
Mirko Bonadei9f6808b2021-05-21 18:46:0937 DtlsTransportState state) {
Lahiru Ginnaliya Gamathige60c0b442021-02-16 15:29:0838 OnInternalDtlsState(transport, state);
39 });
Harald Alvestrand69fb6c82019-02-13 18:40:1140 UpdateInformation();
Harald Alvestrandd02541e2019-01-03 11:43:2841}
42
43DtlsTransport::~DtlsTransport() {
Tommi3ba809d2023-12-14 18:49:4944 // TODO(tommi): Due to a reference being held by the RtpSenderBase
45 // implementation, the last reference to the `DtlsTransport` instance can
46 // be released on the signaling thread.
47 // RTC_DCHECK_RUN_ON(owner_thread_);
48
Harald Alvestrandd02541e2019-01-03 11:43:2849 // We depend on the signaling thread to call Clear() before dropping
50 // its last reference to this object.
Tommi3ba809d2023-12-14 18:49:4951
52 // If there are non `owner_thread_` references outstanding, and those
53 // references are the last ones released, we depend on Clear() having been
54 // called from the owner_thread before the last reference is deleted.
55 // `Clear()` is currently called from `JsepTransport::~JsepTransport`.
Harald Alvestrand69fb6c82019-02-13 18:40:1156 RTC_DCHECK(owner_thread_->IsCurrent() || !internal_dtls_transport_);
Harald Alvestrandd02541e2019-01-03 11:43:2857}
58
59DtlsTransportInformation DtlsTransport::Information() {
Markus Handell6fcd0f82020-07-07 17:08:5360 MutexLock lock(&lock_);
Harald Alvestrand69fb6c82019-02-13 18:40:1161 return info_;
Harald Alvestrandd02541e2019-01-03 11:43:2862}
63
64void DtlsTransport::RegisterObserver(DtlsTransportObserverInterface* observer) {
Harald Alvestrand69fb6c82019-02-13 18:40:1165 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 11:43:2866 RTC_DCHECK(observer);
67 observer_ = observer;
68}
69
70void DtlsTransport::UnregisterObserver() {
Harald Alvestrand69fb6c82019-02-13 18:40:1171 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 11:43:2872 observer_ = nullptr;
73}
74
Harald Alvestrand98462622019-01-30 13:57:0375rtc::scoped_refptr<IceTransportInterface> DtlsTransport::ice_transport() {
76 return ice_transport_;
77}
78
Harald Alvestrandd02541e2019-01-03 11:43:2879// Internal functions
80void DtlsTransport::Clear() {
Harald Alvestrand69fb6c82019-02-13 18:40:1181 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandcdc30452019-01-08 17:08:0482 RTC_DCHECK(internal());
Harald Alvestrand69fb6c82019-02-13 18:40:1183 bool must_send_event =
Mirko Bonadei9f6808b2021-05-21 18:46:0984 (internal()->dtls_state() != DtlsTransportState::kClosed);
Tommi3ba809d2023-12-14 18:49:4985 internal_dtls_transport_.reset();
86 ice_transport_->Clear();
Harald Alvestrand69fb6c82019-02-13 18:40:1187 UpdateInformation();
88 if (observer_ && must_send_event) {
89 observer_->OnStateChange(Information());
90 }
Harald Alvestrandd02541e2019-01-03 11:43:2891}
92
93void DtlsTransport::OnInternalDtlsState(
94 cricket::DtlsTransportInternal* transport,
Mirko Bonadei9f6808b2021-05-21 18:46:0995 DtlsTransportState state) {
Harald Alvestrand69fb6c82019-02-13 18:40:1196 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 11:43:2897 RTC_DCHECK(transport == internal());
98 RTC_DCHECK(state == internal()->dtls_state());
Harald Alvestrand69fb6c82019-02-13 18:40:1199 UpdateInformation();
Harald Alvestrandd02541e2019-01-03 11:43:28100 if (observer_) {
101 observer_->OnStateChange(Information());
102 }
Harald Alvestrandad88c882018-11-28 15:47:46103}
104
Harald Alvestrand69fb6c82019-02-13 18:40:11105void DtlsTransport::UpdateInformation() {
106 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrand69fb6c82019-02-13 18:40:11107 if (internal_dtls_transport_) {
Harald Alvestrand7061e512019-04-10 15:20:42108 if (internal_dtls_transport_->dtls_state() ==
Mirko Bonadei9f6808b2021-05-21 18:46:09109 DtlsTransportState::kConnected) {
Harald Alvestrandc6c3f862019-10-29 11:19:31110 bool success = true;
Harald Alvestrand316ab122022-02-10 08:23:47111 rtc::SSLRole internal_role;
Florent Castelli8037fc62024-08-29 13:00:40112 std::optional<DtlsTransportTlsRole> role;
Harald Alvestrand114871b2019-04-11 11:37:41113 int ssl_cipher_suite;
Harald Alvestrandc6c3f862019-10-29 11:19:31114 int tls_version;
115 int srtp_cipher;
Harald Alvestrand316ab122022-02-10 08:23:47116 success &= internal_dtls_transport_->GetDtlsRole(&internal_role);
117 if (success) {
118 switch (internal_role) {
119 case rtc::SSL_CLIENT:
Harald Alvestrand321ec3b2022-02-10 13:42:18120 role = DtlsTransportTlsRole::kClient;
Harald Alvestrand316ab122022-02-10 08:23:47121 break;
122 case rtc::SSL_SERVER:
Harald Alvestrand321ec3b2022-02-10 13:42:18123 role = DtlsTransportTlsRole::kServer;
Harald Alvestrand316ab122022-02-10 08:23:47124 break;
125 }
126 }
Harald Alvestrandc6c3f862019-10-29 11:19:31127 success &= internal_dtls_transport_->GetSslVersionBytes(&tls_version);
128 success &= internal_dtls_transport_->GetSslCipherSuite(&ssl_cipher_suite);
129 success &= internal_dtls_transport_->GetSrtpCryptoSuite(&srtp_cipher);
130 if (success) {
Tommi3ba809d2023-12-14 18:49:49131 set_info(DtlsTransportInformation(
Harald Alvestrand316ab122022-02-10 08:23:47132 internal_dtls_transport_->dtls_state(), role, tls_version,
Harald Alvestrandc6c3f862019-10-29 11:19:31133 ssl_cipher_suite, srtp_cipher,
Tommi3ba809d2023-12-14 18:49:49134 internal_dtls_transport_->GetRemoteSSLCertChain()));
Harald Alvestrand114871b2019-04-11 11:37:41135 } else {
Harald Alvestrandc6c3f862019-10-29 11:19:31136 RTC_LOG(LS_ERROR) << "DtlsTransport in connected state has incomplete "
137 "TLS information";
Tommi3ba809d2023-12-14 18:49:49138 set_info(DtlsTransportInformation(
Florent Castelli8037fc62024-08-29 13:00:40139 internal_dtls_transport_->dtls_state(), role, std::nullopt,
140 std::nullopt, std::nullopt,
Tommi3ba809d2023-12-14 18:49:49141 internal_dtls_transport_->GetRemoteSSLCertChain()));
Harald Alvestrand114871b2019-04-11 11:37:41142 }
Harald Alvestrand7061e512019-04-10 15:20:42143 } else {
Tommi3ba809d2023-12-14 18:49:49144 set_info(
145 DtlsTransportInformation(internal_dtls_transport_->dtls_state()));
Harald Alvestrand7061e512019-04-10 15:20:42146 }
Harald Alvestrand69fb6c82019-02-13 18:40:11147 } else {
Tommi3ba809d2023-12-14 18:49:49148 set_info(DtlsTransportInformation(DtlsTransportState::kClosed));
Harald Alvestrand69fb6c82019-02-13 18:40:11149 }
150}
151
Harald Alvestrandad88c882018-11-28 15:47:46152} // namespace webrtc