Add a new API to DNS resolution
This API should allow existing factories to be used unmodified, but
offers a new API that documents ownership better and does not use
sigslot.
Bug: webrtc:12598
Change-Id: I0f68371059cd4a18ab07b87fc0e7526dcc0ac669
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/212609
Reviewed-by: Tommi <tommi@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33553}
diff --git a/p2p/base/basic_async_resolver_factory.cc b/p2p/base/basic_async_resolver_factory.cc
index 027358b..67dd18f 100644
--- a/p2p/base/basic_async_resolver_factory.cc
+++ b/p2p/base/basic_async_resolver_factory.cc
@@ -10,6 +10,11 @@
#include "p2p/base/basic_async_resolver_factory.h"
+#include <memory>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "api/async_dns_resolver.h"
#include "rtc_base/async_resolver.h"
namespace webrtc {
@@ -18,4 +23,93 @@
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 { wrapped_.release()->Destroy(false); }
+
+ void Start(const rtc::SocketAddress& addr,
+ std::function<void()> callback) override {
+ RTC_DCHECK(state_ == State::kNotStarted);
+ state_ = State::kStarted;
+ callback_ = callback;
+ wrapped_->SignalDone.connect(this,
+ &WrappingAsyncDnsResolver::OnResolveResult);
+ wrapped_->Start(addr);
+ }
+
+ const AsyncDnsResolverResult& result() const override {
+ RTC_DCHECK(state_ == State::kResolved);
+ return result_;
+ }
+
+ // For use by WrappingAsyncDnsResolverResult
+ rtc::AsyncResolverInterface* wrapped() const { return wrapped_.get(); }
+
+ private:
+ enum class State { kNotStarted, kStarted, kResolved };
+
+ void OnResolveResult(rtc::AsyncResolverInterface* ref) {
+ RTC_DCHECK(state_ == State::kStarted);
+ RTC_DCHECK_EQ(ref, wrapped_.get());
+ state_ = State::kResolved;
+ callback_();
+ }
+
+ std::function<void()> callback_;
+ std::unique_ptr<rtc::AsyncResolverInterface> wrapped_;
+ State state_ = State::kNotStarted;
+ WrappingAsyncDnsResolverResult result_;
+};
+
+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() {
+ return std::make_unique<WrappingAsyncDnsResolver>(wrapped_factory_->Create());
+}
+
+std::unique_ptr<webrtc::AsyncDnsResolverInterface>
+WrappingAsyncDnsResolverFactory::CreateAndResolve(
+ const rtc::SocketAddress& addr,
+ std::function<void()> callback) {
+ std::unique_ptr<webrtc::AsyncDnsResolverInterface> resolver = Create();
+ resolver->Start(addr, callback);
+ return resolver;
+}
+
} // namespace webrtc