blob: 80da206e75d5309b455503ba413baf0dc109dbe4 [file] [log] [blame]
Harald Alvestrand985310e2021-10-01 15:11:17 +00001/*
2 * Copyright 2021 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
11#ifndef API_WRAPPING_ASYNC_DNS_RESOLVER_H_
12#define API_WRAPPING_ASYNC_DNS_RESOLVER_H_
13
14#include <functional>
15#include <memory>
16
17#include "absl/memory/memory.h"
18#include "api/async_dns_resolver.h"
19#include "api/sequence_checker.h"
20#include "rtc_base/async_resolver.h"
21#include "rtc_base/async_resolver_interface.h"
22#include "rtc_base/checks.h"
23#include "rtc_base/socket_address.h"
24#include "rtc_base/third_party/sigslot/sigslot.h"
25#include "rtc_base/thread_annotations.h"
26
27// This file defines a DNS resolver that wraps an old-style
28// AsyncResolver.
29// It is part of the conversion to the newer interface, and will go away
30// once conversion is finished.
31// TODO(bugs.webrtc.org/12598): Delete this API.
32
33namespace webrtc {
34
35class WrappingAsyncDnsResolver;
36
37class RTC_EXPORT WrappingAsyncDnsResolverResult
38 : public AsyncDnsResolverResult {
39 public:
40 explicit WrappingAsyncDnsResolverResult(WrappingAsyncDnsResolver* owner)
41 : owner_(owner) {}
42 ~WrappingAsyncDnsResolverResult() {}
43
44 // Note: Inline declaration not possible, since it refers to
45 // WrappingAsyncDnsResolver.
46 bool GetResolvedAddress(int family, rtc::SocketAddress* addr) const override;
47 int GetError() const override;
48
49 private:
50 WrappingAsyncDnsResolver* const owner_;
51};
52
53class RTC_EXPORT WrappingAsyncDnsResolver : public AsyncDnsResolverInterface,
54 public sigslot::has_slots<> {
55 public:
56 explicit WrappingAsyncDnsResolver(rtc::AsyncResolverInterface* wrapped)
57 : wrapped_(absl::WrapUnique(wrapped)), result_(this) {}
58
59 ~WrappingAsyncDnsResolver() override {
60 // Workaround to get around the fact that sigslot-using objects can't be
61 // destroyed from within their callback: Alert class users early.
62 // TODO(bugs.webrtc.org/12651): Delete this class once the sigslot users are
63 // gone.
64 RTC_CHECK(!within_resolve_result_);
65 wrapped_.release()->Destroy(false);
66 }
67
68 void Start(const rtc::SocketAddress& addr,
69 std::function<void()> callback) override {
70 RTC_DCHECK_RUN_ON(&sequence_checker_);
71 RTC_DCHECK_EQ(State::kNotStarted, state_);
72 state_ = State::kStarted;
73 callback_ = callback;
74 wrapped_->SignalDone.connect(this,
75 &WrappingAsyncDnsResolver::OnResolveResult);
76 wrapped_->Start(addr);
77 }
78
79 const AsyncDnsResolverResult& result() const override {
80 RTC_DCHECK_RUN_ON(&sequence_checker_);
81 RTC_DCHECK_EQ(State::kResolved, state_);
82 return result_;
83 }
84
85 private:
86 enum class State { kNotStarted, kStarted, kResolved };
87
88 friend class WrappingAsyncDnsResolverResult;
89 // For use by WrappingAsyncDnsResolverResult
90 rtc::AsyncResolverInterface* wrapped() const {
91 RTC_DCHECK_RUN_ON(&sequence_checker_);
92 return wrapped_.get();
93 }
94
95 void OnResolveResult(rtc::AsyncResolverInterface* ref) {
96 RTC_DCHECK_RUN_ON(&sequence_checker_);
97 RTC_DCHECK(state_ == State::kStarted);
98 RTC_DCHECK_EQ(ref, wrapped_.get());
99 state_ = State::kResolved;
100 within_resolve_result_ = true;
101 callback_();
102 within_resolve_result_ = false;
103 }
104
105 // The class variables need to be accessed on a single thread.
106 SequenceChecker sequence_checker_;
107 std::function<void()> callback_ RTC_GUARDED_BY(sequence_checker_);
108 std::unique_ptr<rtc::AsyncResolverInterface> wrapped_
109 RTC_GUARDED_BY(sequence_checker_);
110 State state_ RTC_GUARDED_BY(sequence_checker_) = State::kNotStarted;
111 WrappingAsyncDnsResolverResult result_ RTC_GUARDED_BY(sequence_checker_);
112 bool within_resolve_result_ RTC_GUARDED_BY(sequence_checker_) = false;
113};
114
115} // namespace webrtc
116
117#endif // API_WRAPPING_ASYNC_DNS_RESOLVER_H_