blob: 8abfcae53f98d63805e899d2d15c5afe7c9ceae3 [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
13#include <utility>
14
Harald Alvestrand98462622019-01-30 13:57:0315#include "pc/ice_transport.h"
16
Harald Alvestrandad88c882018-11-28 15:47:4617namespace webrtc {
18
Harald Alvestrandd02541e2019-01-03 11:43:2819namespace {
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 15:47:4644DtlsTransport::DtlsTransport(
45 std::unique_ptr<cricket::DtlsTransportInternal> internal)
Harald Alvestrand69fb6c82019-02-13 18:40:1146 : owner_thread_(rtc::Thread::Current()),
47 info_(DtlsTransportState::kNew),
Harald Alvestrand26451932019-02-21 10:27:1548 internal_dtls_transport_(std::move(internal)),
49 ice_transport_(new rtc::RefCountedObject<IceTransportWithPointer>(
50 internal_dtls_transport_->ice_transport())) {
Harald Alvestrandad88c882018-11-28 15:47:4651 RTC_DCHECK(internal_dtls_transport_.get());
Harald Alvestrandd02541e2019-01-03 11:43:2852 internal_dtls_transport_->SignalDtlsState.connect(
53 this, &DtlsTransport::OnInternalDtlsState);
Harald Alvestrand69fb6c82019-02-13 18:40:1154 UpdateInformation();
Harald Alvestrandd02541e2019-01-03 11:43:2855}
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 18:40:1160 RTC_DCHECK(owner_thread_->IsCurrent() || !internal_dtls_transport_);
Harald Alvestrandd02541e2019-01-03 11:43:2861}
62
63DtlsTransportInformation DtlsTransport::Information() {
Harald Alvestrand69fb6c82019-02-13 18:40:1164 rtc::CritScope scope(&lock_);
65 return info_;
Harald Alvestrandd02541e2019-01-03 11:43:2866}
67
68void DtlsTransport::RegisterObserver(DtlsTransportObserverInterface* observer) {
Harald Alvestrand69fb6c82019-02-13 18:40:1169 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 11:43:2870 RTC_DCHECK(observer);
71 observer_ = observer;
72}
73
74void DtlsTransport::UnregisterObserver() {
Harald Alvestrand69fb6c82019-02-13 18:40:1175 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 11:43:2876 observer_ = nullptr;
77}
78
Harald Alvestrand98462622019-01-30 13:57:0379rtc::scoped_refptr<IceTransportInterface> DtlsTransport::ice_transport() {
80 return ice_transport_;
81}
82
Harald Alvestrandd02541e2019-01-03 11:43:2883// Internal functions
84void DtlsTransport::Clear() {
Harald Alvestrand69fb6c82019-02-13 18:40:1185 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandcdc30452019-01-08 17:08:0486 RTC_DCHECK(internal());
Harald Alvestrand69fb6c82019-02-13 18:40:1187 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 17:08:0496 }
Harald Alvestrand69fb6c82019-02-13 18:40:1197 UpdateInformation();
98 if (observer_ && must_send_event) {
99 observer_->OnStateChange(Information());
100 }
Harald Alvestrandd02541e2019-01-03 11:43:28101}
102
103void DtlsTransport::OnInternalDtlsState(
104 cricket::DtlsTransportInternal* transport,
105 cricket::DtlsTransportState state) {
Harald Alvestrand69fb6c82019-02-13 18:40:11106 RTC_DCHECK_RUN_ON(owner_thread_);
Harald Alvestrandd02541e2019-01-03 11:43:28107 RTC_DCHECK(transport == internal());
108 RTC_DCHECK(state == internal()->dtls_state());
Harald Alvestrand69fb6c82019-02-13 18:40:11109 UpdateInformation();
Harald Alvestrandd02541e2019-01-03 11:43:28110 if (observer_) {
111 observer_->OnStateChange(Information());
112 }
Harald Alvestrandad88c882018-11-28 15:47:46113}
114
Harald Alvestrand69fb6c82019-02-13 18:40:11115void DtlsTransport::UpdateInformation() {
116 RTC_DCHECK_RUN_ON(owner_thread_);
117 rtc::CritScope scope(&lock_);
118 if (internal_dtls_transport_) {
Harald Alvestrand7061e512019-04-10 15:20:42119 if (internal_dtls_transport_->dtls_state() ==
120 cricket::DTLS_TRANSPORT_CONNECTED) {
Harald Alvestrandc6c3f862019-10-29 11:19:31121 bool success = true;
Harald Alvestrand114871b2019-04-11 11:37:41122 int ssl_cipher_suite;
Harald Alvestrandc6c3f862019-10-29 11:19:31123 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 11:37:41129 info_ = DtlsTransportInformation(
Harald Alvestrandc6c3f862019-10-29 11:19:31130 TranslateState(internal_dtls_transport_->dtls_state()), tls_version,
131 ssl_cipher_suite, srtp_cipher,
Harald Alvestrand114871b2019-04-11 11:37:41132 internal_dtls_transport_->GetRemoteSSLCertChain());
133 } else {
Harald Alvestrandc6c3f862019-10-29 11:19:31134 RTC_LOG(LS_ERROR) << "DtlsTransport in connected state has incomplete "
135 "TLS information";
Harald Alvestrand114871b2019-04-11 11:37:41136 info_ = DtlsTransportInformation(
137 TranslateState(internal_dtls_transport_->dtls_state()),
Harald Alvestrandc6c3f862019-10-29 11:19:31138 absl::nullopt, absl::nullopt, absl::nullopt,
139 internal_dtls_transport_->GetRemoteSSLCertChain());
Harald Alvestrand114871b2019-04-11 11:37:41140 }
Harald Alvestrand7061e512019-04-10 15:20:42141 } else {
142 info_ = DtlsTransportInformation(
143 TranslateState(internal_dtls_transport_->dtls_state()));
144 }
Harald Alvestrand69fb6c82019-02-13 18:40:11145 } else {
146 info_ = DtlsTransportInformation(DtlsTransportState::kClosed);
147 }
148}
149
Harald Alvestrandad88c882018-11-28 15:47:46150} // namespace webrtc