blob: 7f26a981ee5ea4be076d0c969929d82cc23891da [file] [log] [blame]
Zach Steine20867f2018-08-02 20:20:151/*
2 * Copyright 2018 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton10542f22019-01-11 17:11:0011#include "p2p/base/basic_async_resolver_factory.h"
Zach Steine20867f2018-08-02 20:20:1512
Harald Alvestrande6e2f282021-03-24 12:13:2813#include <memory>
14#include <utility>
15
16#include "absl/memory/memory.h"
17#include "api/async_dns_resolver.h"
Mirko Bonadeie5f4c6b2021-01-15 09:41:0118#include "rtc_base/async_resolver.h"
Harald Alvestrand0ccfbd22021-04-08 07:25:0419#include "rtc_base/logging.h"
Zach Steine20867f2018-08-02 20:20:1520
21namespace webrtc {
22
23rtc::AsyncResolverInterface* BasicAsyncResolverFactory::Create() {
24 return new rtc::AsyncResolver();
25}
26
Harald Alvestrande6e2f282021-03-24 12:13:2827class WrappingAsyncDnsResolver;
28
29class WrappingAsyncDnsResolverResult : public AsyncDnsResolverResult {
30 public:
31 explicit WrappingAsyncDnsResolverResult(WrappingAsyncDnsResolver* owner)
32 : owner_(owner) {}
33 ~WrappingAsyncDnsResolverResult() {}
34
35 // Note: Inline declaration not possible, since it refers to
36 // WrappingAsyncDnsResolver.
37 bool GetResolvedAddress(int family, rtc::SocketAddress* addr) const override;
38 int GetError() const override;
39
40 private:
41 WrappingAsyncDnsResolver* const owner_;
42};
43
44class WrappingAsyncDnsResolver : public AsyncDnsResolverInterface,
45 public sigslot::has_slots<> {
46 public:
47 explicit WrappingAsyncDnsResolver(rtc::AsyncResolverInterface* wrapped)
48 : wrapped_(absl::WrapUnique(wrapped)), result_(this) {}
49
Harald Alvestrand0ccfbd22021-04-08 07:25:0450 ~WrappingAsyncDnsResolver() override {
51 // Workaround to get around the fact that sigslot-using objects can't be
52 // destroyed from within their callback: Alert class users early.
53 // TODO(bugs.webrtc.org/12651): Delete this class once the sigslot users are
54 // gone.
55 RTC_CHECK(!within_resolve_result_);
56 wrapped_.release()->Destroy(false);
57 }
Harald Alvestrande6e2f282021-03-24 12:13:2858
59 void Start(const rtc::SocketAddress& addr,
60 std::function<void()> callback) override {
Harald Alvestrand0ccfbd22021-04-08 07:25:0461 RTC_DCHECK_RUN_ON(&sequence_checker_);
62 RTC_DCHECK_EQ(State::kNotStarted, state_);
Harald Alvestrande6e2f282021-03-24 12:13:2863 state_ = State::kStarted;
64 callback_ = callback;
65 wrapped_->SignalDone.connect(this,
66 &WrappingAsyncDnsResolver::OnResolveResult);
67 wrapped_->Start(addr);
68 }
69
70 const AsyncDnsResolverResult& result() const override {
Harald Alvestrand0ccfbd22021-04-08 07:25:0471 RTC_DCHECK_RUN_ON(&sequence_checker_);
72 RTC_DCHECK_EQ(State::kResolved, state_);
Harald Alvestrande6e2f282021-03-24 12:13:2873 return result_;
74 }
75
Harald Alvestrande6e2f282021-03-24 12:13:2876 private:
77 enum class State { kNotStarted, kStarted, kResolved };
78
Harald Alvestrand0ccfbd22021-04-08 07:25:0479 friend class WrappingAsyncDnsResolverResult;
80 // For use by WrappingAsyncDnsResolverResult
81 rtc::AsyncResolverInterface* wrapped() const {
82 RTC_DCHECK_RUN_ON(&sequence_checker_);
83 return wrapped_.get();
84 }
85
Harald Alvestrande6e2f282021-03-24 12:13:2886 void OnResolveResult(rtc::AsyncResolverInterface* ref) {
Harald Alvestrand0ccfbd22021-04-08 07:25:0487 RTC_DCHECK_RUN_ON(&sequence_checker_);
Harald Alvestrande6e2f282021-03-24 12:13:2888 RTC_DCHECK(state_ == State::kStarted);
89 RTC_DCHECK_EQ(ref, wrapped_.get());
90 state_ = State::kResolved;
Harald Alvestrand0ccfbd22021-04-08 07:25:0491 within_resolve_result_ = true;
Harald Alvestrande6e2f282021-03-24 12:13:2892 callback_();
Harald Alvestrand0ccfbd22021-04-08 07:25:0493 within_resolve_result_ = false;
Harald Alvestrande6e2f282021-03-24 12:13:2894 }
95
Harald Alvestrand0ccfbd22021-04-08 07:25:0496 // The class variables need to be accessed on a single thread.
97 SequenceChecker sequence_checker_;
98 std::function<void()> callback_ RTC_GUARDED_BY(sequence_checker_);
99 std::unique_ptr<rtc::AsyncResolverInterface> wrapped_
100 RTC_GUARDED_BY(sequence_checker_);
101 State state_ RTC_GUARDED_BY(sequence_checker_) = State::kNotStarted;
102 WrappingAsyncDnsResolverResult result_ RTC_GUARDED_BY(sequence_checker_);
103 bool within_resolve_result_ RTC_GUARDED_BY(sequence_checker_) = false;
Harald Alvestrande6e2f282021-03-24 12:13:28104};
105
106bool WrappingAsyncDnsResolverResult::GetResolvedAddress(
107 int family,
108 rtc::SocketAddress* addr) const {
109 if (!owner_->wrapped()) {
110 return false;
111 }
112 return owner_->wrapped()->GetResolvedAddress(family, addr);
113}
114
115int WrappingAsyncDnsResolverResult::GetError() const {
116 if (!owner_->wrapped()) {
117 return -1; // FIXME: Find a code that makes sense.
118 }
119 return owner_->wrapped()->GetError();
120}
121
122std::unique_ptr<webrtc::AsyncDnsResolverInterface>
123WrappingAsyncDnsResolverFactory::Create() {
124 return std::make_unique<WrappingAsyncDnsResolver>(wrapped_factory_->Create());
125}
126
127std::unique_ptr<webrtc::AsyncDnsResolverInterface>
128WrappingAsyncDnsResolverFactory::CreateAndResolve(
129 const rtc::SocketAddress& addr,
130 std::function<void()> callback) {
131 std::unique_ptr<webrtc::AsyncDnsResolverInterface> resolver = Create();
132 resolver->Start(addr, callback);
133 return resolver;
134}
135
Zach Steine20867f2018-08-02 20:20:15136} // namespace webrtc