host_resolver_proc.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/host_resolver_proc.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_byteorder.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/dns_reloader.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/sys_addrinfo.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_OPENBSD) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AI_ADDRCONFIG 0 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsAllLocalhostOfOneFamily(const struct addrinfo* ai) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool saw_v4_localhost = false; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool saw_v6_localhost = false; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; ai != NULL; ai = ai->ai_next) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (ai->ai_family) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AF_INET: { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in* addr_in = 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<struct sockaddr_in*>(ai->ai_addr); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((base::NetToHost32(addr_in->sin_addr.s_addr) & 0xff000000) == 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x7f000000) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saw_v4_localhost = true; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AF_INET6: { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in6* addr_in6 = 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<struct sockaddr_in6*>(ai->ai_addr); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IN6_IS_ADDR_LOOPBACK(&addr_in6->sin6_addr)) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saw_v6_localhost = true; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return saw_v4_localhost != saw_v6_localhost; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostResolverProc* HostResolverProc::default_proc_ = NULL; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostResolverProc::HostResolverProc(HostResolverProc* previous) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPreviousProc(previous); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Implicitly fall-back to the global default procedure. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!previous) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPreviousProc(default_proc_); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostResolverProc::~HostResolverProc() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HostResolverProc::ResolveUsingPrevious( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& host, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressFamily address_family, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolverFlags host_resolver_flags, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList* addrlist, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* os_error) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (previous_proc_) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return previous_proc_->Resolve(host, address_family, host_resolver_flags, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrlist, os_error); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Final fallback is the system resolver. 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SystemHostResolverCall(host, address_family, host_resolver_flags, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrlist, os_error); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostResolverProc::SetPreviousProc(HostResolverProc* proc) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolverProc* current_previous = previous_proc_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_proc_ = NULL; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now that we've guaranteed |this| is the last proc in a chain, we can 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detect potential cycles using GetLastProc(). 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_proc_ = (GetLastProc(proc) == this) ? current_previous : proc; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostResolverProc::SetLastProc(HostResolverProc* proc) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLastProc(this)->SetPreviousProc(proc); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostResolverProc* HostResolverProc::GetLastProc(HostResolverProc* proc) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proc == NULL) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolverProc* last_proc = proc; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (last_proc->previous_proc_ != NULL) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_proc = last_proc->previous_proc_; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return last_proc; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostResolverProc* HostResolverProc::SetDefault(HostResolverProc* proc) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolverProc* old = default_proc_; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_proc_ = proc; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return old; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostResolverProc* HostResolverProc::GetDefault() { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return default_proc_; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int SystemHostResolverCall(const std::string& host, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressFamily address_family, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolverFlags host_resolver_flags, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList* addrlist, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* os_error) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (os_error) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os_error = 0; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct addrinfo* ai = NULL; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct addrinfo hints = {0}; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (address_family) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ADDRESS_FAMILY_IPV4: 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_family = AF_INET; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ADDRESS_FAMILY_IPV6: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_family = AF_INET6; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ADDRESS_FAMILY_UNSPECIFIED: 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_family = AF_UNSPEC; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_family = AF_UNSPEC; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DO NOT USE AI_ADDRCONFIG ON WINDOWS. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The following comment in <winsock2.h> is the best documentation I found 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on AI_ADDRCONFIG for Windows: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flags used in "hints" argument to getaddrinfo() 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - AI_ADDRCONFIG is supported starting with Vista 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - default is AI_ADDRCONFIG ON whether the flag is set or not 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because the performance penalty in not having ADDRCONFIG in 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the multi-protocol stack environment is severe; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this defaulting may be disabled by specifying the AI_ALL flag, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in that case AI_ADDRCONFIG must be EXPLICITLY specified to 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enable ADDRCONFIG behavior 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not only is AI_ADDRCONFIG unnecessary, but it can be harmful. If the 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // computer is not connected to a network, AI_ADDRCONFIG causes getaddrinfo 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to fail with WSANO_DATA (11004) for "localhost", probably because of the 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // following note on AI_ADDRCONFIG in the MSDN getaddrinfo page: 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The IPv4 or IPv6 loopback address is not considered a valid global 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // address. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://crbug.com/5234. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OpenBSD does not support it, either. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_flags = 0; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_flags = AI_ADDRCONFIG; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Linux AI_ADDRCONFIG doesn't consider loopback addreses, even if only 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loopback addresses are configured. So don't use it when there are only 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loopback addresses. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_resolver_flags & HOST_RESOLVER_LOOPBACK_ONLY) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_flags &= ~AI_ADDRCONFIG; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_resolver_flags & HOST_RESOLVER_CANONNAME) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_flags |= AI_CANONNAME; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restrict result set to only this socket type to avoid duplicates. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_socktype = SOCK_STREAM; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !defined(OS_ANDROID) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DnsReloaderMaybeReload(); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err = getaddrinfo(host.c_str(), NULL, &hints, &ai); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool should_retry = false; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the lookup was restricted (either by address family, or address 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detection), and the results where all localhost of a single family, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // maybe we should retry. There were several bugs related to these 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // issues, for example http://crbug.com/42058 and http://crbug.com/49024 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((hints.ai_family != AF_UNSPEC || hints.ai_flags & AI_ADDRCONFIG) && 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err == 0 && IsAllLocalhostOfOneFamily(ai)) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_resolver_flags & HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_family = AF_UNSPEC; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_retry = true; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hints.ai_flags & AI_ADDRCONFIG) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_flags &= ~AI_ADDRCONFIG; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_retry = true; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_retry) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ai != NULL) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freeaddrinfo(ai); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ai = NULL; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = getaddrinfo(host.c_str(), NULL, &hints, &ai); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = WSAGetLastError(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return the OS error to the caller. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (os_error) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os_error = err; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the call to getaddrinfo() failed because of a system error, report 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it separately from ERR_NAME_NOT_RESOLVED. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err != WSAHOST_NOT_FOUND && err != WSANO_DATA) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_NAME_RESOLUTION_FAILED; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_FREEBSD) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err != EAI_NONAME && err != EAI_NODATA) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_NAME_RESOLUTION_FAILED; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_NAME_NOT_RESOLVED; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Workaround for Android's getaddrinfo leaving ai==NULL without an error. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/134142 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ai == NULL) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_NAME_NOT_RESOLVED; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *addrlist = AddressList::CreateFromAddrinfo(ai); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freeaddrinfo(ai); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SystemHostResolverProc::SystemHostResolverProc() : HostResolverProc(NULL) {} 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int SystemHostResolverProc::Resolve(const std::string& hostname, 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AddressFamily address_family, 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HostResolverFlags host_resolver_flags, 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AddressList* addr_list, 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int* os_error) { 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SystemHostResolverCall(hostname, 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_family, 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) host_resolver_flags, 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) addr_list, 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) os_error); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SystemHostResolverProc::~SystemHostResolverProc() {} 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 268