OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/dns/host_resolver_impl.h" | 5 #include "net/dns/host_resolver_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 std::map<ResolveKey, AddressList> rules_; | 170 std::map<ResolveKey, AddressList> rules_; |
171 CaptureList capture_list_; | 171 CaptureList capture_list_; |
172 unsigned num_requests_waiting_; | 172 unsigned num_requests_waiting_; |
173 unsigned num_slots_available_; | 173 unsigned num_slots_available_; |
174 base::ConditionVariable requests_waiting_; | 174 base::ConditionVariable requests_waiting_; |
175 base::ConditionVariable slots_available_; | 175 base::ConditionVariable slots_available_; |
176 | 176 |
177 DISALLOW_COPY_AND_ASSIGN(MockHostResolverProc); | 177 DISALLOW_COPY_AND_ASSIGN(MockHostResolverProc); |
178 }; | 178 }; |
179 | 179 |
| 180 bool AddressListContains(const AddressList& list, const std::string& address, |
| 181 int port) { |
| 182 IPAddressNumber ip; |
| 183 bool rv = ParseIPLiteralToNumber(address, &ip); |
| 184 DCHECK(rv); |
| 185 return std::find(list.begin(), |
| 186 list.end(), |
| 187 IPEndPoint(ip, port)) != list.end(); |
| 188 } |
| 189 |
180 // A wrapper for requests to a HostResolver. | 190 // A wrapper for requests to a HostResolver. |
181 class Request { | 191 class Request { |
182 public: | 192 public: |
183 // Base class of handlers to be executed on completion of requests. | 193 // Base class of handlers to be executed on completion of requests. |
184 struct Handler { | 194 struct Handler { |
185 virtual ~Handler() {} | 195 virtual ~Handler() {} |
186 virtual void Handle(Request* request) = 0; | 196 virtual void Handle(Request* request) = 0; |
187 }; | 197 }; |
188 | 198 |
189 Request(const HostResolver::RequestInfo& info, | 199 Request(const HostResolver::RequestInfo& info, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 } | 234 } |
225 | 235 |
226 const HostResolver::RequestInfo& info() const { return info_; } | 236 const HostResolver::RequestInfo& info() const { return info_; } |
227 size_t index() const { return index_; } | 237 size_t index() const { return index_; } |
228 const AddressList& list() const { return list_; } | 238 const AddressList& list() const { return list_; } |
229 int result() const { return result_; } | 239 int result() const { return result_; } |
230 bool completed() const { return result_ != ERR_IO_PENDING; } | 240 bool completed() const { return result_ != ERR_IO_PENDING; } |
231 bool pending() const { return handle_ != NULL; } | 241 bool pending() const { return handle_ != NULL; } |
232 | 242 |
233 bool HasAddress(const std::string& address, int port) const { | 243 bool HasAddress(const std::string& address, int port) const { |
234 IPAddressNumber ip; | 244 return AddressListContains(list_, address, port); |
235 bool rv = ParseIPLiteralToNumber(address, &ip); | |
236 DCHECK(rv); | |
237 return std::find(list_.begin(), | |
238 list_.end(), | |
239 IPEndPoint(ip, port)) != list_.end(); | |
240 } | 245 } |
241 | 246 |
242 // Returns the number of addresses in |list_|. | 247 // Returns the number of addresses in |list_|. |
243 unsigned NumberOfAddresses() const { | 248 unsigned NumberOfAddresses() const { |
244 return list_.size(); | 249 return list_.size(); |
245 } | 250 } |
246 | 251 |
247 bool HasOneAddress(const std::string& address, int port) const { | 252 bool HasOneAddress(const std::string& address, int port) const { |
248 return HasAddress(address, port) && (NumberOfAddresses() == 1u); | 253 return HasAddress(address, port) && (NumberOfAddresses() == 1u); |
249 } | 254 } |
(...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 | 1480 |
1476 // Make |proc_| default to failures. | 1481 // Make |proc_| default to failures. |
1477 proc_->AddRuleForAllFamilies(std::string(), std::string()); | 1482 proc_->AddRuleForAllFamilies(std::string(), std::string()); |
1478 | 1483 |
1479 // DnsTask should still be enabled. | 1484 // DnsTask should still be enabled. |
1480 Request* req = CreateRequest("ok_last", 80); | 1485 Request* req = CreateRequest("ok_last", 80); |
1481 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | 1486 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); |
1482 EXPECT_EQ(OK, req->WaitForResult()); | 1487 EXPECT_EQ(OK, req->WaitForResult()); |
1483 } | 1488 } |
1484 | 1489 |
| 1490 // Confirm that resolving "localhost" is unrestricted even if there are no |
| 1491 // global IPv6 address. See SystemHostResolverCall for rationale. |
| 1492 // Test both the DnsClient and system host resolver paths. |
| 1493 TEST_F(HostResolverImplDnsTest, DualFamilyLocalhost) { |
| 1494 // Use regular SystemHostResolverCall! |
| 1495 scoped_refptr<HostResolverProc> proc(new SystemHostResolverProc()); |
| 1496 resolver_.reset(new HostResolverImpl(HostCache::CreateDefaultCache(), |
| 1497 DefaultLimits(), |
| 1498 DefaultParams(proc), |
| 1499 NULL)); |
| 1500 resolver_->SetDnsClient(CreateMockDnsClient(DnsConfig(), dns_rules_)); |
| 1501 resolver_->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV4); |
| 1502 |
| 1503 // Get the expected output. |
| 1504 AddressList addrlist; |
| 1505 int rv = proc->Resolve("localhost", ADDRESS_FAMILY_UNSPECIFIED, 0, &addrlist, |
| 1506 NULL); |
| 1507 if (rv != OK) |
| 1508 return; |
| 1509 |
| 1510 for (unsigned i = 0; i < addrlist.size(); ++i) |
| 1511 LOG(WARNING) << addrlist[i].ToString(); |
| 1512 |
| 1513 bool saw_ipv4 = AddressListContains(addrlist, "127.0.0.1", 0); |
| 1514 bool saw_ipv6 = AddressListContains(addrlist, "::1", 0); |
| 1515 if (!saw_ipv4 && !saw_ipv6) |
| 1516 return; |
| 1517 |
| 1518 HostResolver::RequestInfo info(HostPortPair("localhost", 80)); |
| 1519 info.set_address_family(ADDRESS_FAMILY_UNSPECIFIED); |
| 1520 info.set_host_resolver_flags(HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6); |
| 1521 |
| 1522 // Try without DnsClient. |
| 1523 ChangeDnsConfig(DnsConfig()); |
| 1524 Request* req = CreateRequest(info); |
| 1525 // It is resolved via getaddrinfo, so expect asynchronous result. |
| 1526 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); |
| 1527 EXPECT_EQ(OK, req->WaitForResult()); |
| 1528 |
| 1529 EXPECT_EQ(saw_ipv4, req->HasAddress("127.0.0.1", 80)); |
| 1530 EXPECT_EQ(saw_ipv6, req->HasAddress("::1", 80)); |
| 1531 |
| 1532 // Configure DnsClient with dual-host HOSTS file. |
| 1533 DnsConfig config = CreateValidDnsConfig(); |
| 1534 DnsHosts hosts; |
| 1535 IPAddressNumber local_ipv4, local_ipv6; |
| 1536 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &local_ipv4)); |
| 1537 ASSERT_TRUE(ParseIPLiteralToNumber("::1", &local_ipv6)); |
| 1538 if (saw_ipv4) |
| 1539 hosts[DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4)] = local_ipv4; |
| 1540 if (saw_ipv6) |
| 1541 hosts[DnsHostsKey("localhost", ADDRESS_FAMILY_IPV6)] = local_ipv6; |
| 1542 config.hosts = hosts; |
| 1543 |
| 1544 ChangeDnsConfig(config); |
| 1545 req = CreateRequest(info); |
| 1546 // Expect synchronous resolution from DnsHosts. |
| 1547 EXPECT_EQ(OK, req->Resolve()); |
| 1548 |
| 1549 EXPECT_EQ(saw_ipv4, req->HasAddress("127.0.0.1", 80)); |
| 1550 EXPECT_EQ(saw_ipv6, req->HasAddress("::1", 80)); |
| 1551 } |
| 1552 |
1485 } // namespace net | 1553 } // namespace net |
OLD | NEW |