Make DTLS role visible on DtlsTransport interface This is important for writing tests that affect the DTLS role. Bug: webrtc:13668 Change-Id: I5d9a93eca7996a8b74cdcfe412f59a85892e1ec1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/251389 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#35971}
diff --git a/api/dtls_transport_interface.cc b/api/dtls_transport_interface.cc index a68ff8f..faebc09 100644 --- a/api/dtls_transport_interface.cc +++ b/api/dtls_transport_interface.cc
@@ -20,11 +20,27 @@ DtlsTransportInformation::DtlsTransportInformation( DtlsTransportState state, + absl::optional<DtlsTransportTlsRole> role, absl::optional<int> tls_version, absl::optional<int> ssl_cipher_suite, absl::optional<int> srtp_cipher_suite, std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates) : state_(state), + role_(role), + tls_version_(tls_version), + ssl_cipher_suite_(ssl_cipher_suite), + srtp_cipher_suite_(srtp_cipher_suite), + remote_ssl_certificates_(std::move(remote_ssl_certificates)) {} + +// Deprecated version +DtlsTransportInformation::DtlsTransportInformation( + DtlsTransportState state, + absl::optional<int> tls_version, + absl::optional<int> ssl_cipher_suite, + absl::optional<int> srtp_cipher_suite, + std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates) + : state_(state), + role_(absl::nullopt), tls_version_(tls_version), ssl_cipher_suite_(ssl_cipher_suite), srtp_cipher_suite_(srtp_cipher_suite), @@ -33,6 +49,7 @@ DtlsTransportInformation::DtlsTransportInformation( const DtlsTransportInformation& c) : state_(c.state()), + role_(c.role_), tls_version_(c.tls_version_), ssl_cipher_suite_(c.ssl_cipher_suite_), srtp_cipher_suite_(c.srtp_cipher_suite_), @@ -43,6 +60,7 @@ DtlsTransportInformation& DtlsTransportInformation::operator=( const DtlsTransportInformation& c) { state_ = c.state(); + role_ = c.role_; tls_version_ = c.tls_version_; ssl_cipher_suite_ = c.ssl_cipher_suite_; srtp_cipher_suite_ = c.srtp_cipher_suite_;
diff --git a/api/dtls_transport_interface.h b/api/dtls_transport_interface.h index 86715b0..7b01512 100644 --- a/api/dtls_transport_interface.h +++ b/api/dtls_transport_interface.h
@@ -36,6 +36,11 @@ kNumValues }; +enum class DtlsTransportTlsRole { + kServer, // Other end sends CLIENT_HELLO + kClient // This end sends CLIENT_HELLO +}; + // This object gives snapshot information about the changeable state of a // DTLSTransport. class RTC_EXPORT DtlsTransportInformation { @@ -44,10 +49,19 @@ explicit DtlsTransportInformation(DtlsTransportState state); DtlsTransportInformation( DtlsTransportState state, + absl::optional<DtlsTransportTlsRole> role, absl::optional<int> tls_version, absl::optional<int> ssl_cipher_suite, absl::optional<int> srtp_cipher_suite, std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates); + ABSL_DEPRECATED("Use version with role parameter") + DtlsTransportInformation( + DtlsTransportState state, + absl::optional<int> tls_version, + absl::optional<int> ssl_cipher_suite, + absl::optional<int> srtp_cipher_suite, + std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates); + // Copy and assign DtlsTransportInformation(const DtlsTransportInformation& c); DtlsTransportInformation& operator=(const DtlsTransportInformation& c); @@ -57,6 +71,7 @@ default; DtlsTransportState state() const { return state_; } + absl::optional<DtlsTransportTlsRole> role() const { return role_; } absl::optional<int> tls_version() const { return tls_version_; } absl::optional<int> ssl_cipher_suite() const { return ssl_cipher_suite_; } absl::optional<int> srtp_cipher_suite() const { return srtp_cipher_suite_; } @@ -67,6 +82,7 @@ private: DtlsTransportState state_; + absl::optional<DtlsTransportTlsRole> role_; absl::optional<int> tls_version_; absl::optional<int> ssl_cipher_suite_; absl::optional<int> srtp_cipher_suite_;
diff --git a/pc/dtls_transport.cc b/pc/dtls_transport.cc index 074f44e..5cee54c 100644 --- a/pc/dtls_transport.cc +++ b/pc/dtls_transport.cc
@@ -105,22 +105,35 @@ if (internal_dtls_transport_->dtls_state() == DtlsTransportState::kConnected) { bool success = true; + rtc::SSLRole internal_role; + absl::optional<DtlsTransportTlsRole> role; int ssl_cipher_suite; int tls_version; int srtp_cipher; + success &= internal_dtls_transport_->GetDtlsRole(&internal_role); + if (success) { + switch (internal_role) { + case rtc::SSL_CLIENT: + role = DtlsTransportTlsRole::kServer; + break; + case rtc::SSL_SERVER: + role = DtlsTransportTlsRole::kClient; + break; + } + } success &= internal_dtls_transport_->GetSslVersionBytes(&tls_version); success &= internal_dtls_transport_->GetSslCipherSuite(&ssl_cipher_suite); success &= internal_dtls_transport_->GetSrtpCryptoSuite(&srtp_cipher); if (success) { info_ = DtlsTransportInformation( - internal_dtls_transport_->dtls_state(), tls_version, + internal_dtls_transport_->dtls_state(), role, tls_version, ssl_cipher_suite, srtp_cipher, internal_dtls_transport_->GetRemoteSSLCertChain()); } else { RTC_LOG(LS_ERROR) << "DtlsTransport in connected state has incomplete " "TLS information"; info_ = DtlsTransportInformation( - internal_dtls_transport_->dtls_state(), absl::nullopt, + internal_dtls_transport_->dtls_state(), role, absl::nullopt, absl::nullopt, absl::nullopt, internal_dtls_transport_->GetRemoteSSLCertChain()); }
diff --git a/pc/dtls_transport_unittest.cc b/pc/dtls_transport_unittest.cc index f80d99b..477133e 100644 --- a/pc/dtls_transport_unittest.cc +++ b/pc/dtls_transport_unittest.cc
@@ -120,6 +120,18 @@ kDefaultTimeout); } +TEST_F(DtlsTransportTest, RoleAppearsOnConnect) { + rtc::FakeSSLCertificate fake_certificate("fake data"); + CreateTransport(&fake_certificate); + transport()->RegisterObserver(observer()); + EXPECT_FALSE(transport()->Information().role()); + CompleteDtlsHandshake(); + ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected, + kDefaultTimeout); + EXPECT_TRUE(observer_.info_.role()); + EXPECT_TRUE(transport()->Information().role()); +} + TEST_F(DtlsTransportTest, CertificateAppearsOnConnect) { rtc::FakeSSLCertificate fake_certificate("fake data"); CreateTransport(&fake_certificate);