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}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index e50e34d..7271ece 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -48,6 +48,7 @@
   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 0000000..3c3bb1e
--- /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 edac135..0fc2a2b 100644
--- a/api/peerconnectioninterface.h
+++ b/api/peerconnectioninterface.h
@@ -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 @@
   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;
 };
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index 6666c9f..297889d 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -20,6 +20,8 @@
   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 @@
 
     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 0000000..22dac68
--- /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 0000000..29fe6d0
--- /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 0000000..4529d5e
--- /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 11cf412..a2833cd 100644
--- a/p2p/base/p2ptransportchannel.cc
+++ b/p2p/base/p2ptransportchannel.cc
@@ -112,11 +112,19 @@
 
 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 94e88dd..1ac898e 100644
--- a/p2p/base/p2ptransportchannel.h
+++ b/p2p/base/p2ptransportchannel.h
@@ -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 @@
 // 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 @@
   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 85518ac..1375ab0 100644
--- a/pc/jseptransportcontroller.cc
+++ b/pc/jseptransportcontroller.cc
@@ -90,10 +90,12 @@
     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 @@
         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);
   }
diff --git a/pc/jseptransportcontroller.h b/pc/jseptransportcontroller.h
index 98e3687..c8effd7 100644
--- a/pc/jseptransportcontroller.h
+++ b/pc/jseptransportcontroller.h
@@ -87,6 +87,7 @@
   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 @@
   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_;
diff --git a/pc/jseptransportcontroller_unittest.cc b/pc/jseptransportcontroller_unittest.cc
index 7bda977..6f8693b 100644
--- a/pc/jseptransportcontroller_unittest.cc
+++ b/pc/jseptransportcontroller_unittest.cc
@@ -75,8 +75,9 @@
     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();
   }
 
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index b66b894..5337fae 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -907,6 +907,7 @@
   }
 
   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 @@
 #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 ac653b1..25fbe1f 100644
--- a/pc/peerconnection.h
+++ b/pc/peerconnection.h
@@ -938,6 +938,9 @@
   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;
diff --git a/pc/peerconnectionfactory.cc b/pc/peerconnectionfactory.cc
index 4d9455c..d407228 100644
--- a/pc/peerconnectionfactory.cc
+++ b/pc/peerconnectionfactory.cc
@@ -378,6 +378,10 @@
         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,