diff --git a/api/BUILD.gn b/api/BUILD.gn index e50e34d8c4..7271ece848 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -48,6 +48,7 @@ rtc_static_library("libjingle_peerconnection_api") { visibility = [ "*" ] cflags = [] sources = [ + "asyncresolverfactory.h", "bitrate_constraints.h", "candidate.cc", "candidate.h", diff --git a/api/asyncresolverfactory.h b/api/asyncresolverfactory.h new file mode 100644 index 0000000000..3c3bb1e703 --- /dev/null +++ b/api/asyncresolverfactory.h @@ -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_ diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h index edac135cf1..0fc2a2b5b8 100644 --- a/api/peerconnectioninterface.h +++ b/api/peerconnectioninterface.h @@ -72,6 +72,7 @@ #include #include +#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 allocator; + std::unique_ptr async_resolver_factory; std::unique_ptr cert_generator; std::unique_ptr tls_cert_verifier; }; diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn index 6666c9fedb..297889dad7 100644 --- a/p2p/BUILD.gn +++ b/p2p/BUILD.gn @@ -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", diff --git a/p2p/base/basicasyncresolverfactory.cc b/p2p/base/basicasyncresolverfactory.cc new file mode 100644 index 0000000000..22dac68510 --- /dev/null +++ b/p2p/base/basicasyncresolverfactory.cc @@ -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 diff --git a/p2p/base/basicasyncresolverfactory.h b/p2p/base/basicasyncresolverfactory.h new file mode 100644 index 0000000000..29fe6d005d --- /dev/null +++ b/p2p/base/basicasyncresolverfactory.h @@ -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_ diff --git a/p2p/base/basicasyncresolverfactory_unittest.cc b/p2p/base/basicasyncresolverfactory_unittest.cc new file mode 100644 index 0000000000..4529d5eb19 --- /dev/null +++ b/p2p/base/basicasyncresolverfactory_unittest.cc @@ -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 diff --git a/p2p/base/p2ptransportchannel.cc b/p2p/base/p2ptransportchannel.cc index 11cf412b2b..a2833cd029 100644 --- a/p2p/base/p2ptransportchannel.cc +++ b/p2p/base/p2ptransportchannel.cc @@ -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), diff --git a/p2p/base/p2ptransportchannel.h b/p2p/base/p2ptransportchannel.h index 94e88ddbb9..1ac898e490 100644 --- a/p2p/base/p2ptransportchannel.h +++ b/p2p/base/p2ptransportchannel.h @@ -27,6 +27,7 @@ #include #include +#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_; diff --git a/pc/jseptransportcontroller.cc b/pc/jseptransportcontroller.cc index 85518aceab..1375ab0e59 100644 --- a/pc/jseptransportcontroller.cc +++ b/pc/jseptransportcontroller.cc @@ -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( - transport_name, component, port_allocator_, config_.event_log); + transport_name, component, port_allocator_, async_resolver_factory_, + config_.event_log); dtls = absl::make_unique(std::move(ice), config_.crypto_options); } diff --git a/pc/jseptransportcontroller.h b/pc/jseptransportcontroller.h index 98e36871fa..c8effd746b 100644 --- a/pc/jseptransportcontroller.h +++ b/pc/jseptransportcontroller.h @@ -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> jsep_transports_by_name_; diff --git a/pc/jseptransportcontroller_unittest.cc b/pc/jseptransportcontroller_unittest.cc index 7bda977da5..6f8693bea7 100644 --- a/pc/jseptransportcontroller_unittest.cc +++ b/pc/jseptransportcontroller_unittest.cc @@ -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( - signaling_thread, network_thread, port_allocator, config); + signaling_thread, network_thread, port_allocator, nullptr, config); ConnectTransportControllerSignals(); } diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc index b66b89419f..5337fae2a4 100644 --- a/pc/peerconnection.cc +++ b/pc/peerconnection.cc @@ -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( diff --git a/pc/peerconnection.h b/pc/peerconnection.h index ac653b11f8..25fbe1fc20 100644 --- a/pc/peerconnection.h +++ b/pc/peerconnection.h @@ -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 async_resolver_factory_; std::unique_ptr port_allocator_; std::unique_ptr tls_cert_verifier_; int port_allocator_flags_ = 0; diff --git a/pc/peerconnectionfactory.cc b/pc/peerconnectionfactory.cc index 4d9455c6ba..d407228e67 100644 --- a/pc/peerconnectionfactory.cc +++ b/pc/peerconnectionfactory.cc @@ -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( RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::SetNetworkIgnoreMask,