OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/mock_host_resolver.h" | 5 #include "net/base/mock_host_resolver.h" |
6 | 6 |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "base/platform_thread.h" | 8 #include "base/platform_thread.h" |
9 #include "base/ref_counted.h" | 9 #include "base/ref_counted.h" |
| 10 #include "googleurl/src/url_canon_ip.h" |
10 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
11 | 12 |
12 namespace net { | 13 namespace net { |
13 | 14 |
| 15 namespace { |
| 16 // Fills |addrlist| with a socket address for |host| which should be an |
| 17 // IPv6 literal. Returns OK on success. |
| 18 int ResolveIPV6LiteralUsingGURL(const std::string& host, |
| 19 AddressList* addrlist) { |
| 20 // GURL expects the hostname to be surrounded with brackets. |
| 21 std::string host_brackets = "[" + host + "]"; |
| 22 url_parse::Component host_comp(0, host_brackets.size()); |
| 23 |
| 24 // Try parsing the hostname as an IPv6 literal. |
| 25 unsigned char ipv6_addr[16]; // 128 bits. |
| 26 bool ok = url_canon::IPv6AddressToNumber(host_brackets.data(), |
| 27 host_comp, |
| 28 ipv6_addr); |
| 29 if (!ok) { |
| 30 LOG(WARNING) << "Not an IPv6 literal: " << host; |
| 31 return ERR_UNEXPECTED; |
| 32 } |
| 33 |
| 34 *addrlist = AddressList::CreateIPv6Address(ipv6_addr); |
| 35 return OK; |
| 36 } |
| 37 |
| 38 } // namespace |
| 39 |
14 MockHostResolverBase::MockHostResolverBase(bool use_caching) | 40 MockHostResolverBase::MockHostResolverBase(bool use_caching) |
15 : use_caching_(use_caching) { | 41 : use_caching_(use_caching) { |
16 Reset(NULL); | 42 Reset(NULL); |
17 } | 43 } |
18 | 44 |
19 int MockHostResolverBase::Resolve(const RequestInfo& info, | 45 int MockHostResolverBase::Resolve(const RequestInfo& info, |
20 AddressList* addresses, | 46 AddressList* addresses, |
21 CompletionCallback* callback, | 47 CompletionCallback* callback, |
22 RequestHandle* out_req) { | 48 RequestHandle* out_req) { |
23 if (synchronous_mode_) { | 49 if (synchronous_mode_) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 | 90 |
65 int max_cache_entries = use_caching_ ? 100 : 0; | 91 int max_cache_entries = use_caching_ ? 100 : 0; |
66 int max_cache_age_ms = use_caching_ ? 60000 : 0; | 92 int max_cache_age_ms = use_caching_ ? 60000 : 0; |
67 | 93 |
68 impl_ = new HostResolverImpl(proc, max_cache_entries, max_cache_age_ms); | 94 impl_ = new HostResolverImpl(proc, max_cache_entries, max_cache_age_ms); |
69 } | 95 } |
70 | 96 |
71 //----------------------------------------------------------------------------- | 97 //----------------------------------------------------------------------------- |
72 | 98 |
73 struct RuleBasedHostResolverProc::Rule { | 99 struct RuleBasedHostResolverProc::Rule { |
| 100 enum ResolverType { |
| 101 kResolverTypeFail, |
| 102 kResolverTypeSystem, |
| 103 kResolverTypeIPV6Literal, |
| 104 }; |
| 105 |
| 106 ResolverType resolver_type; |
74 std::string host_pattern; | 107 std::string host_pattern; |
75 std::string replacement; | 108 std::string replacement; |
76 int latency_ms; // In milliseconds. | 109 int latency_ms; // In milliseconds. |
77 bool direct; // if true, don't mangle hostname and ignore replacement | 110 |
78 Rule(const std::string& host_pattern, const std::string& replacement) | 111 Rule(ResolverType resolver_type, |
79 : host_pattern(host_pattern), | 112 const std::string& host_pattern, |
| 113 const std::string& replacement, |
| 114 int latency_ms) |
| 115 : resolver_type(resolver_type), |
| 116 host_pattern(host_pattern), |
80 replacement(replacement), | 117 replacement(replacement), |
81 latency_ms(0), | 118 latency_ms(latency_ms) {} |
82 direct(false) {} | |
83 Rule(const std::string& host_pattern, const std::string& replacement, | |
84 const int latency_ms) | |
85 : host_pattern(host_pattern), | |
86 replacement(replacement), | |
87 latency_ms(latency_ms), | |
88 direct(false) {} | |
89 Rule(const std::string& host_pattern, const std::string& replacement, | |
90 const bool direct) | |
91 : host_pattern(host_pattern), | |
92 replacement(replacement), | |
93 latency_ms(0), | |
94 direct(direct) {} | |
95 }; | 119 }; |
96 | 120 |
97 RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous) | 121 RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous) |
98 : HostResolverProc(previous) { | 122 : HostResolverProc(previous) { |
99 } | 123 } |
100 | 124 |
101 RuleBasedHostResolverProc::~RuleBasedHostResolverProc() { | 125 RuleBasedHostResolverProc::~RuleBasedHostResolverProc() { |
102 } | 126 } |
103 | 127 |
104 void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern, | 128 void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern, |
105 const std::string& replacement) { | 129 const std::string& replacement) { |
106 rules_.push_back(Rule(host_pattern, replacement)); | 130 DCHECK(!replacement.empty()); |
| 131 Rule rule(Rule::kResolverTypeSystem, host_pattern, replacement, 0); |
| 132 rules_.push_back(rule); |
| 133 } |
| 134 |
| 135 void RuleBasedHostResolverProc::AddIPv6Rule(const std::string& host_pattern, |
| 136 const std::string& ipv6_literal) { |
| 137 Rule rule(Rule::kResolverTypeIPV6Literal, host_pattern, ipv6_literal, 0); |
| 138 rules_.push_back(rule); |
107 } | 139 } |
108 | 140 |
109 void RuleBasedHostResolverProc::AddRuleWithLatency( | 141 void RuleBasedHostResolverProc::AddRuleWithLatency( |
110 const std::string& host_pattern, | 142 const std::string& host_pattern, |
111 const std::string& replacement, int latency_ms) { | 143 const std::string& replacement, |
112 rules_.push_back(Rule(host_pattern, replacement, latency_ms)); | 144 int latency_ms) { |
| 145 DCHECK(!replacement.empty()); |
| 146 Rule rule(Rule::kResolverTypeSystem, host_pattern, replacement, latency_ms); |
| 147 rules_.push_back(rule); |
113 } | 148 } |
114 | 149 |
115 void RuleBasedHostResolverProc::AllowDirectLookup(const std::string& host) { | 150 void RuleBasedHostResolverProc::AllowDirectLookup( |
116 rules_.push_back(Rule(host, "", true)); | 151 const std::string& host_pattern) { |
| 152 Rule rule(Rule::kResolverTypeSystem, host_pattern, "", 0); |
| 153 rules_.push_back(rule); |
117 } | 154 } |
118 | 155 |
119 void RuleBasedHostResolverProc::AddSimulatedFailure(const std::string& host) { | 156 void RuleBasedHostResolverProc::AddSimulatedFailure( |
120 AddRule(host, ""); | 157 const std::string& host_pattern) { |
| 158 Rule rule(Rule::kResolverTypeFail, host_pattern, "", 0); |
| 159 rules_.push_back(rule); |
121 } | 160 } |
122 | 161 |
123 int RuleBasedHostResolverProc::Resolve(const std::string& host, | 162 int RuleBasedHostResolverProc::Resolve(const std::string& host, |
124 AddressList* addrlist) { | 163 AddressList* addrlist) { |
125 RuleList::iterator r; | 164 RuleList::iterator r; |
126 for (r = rules_.begin(); r != rules_.end(); ++r) { | 165 for (r = rules_.begin(); r != rules_.end(); ++r) { |
127 if (MatchPattern(host, r->host_pattern)) { | 166 if (MatchPattern(host, r->host_pattern)) { |
128 if (r->latency_ms != 0) { | 167 if (r->latency_ms != 0) { |
129 PlatformThread::Sleep(r->latency_ms); | 168 PlatformThread::Sleep(r->latency_ms); |
130 // Hmm, this seems unecessary. | 169 // Hmm, this seems unecessary. |
131 r->latency_ms = 1; | 170 r->latency_ms = 1; |
132 } | 171 } |
133 const std::string& effective_host = r->direct ? host : r->replacement; | 172 |
134 if (effective_host.empty()) | 173 // Remap to a new host. |
135 return ERR_NAME_NOT_RESOLVED; | 174 const std::string& effective_host = |
136 return SystemHostResolverProc(effective_host, addrlist); | 175 r->replacement.empty() ? host : r->replacement; |
| 176 |
| 177 // Apply the resolving function to the remapped hostname. |
| 178 switch (r->resolver_type) { |
| 179 case Rule::kResolverTypeFail: |
| 180 return ERR_NAME_NOT_RESOLVED; |
| 181 case Rule::kResolverTypeSystem: |
| 182 return SystemHostResolverProc(effective_host, addrlist); |
| 183 case Rule::kResolverTypeIPV6Literal: |
| 184 return ResolveIPV6LiteralUsingGURL(effective_host, addrlist); |
| 185 default: |
| 186 NOTREACHED(); |
| 187 return ERR_UNEXPECTED; |
| 188 } |
137 } | 189 } |
138 } | 190 } |
139 return ResolveUsingPrevious(host, addrlist); | 191 return ResolveUsingPrevious(host, addrlist); |
140 } | 192 } |
141 | 193 |
142 //----------------------------------------------------------------------------- | 194 //----------------------------------------------------------------------------- |
143 | 195 |
144 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc( | 196 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc( |
145 HostResolverProc* proc) : current_proc_(proc) { | 197 HostResolverProc* proc) : current_proc_(proc) { |
146 previous_proc_ = HostResolverProc::SetDefault(current_proc_); | 198 previous_proc_ = HostResolverProc::SetDefault(current_proc_); |
147 current_proc_->set_previous_proc(previous_proc_); | 199 current_proc_->set_previous_proc(previous_proc_); |
148 } | 200 } |
149 | 201 |
150 ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() { | 202 ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() { |
151 HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_); | 203 HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_); |
152 // The lifetimes of multiple instances must be nested. | 204 // The lifetimes of multiple instances must be nested. |
153 CHECK(old_proc == current_proc_); | 205 CHECK(old_proc == current_proc_); |
154 } | 206 } |
155 | 207 |
156 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) { | 208 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) { |
157 current_proc_ = proc; | 209 current_proc_ = proc; |
158 previous_proc_ = HostResolverProc::SetDefault(current_proc_); | 210 previous_proc_ = HostResolverProc::SetDefault(current_proc_); |
159 current_proc_->set_previous_proc(previous_proc_); | 211 current_proc_->set_previous_proc(previous_proc_); |
160 } | 212 } |
161 | 213 |
162 } // namespace net | 214 } // namespace net |
OLD | NEW |