// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/dns/host_resolver_proc.h" #include #include "base/check.h" #include "base/memory/scoped_refptr.h" #include "base/notreached.h" #include "build/build_config.h" #include "net/base/address_family.h" #include "net/base/address_list.h" #include "net/base/net_errors.h" #include "net/dns/host_resolver_system_task.h" #if BUILDFLAG(IS_OPENBSD) #define AI_ADDRCONFIG 0 #endif namespace net { HostResolverProc* HostResolverProc::default_proc_ = nullptr; HostResolverProc::HostResolverProc(scoped_refptr previous, bool allow_fallback_to_system_or_default) : allow_fallback_to_system_(allow_fallback_to_system_or_default) { SetPreviousProc(previous); // Implicitly fall-back to the global default procedure. if (!previous && allow_fallback_to_system_or_default) SetPreviousProc(default_proc_); } HostResolverProc::~HostResolverProc() = default; int HostResolverProc::Resolve(const std::string& host, AddressFamily address_family, HostResolverFlags host_resolver_flags, AddressList* addrlist, int* os_error, handles::NetworkHandle network) { if (network == handles::kInvalidNetworkHandle) return Resolve(host, address_family, host_resolver_flags, addrlist, os_error); NOTIMPLEMENTED(); return ERR_NOT_IMPLEMENTED; } int HostResolverProc::ResolveUsingPrevious( const std::string& host, AddressFamily address_family, HostResolverFlags host_resolver_flags, AddressList* addrlist, int* os_error) { if (previous_proc_.get()) { return previous_proc_->Resolve( host, address_family, host_resolver_flags, addrlist, os_error); } // If `allow_fallback_to_system_` is false there is no final fallback. It must // be ensured that the Procs can handle any allowed requests. If this check // fails while using MockHostResolver or RuleBasedHostResolverProc, it means // none of the configured rules matched a host resolution request. CHECK(allow_fallback_to_system_); // Final fallback is the system resolver. return SystemHostResolverCall(host, address_family, host_resolver_flags, addrlist, os_error); } void HostResolverProc::SetPreviousProc(scoped_refptr proc) { auto current_previous = std::move(previous_proc_); // Now that we've guaranteed |this| is the last proc in a chain, we can // detect potential cycles using GetLastProc(). previous_proc_ = (GetLastProc(proc.get()) == this) ? std::move(current_previous) : std::move(proc); } void HostResolverProc::SetLastProc(scoped_refptr proc) { GetLastProc(this)->SetPreviousProc(std::move(proc)); } // static HostResolverProc* HostResolverProc::GetLastProc(HostResolverProc* proc) { if (proc == nullptr) return nullptr; HostResolverProc* last_proc = proc; while (last_proc->previous_proc_.get() != nullptr) last_proc = last_proc->previous_proc_.get(); return last_proc; } // static HostResolverProc* HostResolverProc::SetDefault(HostResolverProc* proc) { HostResolverProc* old = default_proc_; default_proc_ = proc; return old; } // static HostResolverProc* HostResolverProc::GetDefault() { return default_proc_; } } // namespace net