Add CreateAsyncDnsResolver to PacketSocketFactory API

This unlocks migration from AsyncResolver to AsyncDnsResolver for
clients that implement PacketSocketFactory.

A default implementation is provided, so that clients that implement
CreateAsyncResolver will still see their name resolution work.

Bug: webrtc:12598
Change-Id: If835cbc753712e9f5b4bd3d5805c7f7d2a561ee5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/233500
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Markus Handell <handellm@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35131}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 376c83f..e969fec 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -255,6 +255,7 @@
   ]
   deps = [
     ":async_dns_resolver",
+    ":wrapping_async_dns_resolver",
     "../rtc_base:async_resolver_interface",
     "../rtc_base:rtc_base",
     "../rtc_base:socket_address",
@@ -271,6 +272,28 @@
   ]
 }
 
+rtc_source_set("wrapping_async_dns_resolver") {
+  visibility = [
+    ":*",
+    "../p2p:rtc_p2p",
+  ]
+  sources = [
+    "wrapping_async_dns_resolver.cc",
+    "wrapping_async_dns_resolver.h",
+  ]
+  deps = [
+    ":async_dns_resolver",
+    ":sequence_checker",
+    "../rtc_base:async_resolver_interface",
+    "../rtc_base:checks",
+    "../rtc_base:macromagic",
+    "../rtc_base:socket_address",
+    "../rtc_base:threading",
+    "../rtc_base/third_party/sigslot",
+  ]
+  absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
+}
+
 rtc_source_set("scoped_refptr") {
   visibility = [ "*" ]
   sources = [ "scoped_refptr.h" ]
diff --git a/api/DEPS b/api/DEPS
index d201a44..cadaaa2 100644
--- a/api/DEPS
+++ b/api/DEPS
@@ -305,6 +305,14 @@
     "+rtc_base/thread_annotations.h",
   ],
 
+  "wrapping_async_dns_resolver\.h": [
+    "+rtc_base/async_resolver.h",
+    "+rtc_base/async_resolver_interface.h",
+    "+rtc_base/socket_address.h",
+    "+rtc_base/third_party/sigslot/sigslot.h",
+    "+rtc_base/thread_annotations.h",
+  ],
+
   # .cc files in api/ should not be restricted in what they can #include,
   # so we re-add all the top-level directories here. (That's because .h
   # files leak their #includes to whoever's #including them, but .cc files
diff --git a/api/packet_socket_factory.h b/api/packet_socket_factory.h
index 1e9f470..79f48f2 100644
--- a/api/packet_socket_factory.h
+++ b/api/packet_socket_factory.h
@@ -11,9 +11,12 @@
 #ifndef API_PACKET_SOCKET_FACTORY_H_
 #define API_PACKET_SOCKET_FACTORY_H_
 
+#include <memory>
 #include <string>
 #include <vector>
 
+#include "api/async_dns_resolver.h"
+#include "api/wrapping_async_dns_resolver.h"
 #include "rtc_base/async_packet_socket.h"
 #include "rtc_base/proxy_info.h"
 #include "rtc_base/system/rtc_export.h"
@@ -69,7 +72,23 @@
       const std::string& user_agent,
       const PacketSocketTcpOptions& tcp_options) = 0;
 
-  virtual AsyncResolverInterface* CreateAsyncResolver() = 0;
+  // The AsyncResolverInterface is deprecated; users are encouraged
+  // to switch to the AsyncDnsResolverInterface.
+  // TODO(bugs.webrtc.org/12598): Remove once all downstream users
+  // are converted.
+  virtual AsyncResolverInterface* CreateAsyncResolver() {
+    // Default implementation, so that downstream users can remove this
+    // immediately after changing to CreateAsyncDnsResolver
+    RTC_NOTREACHED();
+    return nullptr;
+  }
+
+  virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface>
+  CreateAsyncDnsResolver() {
+    // Default implementation, to aid in transition to AsyncDnsResolverInterface
+    return std::make_unique<webrtc::WrappingAsyncDnsResolver>(
+        CreateAsyncResolver());
+  }
 
  private:
   PacketSocketFactory(const PacketSocketFactory&) = delete;
diff --git a/api/wrapping_async_dns_resolver.cc b/api/wrapping_async_dns_resolver.cc
new file mode 100644
index 0000000..866cb00
--- /dev/null
+++ b/api/wrapping_async_dns_resolver.cc
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 2021 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/wrapping_async_dns_resolver.h"
+
+namespace webrtc {
+
+bool WrappingAsyncDnsResolverResult::GetResolvedAddress(
+    int family,
+    rtc::SocketAddress* addr) const {
+  if (!owner_->wrapped()) {
+    return false;
+  }
+  return owner_->wrapped()->GetResolvedAddress(family, addr);
+}
+
+int WrappingAsyncDnsResolverResult::GetError() const {
+  if (!owner_->wrapped()) {
+    return -1;  // FIXME: Find a code that makes sense.
+  }
+  return owner_->wrapped()->GetError();
+}
+
+}  // namespace webrtc
diff --git a/api/wrapping_async_dns_resolver.h b/api/wrapping_async_dns_resolver.h
new file mode 100644
index 0000000..80da206
--- /dev/null
+++ b/api/wrapping_async_dns_resolver.h
@@ -0,0 +1,117 @@
+/*
+ *  Copyright 2021 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_WRAPPING_ASYNC_DNS_RESOLVER_H_
+#define API_WRAPPING_ASYNC_DNS_RESOLVER_H_
+
+#include <functional>
+#include <memory>
+
+#include "absl/memory/memory.h"
+#include "api/async_dns_resolver.h"
+#include "api/sequence_checker.h"
+#include "rtc_base/async_resolver.h"
+#include "rtc_base/async_resolver_interface.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/socket_address.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
+#include "rtc_base/thread_annotations.h"
+
+// This file defines a DNS resolver that wraps an old-style
+// AsyncResolver.
+// It is part of the conversion to the newer interface, and will go away
+// once conversion is finished.
+// TODO(bugs.webrtc.org/12598): Delete this API.
+
+namespace webrtc {
+
+class WrappingAsyncDnsResolver;
+
+class RTC_EXPORT WrappingAsyncDnsResolverResult
+    : public AsyncDnsResolverResult {
+ public:
+  explicit WrappingAsyncDnsResolverResult(WrappingAsyncDnsResolver* owner)
+      : owner_(owner) {}
+  ~WrappingAsyncDnsResolverResult() {}
+
+  // Note: Inline declaration not possible, since it refers to
+  // WrappingAsyncDnsResolver.
+  bool GetResolvedAddress(int family, rtc::SocketAddress* addr) const override;
+  int GetError() const override;
+
+ private:
+  WrappingAsyncDnsResolver* const owner_;
+};
+
+class RTC_EXPORT WrappingAsyncDnsResolver : public AsyncDnsResolverInterface,
+                                            public sigslot::has_slots<> {
+ public:
+  explicit WrappingAsyncDnsResolver(rtc::AsyncResolverInterface* wrapped)
+      : wrapped_(absl::WrapUnique(wrapped)), result_(this) {}
+
+  ~WrappingAsyncDnsResolver() override {
+    // Workaround to get around the fact that sigslot-using objects can't be
+    // destroyed from within their callback: Alert class users early.
+    // TODO(bugs.webrtc.org/12651): Delete this class once the sigslot users are
+    // gone.
+    RTC_CHECK(!within_resolve_result_);
+    wrapped_.release()->Destroy(false);
+  }
+
+  void Start(const rtc::SocketAddress& addr,
+             std::function<void()> callback) override {
+    RTC_DCHECK_RUN_ON(&sequence_checker_);
+    RTC_DCHECK_EQ(State::kNotStarted, state_);
+    state_ = State::kStarted;
+    callback_ = callback;
+    wrapped_->SignalDone.connect(this,
+                                 &WrappingAsyncDnsResolver::OnResolveResult);
+    wrapped_->Start(addr);
+  }
+
+  const AsyncDnsResolverResult& result() const override {
+    RTC_DCHECK_RUN_ON(&sequence_checker_);
+    RTC_DCHECK_EQ(State::kResolved, state_);
+    return result_;
+  }
+
+ private:
+  enum class State { kNotStarted, kStarted, kResolved };
+
+  friend class WrappingAsyncDnsResolverResult;
+  // For use by WrappingAsyncDnsResolverResult
+  rtc::AsyncResolverInterface* wrapped() const {
+    RTC_DCHECK_RUN_ON(&sequence_checker_);
+    return wrapped_.get();
+  }
+
+  void OnResolveResult(rtc::AsyncResolverInterface* ref) {
+    RTC_DCHECK_RUN_ON(&sequence_checker_);
+    RTC_DCHECK(state_ == State::kStarted);
+    RTC_DCHECK_EQ(ref, wrapped_.get());
+    state_ = State::kResolved;
+    within_resolve_result_ = true;
+    callback_();
+    within_resolve_result_ = false;
+  }
+
+  // The class variables need to be accessed on a single thread.
+  SequenceChecker sequence_checker_;
+  std::function<void()> callback_ RTC_GUARDED_BY(sequence_checker_);
+  std::unique_ptr<rtc::AsyncResolverInterface> wrapped_
+      RTC_GUARDED_BY(sequence_checker_);
+  State state_ RTC_GUARDED_BY(sequence_checker_) = State::kNotStarted;
+  WrappingAsyncDnsResolverResult result_ RTC_GUARDED_BY(sequence_checker_);
+  bool within_resolve_result_ RTC_GUARDED_BY(sequence_checker_) = false;
+};
+
+}  // namespace webrtc
+
+#endif  // API_WRAPPING_ASYNC_DNS_RESOLVER_H_
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index f885694..3029e0a 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -91,6 +91,7 @@
     "../api:rtc_error",
     "../api:scoped_refptr",
     "../api:sequence_checker",
+    "../api:wrapping_async_dns_resolver",
     "../api/crypto:options",
     "../api/rtc_event_log",
     "../api/task_queue",
diff --git a/p2p/base/basic_async_resolver_factory.cc b/p2p/base/basic_async_resolver_factory.cc
index 7f26a98..6824357 100644
--- a/p2p/base/basic_async_resolver_factory.cc
+++ b/p2p/base/basic_async_resolver_factory.cc
@@ -15,6 +15,7 @@
 
 #include "absl/memory/memory.h"
 #include "api/async_dns_resolver.h"
+#include "api/wrapping_async_dns_resolver.h"
 #include "rtc_base/async_resolver.h"
 #include "rtc_base/logging.h"
 
@@ -24,100 +25,6 @@
   return new rtc::AsyncResolver();
 }
 
-class WrappingAsyncDnsResolver;
-
-class WrappingAsyncDnsResolverResult : public AsyncDnsResolverResult {
- public:
-  explicit WrappingAsyncDnsResolverResult(WrappingAsyncDnsResolver* owner)
-      : owner_(owner) {}
-  ~WrappingAsyncDnsResolverResult() {}
-
-  // Note: Inline declaration not possible, since it refers to
-  // WrappingAsyncDnsResolver.
-  bool GetResolvedAddress(int family, rtc::SocketAddress* addr) const override;
-  int GetError() const override;
-
- private:
-  WrappingAsyncDnsResolver* const owner_;
-};
-
-class WrappingAsyncDnsResolver : public AsyncDnsResolverInterface,
-                                 public sigslot::has_slots<> {
- public:
-  explicit WrappingAsyncDnsResolver(rtc::AsyncResolverInterface* wrapped)
-      : wrapped_(absl::WrapUnique(wrapped)), result_(this) {}
-
-  ~WrappingAsyncDnsResolver() override {
-    // Workaround to get around the fact that sigslot-using objects can't be
-    // destroyed from within their callback: Alert class users early.
-    // TODO(bugs.webrtc.org/12651): Delete this class once the sigslot users are
-    // gone.
-    RTC_CHECK(!within_resolve_result_);
-    wrapped_.release()->Destroy(false);
-  }
-
-  void Start(const rtc::SocketAddress& addr,
-             std::function<void()> callback) override {
-    RTC_DCHECK_RUN_ON(&sequence_checker_);
-    RTC_DCHECK_EQ(State::kNotStarted, state_);
-    state_ = State::kStarted;
-    callback_ = callback;
-    wrapped_->SignalDone.connect(this,
-                                 &WrappingAsyncDnsResolver::OnResolveResult);
-    wrapped_->Start(addr);
-  }
-
-  const AsyncDnsResolverResult& result() const override {
-    RTC_DCHECK_RUN_ON(&sequence_checker_);
-    RTC_DCHECK_EQ(State::kResolved, state_);
-    return result_;
-  }
-
- private:
-  enum class State { kNotStarted, kStarted, kResolved };
-
-  friend class WrappingAsyncDnsResolverResult;
-  // For use by WrappingAsyncDnsResolverResult
-  rtc::AsyncResolverInterface* wrapped() const {
-    RTC_DCHECK_RUN_ON(&sequence_checker_);
-    return wrapped_.get();
-  }
-
-  void OnResolveResult(rtc::AsyncResolverInterface* ref) {
-    RTC_DCHECK_RUN_ON(&sequence_checker_);
-    RTC_DCHECK(state_ == State::kStarted);
-    RTC_DCHECK_EQ(ref, wrapped_.get());
-    state_ = State::kResolved;
-    within_resolve_result_ = true;
-    callback_();
-    within_resolve_result_ = false;
-  }
-
-  // The class variables need to be accessed on a single thread.
-  SequenceChecker sequence_checker_;
-  std::function<void()> callback_ RTC_GUARDED_BY(sequence_checker_);
-  std::unique_ptr<rtc::AsyncResolverInterface> wrapped_
-      RTC_GUARDED_BY(sequence_checker_);
-  State state_ RTC_GUARDED_BY(sequence_checker_) = State::kNotStarted;
-  WrappingAsyncDnsResolverResult result_ RTC_GUARDED_BY(sequence_checker_);
-  bool within_resolve_result_ RTC_GUARDED_BY(sequence_checker_) = false;
-};
-
-bool WrappingAsyncDnsResolverResult::GetResolvedAddress(
-    int family,
-    rtc::SocketAddress* addr) const {
-  if (!owner_->wrapped()) {
-    return false;
-  }
-  return owner_->wrapped()->GetResolvedAddress(family, addr);
-}
-
-int WrappingAsyncDnsResolverResult::GetError() const {
-  if (!owner_->wrapped()) {
-    return -1;  // FIXME: Find a code that makes sense.
-  }
-  return owner_->wrapped()->GetError();
-}
 
 std::unique_ptr<webrtc::AsyncDnsResolverInterface>
 WrappingAsyncDnsResolverFactory::Create() {