Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: net/base/host_resolver_proc.cc

Issue 3231005: Fix remaining localhost resolution issues. (Closed)
Patch Set: Fix mock resolver to ignore network config-induced host resolver flags when using default flags. Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/host_resolver_proc.h" 5 #include "net/base/host_resolver_proc.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #if defined(OS_POSIX) && !defined(OS_MACOSX) 9 #if defined(OS_POSIX) && !defined(OS_MACOSX)
10 #include <resolv.h> 10 #include <resolv.h>
11 #endif 11 #endif
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "net/base/address_list.h" 14 #include "net/base/address_list.h"
15 #include "net/base/dns_reload_timer.h" 15 #include "net/base/dns_reload_timer.h"
16 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
17 #include "net/base/sys_addrinfo.h" 17 #include "net/base/sys_addrinfo.h"
18 18
19 namespace net { 19 namespace net {
20 20
21 namespace {
22
23 bool IsAllLocalhostOfOneFamily(const struct addrinfo* ai) {
24 bool saw_v4_localhost = false;
25 bool saw_v6_localhost = false;
26 for (; ai != NULL; ai = ai->ai_next) {
27 switch (ai->ai_family) {
28 case AF_INET: {
29 const struct sockaddr_in* addr_in =
30 reinterpret_cast<struct sockaddr_in*>(ai->ai_addr);
31 if ((ntohl(addr_in->sin_addr.s_addr) & 0xff000000) == 0x7f000000)
32 saw_v4_localhost = true;
33 else
34 return false;
35 break;
36 }
37 case AF_INET6: {
38 const struct sockaddr_in6* addr_in6 =
39 reinterpret_cast<struct sockaddr_in6*>(ai->ai_addr);
40 if (IN6_IS_ADDR_LOOPBACK(&addr_in6->sin6_addr))
41 saw_v6_localhost = true;
42 else
43 return false;
44 break;
45 }
46 default:
47 NOTREACHED();
48 return false;
49 }
50 }
51
52 return saw_v4_localhost != saw_v6_localhost;
53 }
54
55 } // namespace
56
21 HostResolverProc* HostResolverProc::default_proc_ = NULL; 57 HostResolverProc* HostResolverProc::default_proc_ = NULL;
22 58
23 HostResolverProc::HostResolverProc(HostResolverProc* previous) { 59 HostResolverProc::HostResolverProc(HostResolverProc* previous) {
24 SetPreviousProc(previous); 60 SetPreviousProc(previous);
25 61
26 // Implicitly fall-back to the global default procedure. 62 // Implicitly fall-back to the global default procedure.
27 if (!previous) 63 if (!previous)
28 SetPreviousProc(default_proc_); 64 SetPreviousProc(default_proc_);
29 } 65 }
30 66
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 if (host_resolver_flags & HOST_RESOLVER_LOOPBACK_ONLY) 190 if (host_resolver_flags & HOST_RESOLVER_LOOPBACK_ONLY)
155 hints.ai_flags &= ~AI_ADDRCONFIG; 191 hints.ai_flags &= ~AI_ADDRCONFIG;
156 192
157 if (host_resolver_flags & HOST_RESOLVER_CANONNAME) 193 if (host_resolver_flags & HOST_RESOLVER_CANONNAME)
158 hints.ai_flags |= AI_CANONNAME; 194 hints.ai_flags |= AI_CANONNAME;
159 195
160 // Restrict result set to only this socket type to avoid duplicates. 196 // Restrict result set to only this socket type to avoid duplicates.
161 hints.ai_socktype = SOCK_STREAM; 197 hints.ai_socktype = SOCK_STREAM;
162 198
163 int err = getaddrinfo(host.c_str(), NULL, &hints, &ai); 199 int err = getaddrinfo(host.c_str(), NULL, &hints, &ai);
200 bool should_retry = false;
164 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) 201 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
165 // If we fail, re-initialise the resolver just in case there have been any 202 // If we fail, re-initialise the resolver just in case there have been any
166 // changes to /etc/resolv.conf and retry. See http://crbug.com/11380 for info. 203 // changes to /etc/resolv.conf and retry. See http://crbug.com/11380 for info.
167 if (err && DnsReloadTimerHasExpired()) { 204 if (err && DnsReloadTimerHasExpired()) {
168 res_nclose(&_res); 205 res_nclose(&_res);
169 if (!res_ninit(&_res)) 206 if (!res_ninit(&_res))
170 err = getaddrinfo(host.c_str(), NULL, &hints, &ai); 207 should_retry = true;
171 } 208 }
172 #endif 209 #endif
210 // If the lookup was restricted (either by address family, or address
211 // detection), and the results where all localhost of a single family,
212 // maybe we should retry. There were several bugs related to these
213 // issues, for example http://crbug.com/42058 and http://crbug.com/49024
214 if ((hints.ai_family != AF_UNSPEC || hints.ai_flags & AI_ADDRCONFIG) &&
215 err == 0 && IsAllLocalhostOfOneFamily(ai)) {
willchan no longer on Chromium 2010/09/03 19:36:50 I personally think "err == OK" is more readable, b
vandebo (ex-Chrome) 2010/09/03 19:42:18 err is the result of getaddrinfo, not a chrome net
willchan no longer on Chromium 2010/09/03 20:23:07 Oops, sorry, I thought this was a net::Error. I c
216 if (host_resolver_flags & HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) {
217 hints.ai_family = AF_UNSPEC;
218 should_retry = true;
219 }
220 if (hints.ai_flags & AI_ADDRCONFIG) {
221 hints.ai_flags &= ~AI_ADDRCONFIG;
222 should_retry = true;
223 }
224 }
225 if (should_retry) {
226 freeaddrinfo(ai);
willchan no longer on Chromium 2010/09/03 19:36:50 don't you need a NULL check here? In the line 207
vandebo (ex-Chrome) 2010/09/03 19:42:18 From man 3 free: 'If ptr is NULL, no operation is
willchan no longer on Chromium 2010/09/03 20:23:07 Clearly I haven't done C programming in forever.
227 ai = NULL;
228 err = getaddrinfo(host.c_str(), NULL, &hints, &ai);
229 }
173 230
174 if (err) { 231 if (err) {
175 if (os_error) { 232 if (os_error) {
176 #if defined(OS_WIN) 233 #if defined(OS_WIN)
177 *os_error = WSAGetLastError(); 234 *os_error = WSAGetLastError();
178 #else 235 #else
179 *os_error = err; 236 *os_error = err;
180 #endif 237 #endif
181 } 238 }
182 return ERR_NAME_NOT_RESOLVED; 239 return ERR_NAME_NOT_RESOLVED;
183 } 240 }
184 241
185 addrlist->Adopt(ai); 242 addrlist->Adopt(ai);
186 return OK; 243 return OK;
187 } 244 }
188 245
189 } // namespace net 246 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698