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}
This commit is contained in:
Harald Alvestrand 2019-01-30 14:57:03 +01:00 committed by Commit Bot
parent 0873684401
commit 984626245a
12 changed files with 284 additions and 5 deletions

View File

@ -80,6 +80,7 @@ rtc_static_library("libjingle_peerconnection_api") {
"data_channel_interface.h", "data_channel_interface.h",
"dtls_transport_interface.h", "dtls_transport_interface.h",
"dtmf_sender_interface.h", "dtmf_sender_interface.h",
"ice_transport_interface.h",
"jsep.cc", "jsep.cc",
"jsep.h", "jsep.h",
"jsep_ice_candidate.cc", "jsep_ice_candidate.cc",
@ -347,6 +348,21 @@ rtc_source_set("refcountedbase") {
] ]
} }
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") { rtc_source_set("libjingle_peerconnection_test_api") {
visibility = [ "*" ] visibility = [ "*" ]
testonly = true testonly = true

View File

@ -87,6 +87,10 @@ specific_include_rules = {
"+modules/include/module_fec_types.h", "+modules/include/module_fec_types.h",
], ],
"ice_transport_interface\.h": [
"+rtc_base/ref_count.h",
],
"jsep\.h": [ "jsep\.h": [
"+rtc_base/ref_count.h", "+rtc_base/ref_count.h",
], ],

View File

@ -11,7 +11,9 @@
#ifndef API_DTLS_TRANSPORT_INTERFACE_H_ #ifndef API_DTLS_TRANSPORT_INTERFACE_H_
#define API_DTLS_TRANSPORT_INTERFACE_H_ #define API_DTLS_TRANSPORT_INTERFACE_H_
#include "api/ice_transport_interface.h"
#include "api/rtc_error.h" #include "api/rtc_error.h"
#include "api/scoped_refptr.h"
#include "rtc_base/ref_count.h" #include "rtc_base/ref_count.h"
namespace webrtc { namespace webrtc {
@ -59,6 +61,8 @@ class DtlsTransportObserverInterface {
// be initiated by other threads. // be initiated by other threads.
class DtlsTransportInterface : public rtc::RefCountInterface { class DtlsTransportInterface : public rtc::RefCountInterface {
public: 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. // These functions can only be called from the signalling thread.
virtual DtlsTransportInformation Information() = 0; virtual DtlsTransportInformation Information() = 0;
// Observer management. // Observer management.

View File

@ -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

View File

@ -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_

View File

@ -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_

View File

@ -40,6 +40,8 @@ rtc_static_library("rtc_pc_base") {
"dtls_transport.h", "dtls_transport.h",
"external_hmac.cc", "external_hmac.cc",
"external_hmac.h", "external_hmac.h",
"ice_transport.cc",
"ice_transport.h",
"jsep_transport.cc", "jsep_transport.cc",
"jsep_transport.h", "jsep_transport.h",
"jsep_transport_controller.cc", "jsep_transport_controller.cc",
@ -246,6 +248,7 @@ if (rtc_include_tests) {
"channel_unittest.cc", "channel_unittest.cc",
"dtls_srtp_transport_unittest.cc", "dtls_srtp_transport_unittest.cc",
"dtlstransport_unittest.cc", "dtlstransport_unittest.cc",
"ice_transport_unittest.cc",
"jsep_transport_controller_unittest.cc", "jsep_transport_controller_unittest.cc",
"jsep_transport_unittest.cc", "jsep_transport_unittest.cc",
"media_session_unittest.cc", "media_session_unittest.cc",
@ -278,6 +281,7 @@ if (rtc_include_tests) {
"../api:array_view", "../api:array_view",
"../api:audio_options_api", "../api:audio_options_api",
"../api:fake_media_transport", "../api:fake_media_transport",
"../api:ice_transport_factory",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
"../call:rtp_interfaces", "../call:rtp_interfaces",
"../call:rtp_receiver", "../call:rtp_receiver",

View File

@ -12,6 +12,8 @@
#include <utility> #include <utility>
#include "pc/ice_transport.h"
namespace webrtc { namespace webrtc {
namespace { namespace {
@ -46,6 +48,8 @@ DtlsTransport::DtlsTransport(
RTC_DCHECK(internal_dtls_transport_.get()); RTC_DCHECK(internal_dtls_transport_.get());
internal_dtls_transport_->SignalDtlsState.connect( internal_dtls_transport_->SignalDtlsState.connect(
this, &DtlsTransport::OnInternalDtlsState); this, &DtlsTransport::OnInternalDtlsState);
ice_transport_ = new rtc::RefCountedObject<IceTransportWithPointer>(
internal_dtls_transport_->ice_transport());
} }
DtlsTransport::~DtlsTransport() { DtlsTransport::~DtlsTransport() {
@ -74,6 +78,10 @@ void DtlsTransport::UnregisterObserver() {
observer_ = nullptr; observer_ = nullptr;
} }
rtc::scoped_refptr<IceTransportInterface> DtlsTransport::ice_transport() {
return ice_transport_;
}
// Internal functions // Internal functions
void DtlsTransport::Clear() { void DtlsTransport::Clear() {
RTC_DCHECK(signaling_thread_->IsCurrent()); RTC_DCHECK(signaling_thread_->IsCurrent());
@ -86,6 +94,7 @@ void DtlsTransport::Clear() {
} else { } else {
internal_dtls_transport_.reset(); internal_dtls_transport_.reset();
} }
ice_transport_->Clear();
} }
void DtlsTransport::OnInternalDtlsState( void DtlsTransport::OnInternalDtlsState(

View File

@ -14,11 +14,15 @@
#include <memory> #include <memory>
#include "api/dtls_transport_interface.h" #include "api/dtls_transport_interface.h"
#include "api/ice_transport_interface.h"
#include "api/scoped_refptr.h"
#include "p2p/base/dtls_transport.h" #include "p2p/base/dtls_transport.h"
#include "rtc_base/async_invoker.h" #include "rtc_base/async_invoker.h"
namespace webrtc { namespace webrtc {
class IceTransportWithPointer;
// This implementation wraps a cricket::DtlsTransport, and takes // This implementation wraps a cricket::DtlsTransport, and takes
// ownership of it. // ownership of it.
class DtlsTransport : public DtlsTransportInterface, class DtlsTransport : public DtlsTransportInterface,
@ -28,6 +32,7 @@ class DtlsTransport : public DtlsTransportInterface,
explicit DtlsTransport( explicit DtlsTransport(
std::unique_ptr<cricket::DtlsTransportInternal> internal); std::unique_ptr<cricket::DtlsTransportInternal> internal);
rtc::scoped_refptr<IceTransportInterface> ice_transport() override;
DtlsTransportInformation Information() override; DtlsTransportInformation Information() override;
void RegisterObserver(DtlsTransportObserverInterface* observer) override; void RegisterObserver(DtlsTransportObserverInterface* observer) override;
void UnregisterObserver() override; void UnregisterObserver() override;
@ -51,6 +56,7 @@ class DtlsTransport : public DtlsTransportInterface,
DtlsTransportObserverInterface* observer_ = nullptr; DtlsTransportObserverInterface* observer_ = nullptr;
rtc::Thread* signaling_thread_; rtc::Thread* signaling_thread_;
std::unique_ptr<cricket::DtlsTransportInternal> internal_dtls_transport_; std::unique_ptr<cricket::DtlsTransportInternal> internal_dtls_transport_;
rtc::scoped_refptr<IceTransportWithPointer> ice_transport_;
}; };
} // namespace webrtc } // namespace webrtc

37
pc/ice_transport.cc Normal file
View File

@ -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

49
pc/ice_transport.h Normal file
View File

@ -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_

View File

@ -9,18 +9,39 @@
*/ */
#include "pc/ice_transport.h" #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" #include "test/gtest.h"
namespace webrtc { namespace webrtc {
class IceTransportTest : public testing::Test {}; class IceTransportTest : public testing::Test {};
TEST_F(IceTransportTest, CreateStandaloneIceTransport) { TEST_F(IceTransportTest, CreateNonSelfDeletingTransport) {
auto port_allocator = new cricket::FakePortAllocator(nullptr, nullptr); auto cricket_transport =
auto transport = CreateIceTransport(port_allocator); absl::make_unique<cricket::FakeIceTransport>("name", 0, nullptr);
ASSERT_TRUE(transport->internal()); 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 } // namespace webrtc