Add IceTransportInterface object
This creates the API for an ICE transport object, and lets it
be accessible from a DTLS transport object.
Bug: chromium:907849
Change-Id: Ieb24570217dec75ce0deca8420739c1f116fbba4
Reviewed-on: https://webrtc-review.googlesource.com/c/118703
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26472}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 6a24aba..52da137 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -80,6 +80,7 @@
"data_channel_interface.h",
"dtls_transport_interface.h",
"dtmf_sender_interface.h",
+ "ice_transport_interface.h",
"jsep.cc",
"jsep.h",
"jsep_ice_candidate.cc",
@@ -347,6 +348,21 @@
]
}
+rtc_source_set("ice_transport_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "ice_transport_factory.cc",
+ "ice_transport_factory.h",
+ ]
+ deps = [
+ ":libjingle_peerconnection_api",
+ ":scoped_refptr",
+ "../p2p:rtc_p2p",
+ "../rtc_base:rtc_base",
+ "//third_party/abseil-cpp/absl/memory:memory",
+ ]
+}
+
rtc_source_set("libjingle_peerconnection_test_api") {
visibility = [ "*" ]
testonly = true
diff --git a/api/DEPS b/api/DEPS
index edc9a23..96fd36b 100644
--- a/api/DEPS
+++ b/api/DEPS
@@ -87,6 +87,10 @@
"+modules/include/module_fec_types.h",
],
+ "ice_transport_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
"jsep\.h": [
"+rtc_base/ref_count.h",
],
diff --git a/api/dtls_transport_interface.h b/api/dtls_transport_interface.h
index 1faf3f5..ff3b107 100644
--- a/api/dtls_transport_interface.h
+++ b/api/dtls_transport_interface.h
@@ -11,7 +11,9 @@
#ifndef API_DTLS_TRANSPORT_INTERFACE_H_
#define API_DTLS_TRANSPORT_INTERFACE_H_
+#include "api/ice_transport_interface.h"
#include "api/rtc_error.h"
+#include "api/scoped_refptr.h"
#include "rtc_base/ref_count.h"
namespace webrtc {
@@ -59,6 +61,8 @@
// be initiated by other threads.
class DtlsTransportInterface : public rtc::RefCountInterface {
public:
+ // Returns a pointer to the ICE transport that is owned by the DTLS transport.
+ virtual rtc::scoped_refptr<IceTransportInterface> ice_transport() = 0;
// These functions can only be called from the signalling thread.
virtual DtlsTransportInformation Information() = 0;
// Observer management.
diff --git a/api/ice_transport_factory.cc b/api/ice_transport_factory.cc
new file mode 100644
index 0000000..b632f09
--- /dev/null
+++ b/api/ice_transport_factory.cc
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/ice_transport_factory.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "p2p/base/ice_transport_internal.h"
+#include "p2p/base/p2p_transport_channel.h"
+#include "p2p/base/port_allocator.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+
+namespace {
+
+// This implementation of IceTransportInterface is used in cases where
+// the only reference to the P2PTransport will be through this class.
+// It must be constructed, accessed and destroyed on the signaling thread.
+class IceTransportWithTransportChannel : public IceTransportInterface {
+ public:
+ IceTransportWithTransportChannel(
+ std::unique_ptr<cricket::IceTransportInternal> internal)
+ : internal_(std::move(internal)) {}
+
+ ~IceTransportWithTransportChannel() override {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ }
+
+ cricket::IceTransportInternal* internal() override {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ return internal_.get();
+ }
+
+ private:
+ const rtc::ThreadChecker thread_checker_;
+ const std::unique_ptr<cricket::IceTransportInternal> internal_
+ RTC_GUARDED_BY(thread_checker_);
+};
+
+} // namespace
+
+rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
+ cricket::PortAllocator* port_allocator) {
+ return new rtc::RefCountedObject<IceTransportWithTransportChannel>(
+ absl::make_unique<cricket::P2PTransportChannel>("", 0, port_allocator));
+}
+
+} // namespace webrtc
diff --git a/api/ice_transport_factory.h b/api/ice_transport_factory.h
new file mode 100644
index 0000000..a8330df
--- /dev/null
+++ b/api/ice_transport_factory.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_ICE_TRANSPORT_FACTORY_H_
+#define API_ICE_TRANSPORT_FACTORY_H_
+
+#include "api/ice_transport_interface.h"
+#include "api/scoped_refptr.h"
+
+namespace cricket {
+class PortAllocator;
+}
+
+namespace webrtc {
+
+// Static factory for an IceTransport object that can be created
+// without using a webrtc::PeerConnection.
+// The returned object must be accessed and destroyed on the thread that
+// created it.
+// The PortAllocator must outlive the created IceTransportInterface object.
+rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
+ cricket::PortAllocator* port_allocator);
+
+} // namespace webrtc
+
+#endif // API_ICE_TRANSPORT_FACTORY_H_
diff --git a/api/ice_transport_interface.h b/api/ice_transport_interface.h
new file mode 100644
index 0000000..6e63045
--- /dev/null
+++ b/api/ice_transport_interface.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_ICE_TRANSPORT_INTERFACE_H_
+#define API_ICE_TRANSPORT_INTERFACE_H_
+
+#include "api/rtc_error.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/ref_count.h"
+
+namespace cricket {
+class IceTransportInternal;
+} // namespace cricket
+
+namespace webrtc {
+
+// An ICE transport, as represented to the outside world.
+// This object is refcounted, and is therefore alive until the
+// last holder has released it.
+class IceTransportInterface : public rtc::RefCountInterface {
+ public:
+ // Accessor for the internal representation of an ICE transport.
+ // The returned object can only be safely used on the signalling thread.
+ // TODO(crbug.com/907849): Add API calls for the functions that have to
+ // be exposed to clients, and stop allowing access to the
+ // cricket::IceTransportInternal API.
+ virtual cricket::IceTransportInternal* internal() = 0;
+};
+
+} // namespace webrtc
+#endif // API_ICE_TRANSPORT_INTERFACE_H_
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 6fdbbcb..b0b2ea0 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -40,6 +40,8 @@
"dtls_transport.h",
"external_hmac.cc",
"external_hmac.h",
+ "ice_transport.cc",
+ "ice_transport.h",
"jsep_transport.cc",
"jsep_transport.h",
"jsep_transport_controller.cc",
@@ -246,6 +248,7 @@
"channel_unittest.cc",
"dtls_srtp_transport_unittest.cc",
"dtlstransport_unittest.cc",
+ "ice_transport_unittest.cc",
"jsep_transport_controller_unittest.cc",
"jsep_transport_unittest.cc",
"media_session_unittest.cc",
@@ -278,6 +281,7 @@
"../api:array_view",
"../api:audio_options_api",
"../api:fake_media_transport",
+ "../api:ice_transport_factory",
"../api:libjingle_peerconnection_api",
"../call:rtp_interfaces",
"../call:rtp_receiver",
diff --git a/pc/dtls_transport.cc b/pc/dtls_transport.cc
index 4709107..62a75f2 100644
--- a/pc/dtls_transport.cc
+++ b/pc/dtls_transport.cc
@@ -12,6 +12,8 @@
#include <utility>
+#include "pc/ice_transport.h"
+
namespace webrtc {
namespace {
@@ -46,6 +48,8 @@
RTC_DCHECK(internal_dtls_transport_.get());
internal_dtls_transport_->SignalDtlsState.connect(
this, &DtlsTransport::OnInternalDtlsState);
+ ice_transport_ = new rtc::RefCountedObject<IceTransportWithPointer>(
+ internal_dtls_transport_->ice_transport());
}
DtlsTransport::~DtlsTransport() {
@@ -74,6 +78,10 @@
observer_ = nullptr;
}
+rtc::scoped_refptr<IceTransportInterface> DtlsTransport::ice_transport() {
+ return ice_transport_;
+}
+
// Internal functions
void DtlsTransport::Clear() {
RTC_DCHECK(signaling_thread_->IsCurrent());
@@ -86,6 +94,7 @@
} else {
internal_dtls_transport_.reset();
}
+ ice_transport_->Clear();
}
void DtlsTransport::OnInternalDtlsState(
diff --git a/pc/dtls_transport.h b/pc/dtls_transport.h
index 0fdcc0f..535c7eb 100644
--- a/pc/dtls_transport.h
+++ b/pc/dtls_transport.h
@@ -14,11 +14,15 @@
#include <memory>
#include "api/dtls_transport_interface.h"
+#include "api/ice_transport_interface.h"
+#include "api/scoped_refptr.h"
#include "p2p/base/dtls_transport.h"
#include "rtc_base/async_invoker.h"
namespace webrtc {
+class IceTransportWithPointer;
+
// This implementation wraps a cricket::DtlsTransport, and takes
// ownership of it.
class DtlsTransport : public DtlsTransportInterface,
@@ -28,6 +32,7 @@
explicit DtlsTransport(
std::unique_ptr<cricket::DtlsTransportInternal> internal);
+ rtc::scoped_refptr<IceTransportInterface> ice_transport() override;
DtlsTransportInformation Information() override;
void RegisterObserver(DtlsTransportObserverInterface* observer) override;
void UnregisterObserver() override;
@@ -51,6 +56,7 @@
DtlsTransportObserverInterface* observer_ = nullptr;
rtc::Thread* signaling_thread_;
std::unique_ptr<cricket::DtlsTransportInternal> internal_dtls_transport_;
+ rtc::scoped_refptr<IceTransportWithPointer> ice_transport_;
};
} // namespace webrtc
diff --git a/pc/ice_transport.cc b/pc/ice_transport.cc
new file mode 100644
index 0000000..e395354
--- /dev/null
+++ b/pc/ice_transport.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "pc/ice_transport.h"
+
+#include <memory>
+#include <utility>
+
+namespace webrtc {
+
+IceTransportWithPointer::~IceTransportWithPointer() {
+ // We depend on the signaling thread to call Clear() before dropping
+ // its last reference to this object; if the destructor is called
+ // on the signaling thread, it's OK to not have called Clear().
+ if (internal_) {
+ RTC_DCHECK_RUN_ON(creator_thread_);
+ }
+}
+
+cricket::IceTransportInternal* IceTransportWithPointer::internal() {
+ RTC_DCHECK_RUN_ON(creator_thread_);
+ return internal_;
+}
+
+void IceTransportWithPointer::Clear() {
+ RTC_DCHECK_RUN_ON(creator_thread_);
+ internal_ = nullptr;
+}
+
+} // namespace webrtc
diff --git a/pc/ice_transport.h b/pc/ice_transport.h
new file mode 100644
index 0000000..69b69e4
--- /dev/null
+++ b/pc/ice_transport.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef PC_ICE_TRANSPORT_H_
+#define PC_ICE_TRANSPORT_H_
+
+#include "api/ice_transport_interface.h"
+#include "rtc_base/constructor_magic.h"
+#include "rtc_base/thread.h"
+#include "rtc_base/thread_checker.h"
+
+namespace webrtc {
+
+// Implementation of IceTransportInterface that does not take ownership
+// of its underlying IceTransport. It depends on its creator class to
+// ensure that Clear() is called before the underlying IceTransport
+// is deallocated.
+class IceTransportWithPointer : public IceTransportInterface {
+ public:
+ explicit IceTransportWithPointer(cricket::IceTransportInternal* internal)
+ : creator_thread_(rtc::Thread::Current()), internal_(internal) {
+ RTC_DCHECK(internal_);
+ }
+
+ cricket::IceTransportInternal* internal() override;
+ // This call will ensure that the pointer passed at construction is
+ // no longer in use by this object. Later calls to internal() will return
+ // null.
+ void Clear();
+
+ protected:
+ ~IceTransportWithPointer() override;
+
+ private:
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(IceTransportWithPointer);
+ const rtc::Thread* creator_thread_;
+ cricket::IceTransportInternal* internal_ RTC_GUARDED_BY(creator_thread_);
+};
+
+} // namespace webrtc
+
+#endif // PC_ICE_TRANSPORT_H_
diff --git a/pc/ice_transport_unittest.cc b/pc/ice_transport_unittest.cc
index c299b2c..8d668de 100644
--- a/pc/ice_transport_unittest.cc
+++ b/pc/ice_transport_unittest.cc
@@ -9,18 +9,39 @@
*/
#include "pc/ice_transport.h"
-#include "p2p/base/fake_port_allocator.h"
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "api/ice_transport_factory.h"
+#include "p2p/base/fake_ice_transport.h"
+#include "p2p/base/fake_port_allocator.h"
+#include "rtc_base/gunit.h"
+#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
class IceTransportTest : public testing::Test {};
-TEST_F(IceTransportTest, CreateStandaloneIceTransport) {
- auto port_allocator = new cricket::FakePortAllocator(nullptr, nullptr);
- auto transport = CreateIceTransport(port_allocator);
- ASSERT_TRUE(transport->internal());
+TEST_F(IceTransportTest, CreateNonSelfDeletingTransport) {
+ auto cricket_transport =
+ absl::make_unique<cricket::FakeIceTransport>("name", 0, nullptr);
+ rtc::scoped_refptr<IceTransportWithPointer> ice_transport =
+ new rtc::RefCountedObject<IceTransportWithPointer>(
+ cricket_transport.get());
+ EXPECT_EQ(ice_transport->internal(), cricket_transport.get());
+ ice_transport->Clear();
+ EXPECT_NE(ice_transport->internal(), cricket_transport.get());
+}
+
+TEST_F(IceTransportTest, CreateSelfDeletingTransport) {
+ std::unique_ptr<cricket::FakePortAllocator> port_allocator(
+ absl::make_unique<cricket::FakePortAllocator>(nullptr, nullptr));
+ auto ice_transport = CreateIceTransport(port_allocator.get());
+ EXPECT_NE(nullptr, ice_transport->internal());
}
} // namespace webrtc