Add AsyncResolverFactory interface and basic implementation.

The factory is plumbed down to P2PTransportChannel and will eventually
be used to resolve hostnames. Uses of PacketSocketFacotry::CreateAsyncResolver
will eventually be migrated to use this factory instead.

Bug: webrtc:4165
Change-Id: I1c48b2ffb8649609a831eba291f67ce544bb10eb
Reviewed-on: https://webrtc-review.googlesource.com/91300
Commit-Queue: Zach Stein <zstein@webrtc.org>
Reviewed-by: Emad Omara <emadomara@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24176}
This commit is contained in:
Zach Stein
2018-08-02 13:20:15 -07:00
committed by Commit Bot
parent da2ec40590
commit e20867ff6d
15 changed files with 166 additions and 5 deletions

View File

@ -48,6 +48,7 @@ rtc_static_library("libjingle_peerconnection_api") {
visibility = [ "*" ]
cflags = []
sources = [
"asyncresolverfactory.h",
"bitrate_constraints.h",
"candidate.cc",
"candidate.h",

View File

@ -0,0 +1,33 @@
/*
* Copyright 2018 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_ASYNCRESOLVERFACTORY_H_
#define API_ASYNCRESOLVERFACTORY_H_
#include "rtc_base/asyncresolverinterface.h"
namespace webrtc {
// An abstract factory for creating AsyncResolverInterfaces. This allows
// client applications to provide WebRTC with their own mechanism for
// performing DNS resolution.
class AsyncResolverFactory {
public:
AsyncResolverFactory() = default;
virtual ~AsyncResolverFactory() = default;
// The returned object is responsible for deleting itself after address
// resolution has completed.
virtual rtc::AsyncResolverInterface* Create() = 0;
};
} // namespace webrtc
#endif // API_ASYNCRESOLVERFACTORY_H_

View File

@ -72,6 +72,7 @@
#include <utility>
#include <vector>
#include "api/asyncresolverfactory.h"
#include "api/audio/audio_mixer.h"
#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/audio_codecs/audio_encoder_factory.h"
@ -1129,6 +1130,7 @@ struct PeerConnectionDependencies final {
PeerConnectionObserver* observer = nullptr;
// Optional dependencies
std::unique_ptr<cricket::PortAllocator> allocator;
std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory;
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier;
};

View File

@ -20,6 +20,8 @@ rtc_static_library("rtc_p2p") {
sources = [
"base/asyncstuntcpsocket.cc",
"base/asyncstuntcpsocket.h",
"base/basicasyncresolverfactory.cc",
"base/basicasyncresolverfactory.h",
"base/basicpacketsocketfactory.cc",
"base/basicpacketsocketfactory.h",
"base/candidatepairinterface.h",
@ -151,6 +153,7 @@ if (rtc_include_tests) {
sources = [
"base/asyncstuntcpsocket_unittest.cc",
"base/basicasyncresolverfactory_unittest.cc",
"base/dtlstransport_unittest.cc",
"base/p2ptransportchannel_unittest.cc",
"base/packetlossestimator_unittest.cc",

View File

@ -0,0 +1,21 @@
/*
* Copyright 2018 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 "p2p/base/basicasyncresolverfactory.h"
#include "rtc_base/nethelpers.h"
namespace webrtc {
rtc::AsyncResolverInterface* BasicAsyncResolverFactory::Create() {
return new rtc::AsyncResolver();
}
} // namespace webrtc

View File

@ -0,0 +1,25 @@
/*
* Copyright 2018 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 P2P_BASE_BASICASYNCRESOLVERFACTORY_H_
#define P2P_BASE_BASICASYNCRESOLVERFACTORY_H_
#include "api/asyncresolverfactory.h"
namespace webrtc {
class BasicAsyncResolverFactory : public AsyncResolverFactory {
public:
rtc::AsyncResolverInterface* Create() override;
};
} // namespace webrtc
#endif // P2P_BASE_BASICASYNCRESOLVERFACTORY_H_

View File

@ -0,0 +1,45 @@
/*
* Copyright 2018 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 "p2p/base/basicasyncresolverfactory.h"
#include "rtc_base/gunit.h"
namespace webrtc {
class BasicAsyncResolverFactoryTest : public testing::Test,
public sigslot::has_slots<> {
public:
void TestCreate() {
BasicAsyncResolverFactory factory;
rtc::AsyncResolverInterface* resolver = factory.Create();
ASSERT_TRUE(resolver);
resolver->SignalDone.connect(
this, &BasicAsyncResolverFactoryTest::SetAddressResolved);
rtc::SocketAddress address("", 0);
resolver->Start(address);
ASSERT_TRUE_WAIT(address_resolved_, 10000 /*ms*/);
}
void SetAddressResolved(rtc::AsyncResolverInterface* resolver) {
address_resolved_ = true;
}
private:
bool address_resolved_ = false;
};
// This test is primarily intended to let tools check that the created resolver
// doesn't leak.
TEST_F(BasicAsyncResolverFactoryTest, TestCreate) {
TestCreate();
}
} // namespace webrtc

View File

@ -112,11 +112,19 @@ bool IceCredentialsChanged(const std::string& old_ufrag,
P2PTransportChannel::P2PTransportChannel(const std::string& transport_name,
int component,
PortAllocator* allocator,
webrtc::RtcEventLog* event_log)
PortAllocator* allocator)
: P2PTransportChannel(transport_name, component, allocator, nullptr) {}
P2PTransportChannel::P2PTransportChannel(
const std::string& transport_name,
int component,
PortAllocator* allocator,
webrtc::AsyncResolverFactory* async_resolver_factory,
webrtc::RtcEventLog* event_log)
: transport_name_(transport_name),
component_(component),
allocator_(allocator),
async_resolver_factory_(async_resolver_factory),
network_thread_(rtc::Thread::Current()),
incoming_only_(false),
error_(0),

View File

@ -27,6 +27,7 @@
#include <string>
#include <vector>
#include "api/asyncresolverfactory.h"
#include "api/candidate.h"
#include "api/rtcerror.h"
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
@ -75,9 +76,15 @@ class RemoteCandidate : public Candidate {
// two P2P clients connected to each other.
class P2PTransportChannel : public IceTransportInternal {
public:
// For testing only.
// TODO(zstein): Remove once AsyncResolverFactory is required.
P2PTransportChannel(const std::string& transport_name,
int component,
PortAllocator* allocator);
P2PTransportChannel(const std::string& transport_name,
int component,
PortAllocator* allocator,
webrtc::AsyncResolverFactory* async_resolver_factory,
webrtc::RtcEventLog* event_log = nullptr);
~P2PTransportChannel() override;
@ -359,6 +366,7 @@ class P2PTransportChannel : public IceTransportInternal {
std::string transport_name_;
int component_;
PortAllocator* allocator_;
webrtc::AsyncResolverFactory* async_resolver_factory_;
rtc::Thread* network_thread_;
bool incoming_only_;
int error_;

View File

@ -90,10 +90,12 @@ JsepTransportController::JsepTransportController(
rtc::Thread* signaling_thread,
rtc::Thread* network_thread,
cricket::PortAllocator* port_allocator,
AsyncResolverFactory* async_resolver_factory,
Config config)
: signaling_thread_(signaling_thread),
network_thread_(network_thread),
port_allocator_(port_allocator),
async_resolver_factory_(async_resolver_factory),
config_(config) {
// The |transport_observer| is assumed to be non-null.
RTC_DCHECK(config_.transport_observer);
@ -398,7 +400,8 @@ JsepTransportController::CreateDtlsTransport(const std::string& transport_name,
std::move(ice), config_.crypto_options);
} else {
auto ice = absl::make_unique<cricket::P2PTransportChannel>(
transport_name, component, port_allocator_, config_.event_log);
transport_name, component, port_allocator_, async_resolver_factory_,
config_.event_log);
dtls = absl::make_unique<cricket::DtlsTransport>(std::move(ice),
config_.crypto_options);
}

View File

@ -87,6 +87,7 @@ class JsepTransportController : public sigslot::has_slots<>,
JsepTransportController(rtc::Thread* signaling_thread,
rtc::Thread* network_thread,
cricket::PortAllocator* port_allocator,
AsyncResolverFactory* async_resolver_factory,
Config config);
virtual ~JsepTransportController();
@ -296,6 +297,7 @@ class JsepTransportController : public sigslot::has_slots<>,
rtc::Thread* const signaling_thread_ = nullptr;
rtc::Thread* const network_thread_ = nullptr;
cricket::PortAllocator* const port_allocator_ = nullptr;
AsyncResolverFactory* const async_resolver_factory_ = nullptr;
std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
jsep_transports_by_name_;

View File

@ -75,8 +75,9 @@ class JsepTransportControllerTest : public JsepTransportController::Observer,
config.transport_observer = this;
// The tests only works with |fake_transport_factory|;
config.external_transport_factory = fake_transport_factory_.get();
// TODO(zstein): Provide an AsyncResolverFactory once it is required.
transport_controller_ = absl::make_unique<JsepTransportController>(
signaling_thread, network_thread, port_allocator, config);
signaling_thread, network_thread, port_allocator, nullptr, config);
ConnectTransportControllerSignals();
}

View File

@ -907,6 +907,7 @@ bool PeerConnection::Initialize(
}
observer_ = dependencies.observer;
async_resolver_factory_ = std::move(dependencies.async_resolver_factory);
port_allocator_ = std::move(dependencies.allocator);
tls_cert_verifier_ = std::move(dependencies.tls_cert_verifier);
@ -968,7 +969,8 @@ bool PeerConnection::Initialize(
#endif
config.active_reset_srtp_params = configuration.active_reset_srtp_params;
transport_controller_.reset(new JsepTransportController(
signaling_thread(), network_thread(), port_allocator_.get(), config));
signaling_thread(), network_thread(), port_allocator_.get(),
async_resolver_factory_.get(), config));
transport_controller_->SignalIceConnectionState.connect(
this, &PeerConnection::OnTransportControllerConnectionState);
transport_controller_->SignalIceGatheringState.connect(

View File

@ -938,6 +938,9 @@ class PeerConnection : public PeerConnectionInternal,
IceGatheringState ice_gathering_state_ = kIceGatheringNew;
PeerConnectionInterface::RTCConfiguration configuration_;
// TODO(zstein): |async_resolver_factory_| can currently be nullptr if it
// is not injected. It should be required once chromium supplies it.
std::unique_ptr<AsyncResolverFactory> async_resolver_factory_;
std::unique_ptr<cricket::PortAllocator> port_allocator_;
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier_;
int port_allocator_flags_ = 0;

View File

@ -378,6 +378,10 @@ PeerConnectionFactory::CreatePeerConnection(
configuration.turn_customizer));
}
// TODO(zstein): Once chromium injects its own AsyncResolverFactory, set
// |dependencies.async_resolver_factory| to a new
// |rtc::BasicAsyncResolverFactory| if no factory is provided.
network_thread_->Invoke<void>(
RTC_FROM_HERE,
rtc::Bind(&cricket::PortAllocator::SetNetworkIgnoreMask,