1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/base/mock_host_resolver.h" 6 7 #include "base/memory/ref_counted.h" 8 #include "base/string_split.h" 9 #include "base/string_util.h" 10 #include "base/threading/platform_thread.h" 11 #include "net/base/net_errors.h" 12 #include "net/base/net_util.h" 13 #include "net/base/sys_addrinfo.h" 14 15 namespace net { 16 17 namespace { 18 19 char* do_strdup(const char* src) { 20 #if defined(OS_WIN) 21 return _strdup(src); 22 #else 23 return strdup(src); 24 #endif 25 } 26 27 // Fills |*addrlist| with a socket address for |host_list| which should be a 28 // comma-separated list of IPv4 or IPv6 literal(s) without enclosing brackets. 29 // If |canonical_name| is non-empty it is used as the DNS canonical name for 30 // the host. Returns OK on success, ERR_UNEXPECTED otherwise. 31 int CreateIPAddressList(const std::string& host_list, 32 const std::string& canonical_name, 33 AddressList* addrlist) { 34 *addrlist = AddressList(); 35 std::vector<std::string> addresses; 36 base::SplitString(host_list, ',', &addresses); 37 for (size_t index = 0; index < addresses.size(); ++index) { 38 IPAddressNumber ip_number; 39 if (!ParseIPLiteralToNumber(addresses[index], &ip_number)) { 40 LOG(WARNING) << "Not a supported IP literal: " << addresses[index]; 41 return ERR_UNEXPECTED; 42 } 43 44 AddressList result(ip_number, -1, false); 45 struct addrinfo* ai = const_cast<struct addrinfo*>(result.head()); 46 if (index == 0) 47 ai->ai_canonname = do_strdup(canonical_name.c_str()); 48 if (!addrlist->head()) 49 addrlist->Copy(result.head(), false); 50 else 51 addrlist->Append(result.head()); 52 } 53 return OK; 54 } 55 56 } // namespace 57 58 MockHostResolverBase::~MockHostResolverBase() {} 59 60 void MockHostResolverBase::Reset(HostResolverProc* interceptor) { 61 synchronous_mode_ = false; 62 63 // At the root of the chain, map everything to localhost. 64 scoped_refptr<RuleBasedHostResolverProc> catchall( 65 new RuleBasedHostResolverProc(NULL)); 66 catchall->AddRule("*", "127.0.0.1"); 67 68 // Next add a rules-based layer the use controls. 69 rules_ = new RuleBasedHostResolverProc(catchall); 70 71 HostResolverProc* proc = rules_; 72 73 // Lastly add the provided interceptor to the front of the chain. 74 if (interceptor) { 75 interceptor->SetPreviousProc(proc); 76 proc = interceptor; 77 } 78 79 HostCache* cache = NULL; 80 81 if (use_caching_) { 82 cache = new HostCache( 83 100, // max entries. 84 base::TimeDelta::FromMinutes(1), 85 base::TimeDelta::FromSeconds(0)); 86 } 87 88 impl_.reset(new HostResolverImpl(proc, cache, 50u, NULL)); 89 } 90 91 int MockHostResolverBase::Resolve(const RequestInfo& info, 92 AddressList* addresses, 93 CompletionCallback* callback, 94 RequestHandle* out_req, 95 const BoundNetLog& net_log) { 96 if (synchronous_mode_) { 97 callback = NULL; 98 out_req = NULL; 99 } 100 return impl_->Resolve(info, addresses, callback, out_req, net_log); 101 } 102 103 void MockHostResolverBase::CancelRequest(RequestHandle req) { 104 impl_->CancelRequest(req); 105 } 106 107 void MockHostResolverBase::AddObserver(Observer* observer) { 108 impl_->AddObserver(observer); 109 } 110 111 void MockHostResolverBase::RemoveObserver(Observer* observer) { 112 impl_->RemoveObserver(observer); 113 } 114 115 MockHostResolverBase::MockHostResolverBase(bool use_caching) 116 : use_caching_(use_caching) { 117 Reset(NULL); 118 } 119 120 //----------------------------------------------------------------------------- 121 122 struct RuleBasedHostResolverProc::Rule { 123 enum ResolverType { 124 kResolverTypeFail, 125 kResolverTypeSystem, 126 kResolverTypeIPLiteral, 127 }; 128 129 ResolverType resolver_type; 130 std::string host_pattern; 131 AddressFamily address_family; 132 HostResolverFlags host_resolver_flags; 133 std::string replacement; 134 std::string canonical_name; 135 int latency_ms; // In milliseconds. 136 137 Rule(ResolverType resolver_type, 138 const std::string& host_pattern, 139 AddressFamily address_family, 140 HostResolverFlags host_resolver_flags, 141 const std::string& replacement, 142 const std::string& canonical_name, 143 int latency_ms) 144 : resolver_type(resolver_type), 145 host_pattern(host_pattern), 146 address_family(address_family), 147 host_resolver_flags(host_resolver_flags), 148 replacement(replacement), 149 canonical_name(canonical_name), 150 latency_ms(latency_ms) {} 151 }; 152 153 RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous) 154 : HostResolverProc(previous) { 155 } 156 157 void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern, 158 const std::string& replacement) { 159 AddRuleForAddressFamily(host_pattern, ADDRESS_FAMILY_UNSPECIFIED, 160 replacement); 161 } 162 163 void RuleBasedHostResolverProc::AddRuleForAddressFamily( 164 const std::string& host_pattern, 165 AddressFamily address_family, 166 const std::string& replacement) { 167 DCHECK(!replacement.empty()); 168 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY | 169 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; 170 Rule rule(Rule::kResolverTypeSystem, host_pattern, address_family, flags, 171 replacement, "", 0); 172 rules_.push_back(rule); 173 } 174 175 void RuleBasedHostResolverProc::AddIPLiteralRule( 176 const std::string& host_pattern, 177 const std::string& ip_literal, 178 const std::string& canonical_name) { 179 // Literals are always resolved to themselves by HostResolverImpl, 180 // consequently we do not support remapping them. 181 IPAddressNumber ip_number; 182 DCHECK(!ParseIPLiteralToNumber(host_pattern, &ip_number)); 183 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY | 184 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; 185 if (!canonical_name.empty()) 186 flags |= HOST_RESOLVER_CANONNAME; 187 Rule rule(Rule::kResolverTypeIPLiteral, host_pattern, 188 ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal, canonical_name, 189 0); 190 rules_.push_back(rule); 191 } 192 193 void RuleBasedHostResolverProc::AddRuleWithLatency( 194 const std::string& host_pattern, 195 const std::string& replacement, 196 int latency_ms) { 197 DCHECK(!replacement.empty()); 198 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY | 199 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; 200 Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED, 201 flags, replacement, "", latency_ms); 202 rules_.push_back(rule); 203 } 204 205 void RuleBasedHostResolverProc::AllowDirectLookup( 206 const std::string& host_pattern) { 207 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY | 208 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; 209 Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED, 210 flags, "", "", 0); 211 rules_.push_back(rule); 212 } 213 214 void RuleBasedHostResolverProc::AddSimulatedFailure( 215 const std::string& host_pattern) { 216 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY | 217 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; 218 Rule rule(Rule::kResolverTypeFail, host_pattern, ADDRESS_FAMILY_UNSPECIFIED, 219 flags, "", "", 0); 220 rules_.push_back(rule); 221 } 222 223 int RuleBasedHostResolverProc::Resolve(const std::string& host, 224 AddressFamily address_family, 225 HostResolverFlags host_resolver_flags, 226 AddressList* addrlist, 227 int* os_error) { 228 RuleList::iterator r; 229 for (r = rules_.begin(); r != rules_.end(); ++r) { 230 bool matches_address_family = 231 r->address_family == ADDRESS_FAMILY_UNSPECIFIED || 232 r->address_family == address_family; 233 // Flags match if all of the bitflags in host_resolver_flags are enabled 234 // in the rule's host_resolver_flags. However, the rule may have additional 235 // flags specified, in which case the flags should still be considered a 236 // match. 237 bool matches_flags = (r->host_resolver_flags & host_resolver_flags) == 238 host_resolver_flags; 239 if (matches_flags && matches_address_family && 240 MatchPattern(host, r->host_pattern)) { 241 if (r->latency_ms != 0) 242 base::PlatformThread::Sleep(r->latency_ms); 243 244 // Remap to a new host. 245 const std::string& effective_host = 246 r->replacement.empty() ? host : r->replacement; 247 248 // Apply the resolving function to the remapped hostname. 249 switch (r->resolver_type) { 250 case Rule::kResolverTypeFail: 251 return ERR_NAME_NOT_RESOLVED; 252 case Rule::kResolverTypeSystem: 253 return SystemHostResolverProc(effective_host, 254 address_family, 255 host_resolver_flags, 256 addrlist, os_error); 257 case Rule::kResolverTypeIPLiteral: 258 return CreateIPAddressList(effective_host, 259 r->canonical_name, 260 addrlist); 261 default: 262 NOTREACHED(); 263 return ERR_UNEXPECTED; 264 } 265 } 266 } 267 return ResolveUsingPrevious(host, address_family, 268 host_resolver_flags, addrlist, os_error); 269 } 270 271 RuleBasedHostResolverProc::~RuleBasedHostResolverProc() { 272 } 273 274 //----------------------------------------------------------------------------- 275 276 WaitingHostResolverProc::WaitingHostResolverProc(HostResolverProc* previous) 277 : HostResolverProc(previous), event_(false, false) {} 278 279 void WaitingHostResolverProc::Signal() { 280 event_.Signal(); 281 } 282 283 int WaitingHostResolverProc::Resolve(const std::string& host, 284 AddressFamily address_family, 285 HostResolverFlags host_resolver_flags, 286 AddressList* addrlist, 287 int* os_error) { 288 event_.Wait(); 289 return ResolveUsingPrevious(host, address_family, host_resolver_flags, 290 addrlist, os_error); 291 } 292 293 WaitingHostResolverProc::~WaitingHostResolverProc() {} 294 295 //----------------------------------------------------------------------------- 296 297 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc() {} 298 299 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc( 300 HostResolverProc* proc) { 301 Init(proc); 302 } 303 304 ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() { 305 HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_); 306 // The lifetimes of multiple instances must be nested. 307 CHECK_EQ(old_proc, current_proc_); 308 } 309 310 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) { 311 current_proc_ = proc; 312 previous_proc_ = HostResolverProc::SetDefault(current_proc_); 313 current_proc_->SetLastProc(previous_proc_); 314 } 315 316 } // namespace net 317