blob: 8abfcae53f98d63805e899d2d15c5afe7c9ceae3 [file] [log] [blame]
Harald Alvestrandad88c882018-11-28 16:47:46 +01001/*
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/dtls_transport.h"
Harald Alvestrandad88c882018-11-28 16:47:46 +010012
13#include <utility>
14
Harald Alvestrand98462622019-01-30 14:57:03 +010015#include "pc/ice_transport.h"
16
Harald Alvestrandad88c882018-11-28 16:47:46 +010017namespace webrtc {
18
Harald Alvestrandd02541e2019-01-03 12:43:28 +010019namespace {
20
21DtlsTransportState TranslateState(cricket::DtlsTransportState internal_state) {
22 switch (internal_state) {
23 case cricket::DTLS_TRANSPORT_NEW:
24 return DtlsTransportState::kNew;
25 break;
26 case cricket::DTLS_TRANSPORT_CONNECTING:
27 return DtlsTransportState::kConnecting;
28 break;
29 case cricket::DTLS_TRANSPORT_CONNECTED:
30 return DtlsTransportState::kConnected;
31 break;
32 case cricket::DTLS_TRANSPORT_CLOSED:
33 return DtlsTransportState::kClosed;
34 break;
35 case cricket::DTLS_TRANSPORT_FAILED:
36 return DtlsTransportState::kFailed;
37 break;
38 }
39}
40
41} // namespace
42
43// Implementation of DtlsTransportInterface
Harald Alvestrandad88c882018-11-28 16:47:46 +010044DtlsTransport::DtlsTransport(
45 std::unique_ptr<cricket::DtlsTransportInternal> internal)
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010046 : owner_thread_(rtc::Thread::Current()),
47 info_(DtlsTransportState::kNew),
Harald Alvestrand26451932019-02-21 11:27:15 +010048 internal_dtls_transport_(std::move(internal)),
49 ice_transport_(new rtc::RefCountedObject<IceTransportWithPointer>(
50 internal_dtls_transport_->ice_transport())) {
Harald Alvestrandad88c882018-11-28 16:47:46 +010051 RTC_DCHECK(internal_dtls_transport_.get());
Harald Alvestrandd02541e2019-01-03 12:43:28 +010052 internal_dtls_transport_->SignalDtlsState.connect(
53 this, &DtlsTransport::OnInternalDtlsState);
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010054 UpdateInformation();
Harald Alvestrandd02541e2019-01-03 12:43:28 +010055}
56
57DtlsTransport::~DtlsTransport() {
58 // We depend on the signaling thread to call Clear() before dropping
59 // its last reference to this object.
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010060 RTC_DCHECK(owner_thread_->IsCurrent() || !internal_dtls_transport_);
Harald Alvestrandd02541e2019-01-03 12:43:28 +010061}
62
63DtlsTransportInformation DtlsTransport::Information() {
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010064 rtc::CritScope scope(&lock_);
65 return info_;
Harald Alvestrandd02541e2019-01-03 12:43:28 +010066}
67
68void DtlsTransport::RegisterObserver(DtlsTransportObserverInterface* observer) {
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010069 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 12:43:28 +010070 RTC_DCHECK(observer);
71 observer_ = observer;
72}
73
74void DtlsTransport::UnregisterObserver() {
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010075 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 12:43:28 +010076 observer_ = nullptr;
77}
78
Harald Alvestrand98462622019-01-30 14:57:03 +010079rtc::scoped_refptr<IceTransportInterface> DtlsTransport::ice_transport() {
80 return ice_transport_;
81}
82
Harald Alvestrandd02541e2019-01-03 12:43:28 +010083// Internal functions
84void DtlsTransport::Clear() {
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010085 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandcdc30452019-01-08 18:08:04 +010086 RTC_DCHECK(internal());
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010087 bool must_send_event =
88 (internal()->dtls_state() != cricket::DTLS_TRANSPORT_CLOSED);
89 // The destructor of cricket::DtlsTransportInternal calls back
90 // into DtlsTransport, so we can't hold the lock while releasing.
91 std::unique_ptr<cricket::DtlsTransportInternal> transport_to_release;
92 {
93 rtc::CritScope scope(&lock_);
94 transport_to_release = std::move(internal_dtls_transport_);
95 ice_transport_->Clear();
Harald Alvestrandcdc30452019-01-08 18:08:04 +010096 }
Harald Alvestrand69fb6c82019-02-13 19:40:11 +010097 UpdateInformation();
98 if (observer_ && must_send_event) {
99 observer_->OnStateChange(Information());
100 }
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100101}
102
103void DtlsTransport::OnInternalDtlsState(
104 cricket::DtlsTransportInternal* transport,
105 cricket::DtlsTransportState state) {
Harald Alvestrand69fb6c82019-02-13 19:40:11 +0100106 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100107 RTC_DCHECK(transport == internal());
108 RTC_DCHECK(state == internal()->dtls_state());
Harald Alvestrand69fb6c82019-02-13 19:40:11 +0100109 UpdateInformation();
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100110 if (observer_) {
111 observer_->OnStateChange(Information());
112 }
Harald Alvestrandad88c882018-11-28 16:47:46 +0100113}
114
Harald Alvestrand69fb6c82019-02-13 19:40:11 +0100115void DtlsTransport::UpdateInformation() {
116 RTC_DCHECK_RUN_ON(owner_thread_);
117 rtc::CritScope scope(&lock_);
118 if (internal_dtls_transport_) {
Harald Alvestrand7061e512019-04-10 17:20:42 +0200119 if (internal_dtls_transport_->dtls_state() ==
120 cricket::DTLS_TRANSPORT_CONNECTED) {
Harald Alvestrandc6c3f862019-10-29 12:19:31 +0100121 bool success = true;
Harald Alvestrand114871b2019-04-11 13:37:41 +0200122 int ssl_cipher_suite;
Harald Alvestrandc6c3f862019-10-29 12:19:31 +0100123 int tls_version;
124 int srtp_cipher;
125 success &= internal_dtls_transport_->GetSslVersionBytes(&tls_version);
126 success &= internal_dtls_transport_->GetSslCipherSuite(&ssl_cipher_suite);
127 success &= internal_dtls_transport_->GetSrtpCryptoSuite(&srtp_cipher);
128 if (success) {
Harald Alvestrand114871b2019-04-11 13:37:41 +0200129 info_ = DtlsTransportInformation(
Harald Alvestrandc6c3f862019-10-29 12:19:31 +0100130 TranslateState(internal_dtls_transport_->dtls_state()), tls_version,
131 ssl_cipher_suite, srtp_cipher,
Harald Alvestrand114871b2019-04-11 13:37:41 +0200132 internal_dtls_transport_->GetRemoteSSLCertChain());
133 } else {
Harald Alvestrandc6c3f862019-10-29 12:19:31 +0100134 RTC_LOG(LS_ERROR) << "DtlsTransport in connected state has incomplete "
135 "TLS information";
Harald Alvestrand114871b2019-04-11 13:37:41 +0200136 info_ = DtlsTransportInformation(
137 TranslateState(internal_dtls_transport_->dtls_state()),
Harald Alvestrandc6c3f862019-10-29 12:19:31 +0100138 absl::nullopt, absl::nullopt, absl::nullopt,
139 internal_dtls_transport_->GetRemoteSSLCertChain());
Harald Alvestrand114871b2019-04-11 13:37:41 +0200140 }
Harald Alvestrand7061e512019-04-10 17:20:42 +0200141 } else {
142 info_ = DtlsTransportInformation(
143 TranslateState(internal_dtls_transport_->dtls_state()));
144 }
Harald Alvestrand69fb6c82019-02-13 19:40:11 +0100145 } else {
146 info_ = DtlsTransportInformation(DtlsTransportState::kClosed);
147 }
148}
149
Harald Alvestrandad88c882018-11-28 16:47:46 +0100150} // namespace webrtc