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);