1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dns/host_resolver_proc.h"
6
7 #include <tuple>
8
9 #include "base/check.h"
10 #include "base/memory/scoped_refptr.h"
11 #include "base/notreached.h"
12 #include "build/build_config.h"
13 #include "net/base/address_family.h"
14 #include "net/base/address_list.h"
15 #include "net/base/net_errors.h"
16 #include "net/dns/host_resolver_system_task.h"
17
18 #if BUILDFLAG(IS_OPENBSD)
19 #define AI_ADDRCONFIG 0
20 #endif
21
22 namespace net {
23
24 HostResolverProc* HostResolverProc::default_proc_ = nullptr;
25
HostResolverProc(scoped_refptr<HostResolverProc> previous,bool allow_fallback_to_system_or_default)26 HostResolverProc::HostResolverProc(scoped_refptr<HostResolverProc> previous,
27 bool allow_fallback_to_system_or_default)
28 : allow_fallback_to_system_(allow_fallback_to_system_or_default) {
29 SetPreviousProc(previous);
30
31 // Implicitly fall-back to the global default procedure.
32 if (!previous && allow_fallback_to_system_or_default)
33 SetPreviousProc(default_proc_);
34 }
35
36 HostResolverProc::~HostResolverProc() = default;
37
Resolve(const std::string & host,AddressFamily address_family,HostResolverFlags host_resolver_flags,AddressList * addrlist,int * os_error,handles::NetworkHandle network)38 int HostResolverProc::Resolve(const std::string& host,
39 AddressFamily address_family,
40 HostResolverFlags host_resolver_flags,
41 AddressList* addrlist,
42 int* os_error,
43 handles::NetworkHandle network) {
44 if (network == handles::kInvalidNetworkHandle)
45 return Resolve(host, address_family, host_resolver_flags, addrlist,
46 os_error);
47
48 NOTIMPLEMENTED();
49 return ERR_NOT_IMPLEMENTED;
50 }
51
ResolveUsingPrevious(const std::string & host,AddressFamily address_family,HostResolverFlags host_resolver_flags,AddressList * addrlist,int * os_error)52 int HostResolverProc::ResolveUsingPrevious(
53 const std::string& host,
54 AddressFamily address_family,
55 HostResolverFlags host_resolver_flags,
56 AddressList* addrlist,
57 int* os_error) {
58 if (previous_proc_.get()) {
59 return previous_proc_->Resolve(
60 host, address_family, host_resolver_flags, addrlist, os_error);
61 }
62
63 // If `allow_fallback_to_system_` is false there is no final fallback. It must
64 // be ensured that the Procs can handle any allowed requests. If this check
65 // fails while using MockHostResolver or RuleBasedHostResolverProc, it means
66 // none of the configured rules matched a host resolution request.
67 CHECK(allow_fallback_to_system_);
68
69 // Final fallback is the system resolver.
70 return SystemHostResolverCall(host, address_family, host_resolver_flags,
71 addrlist, os_error);
72 }
73
SetPreviousProc(scoped_refptr<HostResolverProc> proc)74 void HostResolverProc::SetPreviousProc(scoped_refptr<HostResolverProc> proc) {
75 auto current_previous = std::move(previous_proc_);
76 // Now that we've guaranteed |this| is the last proc in a chain, we can
77 // detect potential cycles using GetLastProc().
78 previous_proc_ = (GetLastProc(proc.get()) == this)
79 ? std::move(current_previous)
80 : std::move(proc);
81 }
82
SetLastProc(scoped_refptr<HostResolverProc> proc)83 void HostResolverProc::SetLastProc(scoped_refptr<HostResolverProc> proc) {
84 GetLastProc(this)->SetPreviousProc(std::move(proc));
85 }
86
87 // static
GetLastProc(HostResolverProc * proc)88 HostResolverProc* HostResolverProc::GetLastProc(HostResolverProc* proc) {
89 if (proc == nullptr)
90 return nullptr;
91 HostResolverProc* last_proc = proc;
92 while (last_proc->previous_proc_.get() != nullptr)
93 last_proc = last_proc->previous_proc_.get();
94 return last_proc;
95 }
96
97 // static
SetDefault(HostResolverProc * proc)98 HostResolverProc* HostResolverProc::SetDefault(HostResolverProc* proc) {
99 HostResolverProc* old = default_proc_;
100 default_proc_ = proc;
101 return old;
102 }
103
104 // static
GetDefault()105 HostResolverProc* HostResolverProc::GetDefault() {
106 return default_proc_;
107 }
108
109 } // namespace net
110