diff options
author | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-18 08:02:08 +0000 |
---|---|---|
committer | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-18 08:02:08 +0000 |
commit | 40f153572764e76066588fd2e358d05b8fa453bb (patch) | |
tree | 9c8bf3de47da4fac879d1035addf2a6780f163e4 /net/base | |
parent | a2c2fb9ff48cd37dbed258dca5b40461c92b71a8 (diff) | |
download | chromium_src-40f153572764e76066588fd2e358d05b8fa453bb.zip chromium_src-40f153572764e76066588fd2e358d05b8fa453bb.tar.gz chromium_src-40f153572764e76066588fd2e358d05b8fa453bb.tar.bz2 |
Use manually constructed IPv6 socket addresses for tests, rather than system created ones.
The advantage is that GURL's parsing of IPv6 addresses works on all systems, whereas getaddrinfo(ipv6_literal) only succeeds on IPv6 enabled systems.
This allows the tests to run consistently on all systems, including our own WinXP buildbots (which do not support IPv6).
BUG=http://crbug.com/16452
TEST=[net_unittests] SOCKS5ClientSocketTest.IPv6Domain, SOCKSClientSocketTest.SOCKS4AIfDomainInIPv6
Review URL: http://codereview.chromium.org/155618
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21053 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/address_list.cc | 19 | ||||
-rw-r--r-- | net/base/address_list.h | 9 | ||||
-rw-r--r-- | net/base/host_resolver_impl_unittest.cc | 7 | ||||
-rw-r--r-- | net/base/mock_host_resolver.cc | 108 | ||||
-rw-r--r-- | net/base/mock_host_resolver.h | 8 |
5 files changed, 122 insertions, 29 deletions
diff --git a/net/base/address_list.cc b/net/base/address_list.cc index 9fc8d32..7cfab3f 100644 --- a/net/base/address_list.cc +++ b/net/base/address_list.cc @@ -127,6 +127,25 @@ void AddressList::Reset() { data_ = NULL; } +// static +AddressList AddressList::CreateIPv6Address(unsigned char data[16]) { + struct addrinfo* ai = new struct addrinfo; + memset(ai, 0, sizeof(struct addrinfo)); + + ai->ai_family = AF_INET6; + ai->ai_socktype = SOCK_STREAM; + ai->ai_addrlen = sizeof(sockaddr_in6); + + struct sockaddr_in6* addr6 = new sockaddr_in6; + memset(addr6, 0, sizeof(sockaddr_in6)); + + ai->ai_addr = reinterpret_cast<sockaddr*>(addr6); + addr6->sin6_family = AF_INET6; + memcpy(&addr6->sin6_addr, data, 16); + + return AddressList(new Data(ai, false /*is_system_created*/)); +} + AddressList::Data::~Data() { // Call either freeaddrinfo(head), or FreeMyAddrinfo(head), depending who // created the data. diff --git a/net/base/address_list.h b/net/base/address_list.h index 506350b..165086c 100644 --- a/net/base/address_list.h +++ b/net/base/address_list.h @@ -15,6 +15,9 @@ namespace net { // class is designed to be copied around by value. class AddressList { public: + // Constructs an empty address list. + AddressList() {} + // Adopt the given addrinfo list in place of the existing one if any. This // hands over responsibility for freeing the addrinfo list to the AddressList // object. @@ -41,6 +44,9 @@ class AddressList { // empty state as when first constructed. void Reset(); + // Used by unit-tests to manually set the TCP socket address. + static AddressList CreateIPv6Address(unsigned char data[16]); + // Get access to the head of the addrinfo list. const struct addrinfo* head() const { return data_->head; } @@ -54,6 +60,9 @@ class AddressList { // Indicates which free function to use for |head|. bool is_system_created; }; + + explicit AddressList(Data* data) : data_(data) {} + scoped_refptr<Data> data_; }; diff --git a/net/base/host_resolver_impl_unittest.cc b/net/base/host_resolver_impl_unittest.cc index 0ff345c..350a25d 100644 --- a/net/base/host_resolver_impl_unittest.cc +++ b/net/base/host_resolver_impl_unittest.cc @@ -318,7 +318,12 @@ TEST_F(HostResolverImplTest, NumericIPv6Address) { } } -TEST_F(HostResolverImplTest, EmptyHost) { +// TODO(eroman): This test is disabled because it is bogus. It used to pass +// solely because of a bug in the RuleBasedHostMapper -- (empty replacements +// would map to a failure). However when using the actual host resolver +// (getaddrinfo), this is not necessarily the case. On windows getaddrinfo("") +// gives you the address of your machine. +TEST_F(HostResolverImplTest, DISABLED_EmptyHost) { scoped_refptr<RuleBasedHostResolverProc> resolver_proc = new RuleBasedHostResolverProc(NULL); resolver_proc->AllowDirectLookup("*"); diff --git a/net/base/mock_host_resolver.cc b/net/base/mock_host_resolver.cc index 508ef38..c83f3c8 100644 --- a/net/base/mock_host_resolver.cc +++ b/net/base/mock_host_resolver.cc @@ -7,10 +7,36 @@ #include "base/string_util.h" #include "base/platform_thread.h" #include "base/ref_counted.h" +#include "googleurl/src/url_canon_ip.h" #include "net/base/net_errors.h" namespace net { +namespace { +// Fills |addrlist| with a socket address for |host| which should be an +// IPv6 literal. Returns OK on success. +int ResolveIPV6LiteralUsingGURL(const std::string& host, + AddressList* addrlist) { + // GURL expects the hostname to be surrounded with brackets. + std::string host_brackets = "[" + host + "]"; + url_parse::Component host_comp(0, host_brackets.size()); + + // Try parsing the hostname as an IPv6 literal. + unsigned char ipv6_addr[16]; // 128 bits. + bool ok = url_canon::IPv6AddressToNumber(host_brackets.data(), + host_comp, + ipv6_addr); + if (!ok) { + LOG(WARNING) << "Not an IPv6 literal: " << host; + return ERR_UNEXPECTED; + } + + *addrlist = AddressList::CreateIPv6Address(ipv6_addr); + return OK; +} + +} // namespace + MockHostResolverBase::MockHostResolverBase(bool use_caching) : use_caching_(use_caching) { Reset(NULL); @@ -71,27 +97,25 @@ void MockHostResolverBase::Reset(HostResolverProc* interceptor) { //----------------------------------------------------------------------------- struct RuleBasedHostResolverProc::Rule { + enum ResolverType { + kResolverTypeFail, + kResolverTypeSystem, + kResolverTypeIPV6Literal, + }; + + ResolverType resolver_type; std::string host_pattern; std::string replacement; int latency_ms; // In milliseconds. - bool direct; // if true, don't mangle hostname and ignore replacement - Rule(const std::string& host_pattern, const std::string& replacement) - : host_pattern(host_pattern), - replacement(replacement), - latency_ms(0), - direct(false) {} - Rule(const std::string& host_pattern, const std::string& replacement, - const int latency_ms) - : host_pattern(host_pattern), - replacement(replacement), - latency_ms(latency_ms), - direct(false) {} - Rule(const std::string& host_pattern, const std::string& replacement, - const bool direct) - : host_pattern(host_pattern), + + Rule(ResolverType resolver_type, + const std::string& host_pattern, + const std::string& replacement, + int latency_ms) + : resolver_type(resolver_type), + host_pattern(host_pattern), replacement(replacement), - latency_ms(0), - direct(direct) {} + latency_ms(latency_ms) {} }; RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous) @@ -103,21 +127,36 @@ RuleBasedHostResolverProc::~RuleBasedHostResolverProc() { void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern, const std::string& replacement) { - rules_.push_back(Rule(host_pattern, replacement)); + DCHECK(!replacement.empty()); + Rule rule(Rule::kResolverTypeSystem, host_pattern, replacement, 0); + rules_.push_back(rule); +} + +void RuleBasedHostResolverProc::AddIPv6Rule(const std::string& host_pattern, + const std::string& ipv6_literal) { + Rule rule(Rule::kResolverTypeIPV6Literal, host_pattern, ipv6_literal, 0); + rules_.push_back(rule); } void RuleBasedHostResolverProc::AddRuleWithLatency( const std::string& host_pattern, - const std::string& replacement, int latency_ms) { - rules_.push_back(Rule(host_pattern, replacement, latency_ms)); + const std::string& replacement, + int latency_ms) { + DCHECK(!replacement.empty()); + Rule rule(Rule::kResolverTypeSystem, host_pattern, replacement, latency_ms); + rules_.push_back(rule); } -void RuleBasedHostResolverProc::AllowDirectLookup(const std::string& host) { - rules_.push_back(Rule(host, "", true)); +void RuleBasedHostResolverProc::AllowDirectLookup( + const std::string& host_pattern) { + Rule rule(Rule::kResolverTypeSystem, host_pattern, "", 0); + rules_.push_back(rule); } -void RuleBasedHostResolverProc::AddSimulatedFailure(const std::string& host) { - AddRule(host, ""); +void RuleBasedHostResolverProc::AddSimulatedFailure( + const std::string& host_pattern) { + Rule rule(Rule::kResolverTypeFail, host_pattern, "", 0); + rules_.push_back(rule); } int RuleBasedHostResolverProc::Resolve(const std::string& host, @@ -130,10 +169,23 @@ int RuleBasedHostResolverProc::Resolve(const std::string& host, // Hmm, this seems unecessary. r->latency_ms = 1; } - const std::string& effective_host = r->direct ? host : r->replacement; - if (effective_host.empty()) - return ERR_NAME_NOT_RESOLVED; - return SystemHostResolverProc(effective_host, addrlist); + + // Remap to a new host. + const std::string& effective_host = + r->replacement.empty() ? host : r->replacement; + + // Apply the resolving function to the remapped hostname. + switch (r->resolver_type) { + case Rule::kResolverTypeFail: + return ERR_NAME_NOT_RESOLVED; + case Rule::kResolverTypeSystem: + return SystemHostResolverProc(effective_host, addrlist); + case Rule::kResolverTypeIPV6Literal: + return ResolveIPV6LiteralUsingGURL(effective_host, addrlist); + default: + NOTREACHED(); + return ERR_UNEXPECTED; + } } } return ResolveUsingPrevious(host, addrlist); diff --git a/net/base/mock_host_resolver.h b/net/base/mock_host_resolver.h index 1d29684..413bd36 100644 --- a/net/base/mock_host_resolver.h +++ b/net/base/mock_host_resolver.h @@ -98,6 +98,13 @@ class RuleBasedHostResolverProc : public HostResolverProc { void AddRule(const std::string& host_pattern, const std::string& replacement); + // Same as AddRule(), but the replacement is expected to be an IPV6 literal. + // You should use this in place of AddRule(), since the system's host resolver + // may not support IPv6 literals on all systems. Whereas this variant + // constructs the socket address directly so it will always work. + void AddIPv6Rule(const std::string& host_pattern, + const std::string& ipv6_literal); + void AddRuleWithLatency(const std::string& host_pattern, const std::string& replacement, int latency_ms); @@ -115,6 +122,7 @@ class RuleBasedHostResolverProc : public HostResolverProc { private: struct Rule; typedef std::list<Rule> RuleList; + RuleList rules_; }; |