Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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_impl.h" | 5 #include "net/base/host_resolver_impl.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <Winsock2.h> | 8 #include <Winsock2.h> |
| 9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
| 10 #include <netdb.h> | 10 #include <netdb.h> |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 RequestInfoParameters(const HostResolver::RequestInfo& info, | 215 RequestInfoParameters(const HostResolver::RequestInfo& info, |
| 216 const NetLog::Source& source) | 216 const NetLog::Source& source) |
| 217 : info_(info), source_(source) {} | 217 : info_(info), source_(source) {} |
| 218 | 218 |
| 219 virtual Value* ToValue() const { | 219 virtual Value* ToValue() const { |
| 220 DictionaryValue* dict = new DictionaryValue(); | 220 DictionaryValue* dict = new DictionaryValue(); |
| 221 dict->SetString("host", info_.host_port_pair().ToString()); | 221 dict->SetString("host", info_.host_port_pair().ToString()); |
| 222 dict->SetInteger("address_family", | 222 dict->SetInteger("address_family", |
| 223 static_cast<int>(info_.address_family())); | 223 static_cast<int>(info_.address_family())); |
| 224 dict->SetBoolean("allow_cached_response", info_.allow_cached_response()); | 224 dict->SetBoolean("allow_cached_response", info_.allow_cached_response()); |
| 225 dict->SetBoolean("only_use_cached_response", | |
| 226 info_.only_use_cached_response()); | |
| 227 dict->SetBoolean("is_speculative", info_.is_speculative()); | 225 dict->SetBoolean("is_speculative", info_.is_speculative()); |
| 228 dict->SetInteger("priority", info_.priority()); | 226 dict->SetInteger("priority", info_.priority()); |
| 229 | 227 |
| 230 if (source_.is_valid()) | 228 if (source_.is_valid()) |
| 231 dict->Set("source_dependency", source_.ToValue()); | 229 dict->Set("source_dependency", source_.ToValue()); |
| 232 | 230 |
| 233 return dict; | 231 return dict; |
| 234 } | 232 } |
| 235 | 233 |
| 236 private: | 234 private: |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1128 CHECK(jobs_.empty()) << "Can only set constraints during setup"; | 1126 CHECK(jobs_.empty()) << "Can only set constraints during setup"; |
| 1129 JobPool* pool = job_pools_[pool_index]; | 1127 JobPool* pool = job_pools_[pool_index]; |
| 1130 pool->SetConstraints(max_outstanding_jobs, max_pending_requests); | 1128 pool->SetConstraints(max_outstanding_jobs, max_pending_requests); |
| 1131 } | 1129 } |
| 1132 | 1130 |
| 1133 int HostResolverImpl::Resolve(const RequestInfo& info, | 1131 int HostResolverImpl::Resolve(const RequestInfo& info, |
| 1134 AddressList* addresses, | 1132 AddressList* addresses, |
| 1135 CompletionCallback* callback, | 1133 CompletionCallback* callback, |
| 1136 RequestHandle* out_req, | 1134 RequestHandle* out_req, |
| 1137 const BoundNetLog& source_net_log) { | 1135 const BoundNetLog& source_net_log) { |
| 1136 DCHECK(addresses); | |
| 1137 DCHECK(callback); | |
| 1138 DCHECK(CalledOnValidThread()); | 1138 DCHECK(CalledOnValidThread()); |
| 1139 | 1139 |
| 1140 // Choose a unique ID number for observers to see. | 1140 // Choose a unique ID number for observers to see. |
| 1141 int request_id = next_request_id_++; | 1141 int request_id = next_request_id_++; |
| 1142 | 1142 |
| 1143 // Make a log item for the request. | 1143 // Make a log item for the request. |
| 1144 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, | 1144 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, |
| 1145 NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); | 1145 NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); |
| 1146 | 1146 |
| 1147 // Update the net log and notify registered observers. | 1147 // Update the net log and notify registered observers. |
| 1148 OnStartRequest(source_net_log, request_net_log, request_id, info); | 1148 OnStartRequest(source_net_log, request_net_log, request_id, info); |
| 1149 | 1149 |
| 1150 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. | |
| 1151 // On Windows it gives the default interface's address, whereas on Linux it | |
| 1152 // gives an error. We will make it fail on all platforms for consistency. | |
| 1153 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) { | |
| 1154 OnFinishRequest(source_net_log, | |
| 1155 request_net_log, | |
| 1156 request_id, | |
| 1157 info, | |
| 1158 ERR_NAME_NOT_RESOLVED, | |
| 1159 0); | |
| 1160 return ERR_NAME_NOT_RESOLVED; | |
| 1161 } | |
| 1162 | |
| 1163 // Build a key that identifies the request in the cache and in the | 1150 // Build a key that identifies the request in the cache and in the |
| 1164 // outstanding jobs map. | 1151 // outstanding jobs map. |
| 1165 Key key = GetEffectiveKeyForRequest(info); | 1152 Key key = GetEffectiveKeyForRequest(info); |
| 1166 | 1153 |
| 1167 // Check for IP literal. | 1154 int rv = ResolveHelper(request_id, key, info, addresses, |
| 1168 IPAddressNumber ip_number; | 1155 source_net_log, request_net_log); |
|
wtc
2011/10/11 02:42:53
This ResolveHelper call passes source_net_log, req
| |
| 1169 if (ParseIPLiteralToNumber(info.hostname(), &ip_number)) { | 1156 if (rv != ERR_DNS_CACHE_MISS) { |
| 1170 DCHECK_EQ(key.host_resolver_flags & | |
| 1171 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | | |
| 1172 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), | |
| 1173 0) << " Unhandled flag"; | |
| 1174 bool ipv6_disabled = default_address_family_ == ADDRESS_FAMILY_IPV4 && | |
| 1175 !ipv6_probe_monitoring_; | |
| 1176 int net_error = OK; | |
| 1177 if (ip_number.size() == 16 && ipv6_disabled) { | |
| 1178 net_error = ERR_NAME_NOT_RESOLVED; | |
| 1179 } else { | |
| 1180 *addresses = AddressList::CreateFromIPAddressWithCname( | |
| 1181 ip_number, info.port(), | |
| 1182 (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)); | |
| 1183 } | |
| 1184 // Update the net log and notify registered observers. | |
| 1185 OnFinishRequest(source_net_log, request_net_log, request_id, info, | 1157 OnFinishRequest(source_net_log, request_net_log, request_id, info, |
| 1186 net_error, 0 /* os_error (unknown since from cache) */); | 1158 rv, |
| 1187 return net_error; | 1159 0 /* os_error (unknown since from cache) */); |
| 1188 } | 1160 return rv; |
| 1189 | |
| 1190 // Sanity check -- it shouldn't be the case that allow_cached_response is | |
| 1191 // false while only_use_cached_response is true. | |
| 1192 DCHECK(info.allow_cached_response() || !info.only_use_cached_response()); | |
| 1193 | |
| 1194 // If callback is NULL, we must be doing cache-only lookup. | |
| 1195 DCHECK(callback || info.only_use_cached_response()); | |
| 1196 | |
| 1197 // If we have an unexpired cache entry, use it. | |
| 1198 if (info.allow_cached_response() && cache_.get()) { | |
| 1199 const HostCache::Entry* cache_entry = cache_->Lookup( | |
| 1200 key, base::TimeTicks::Now()); | |
| 1201 if (cache_entry) { | |
| 1202 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); | |
| 1203 int net_error = cache_entry->error; | |
| 1204 if (net_error == OK) { | |
| 1205 *addresses = CreateAddressListUsingPort( | |
| 1206 cache_entry->addrlist, info.port()); | |
| 1207 } | |
| 1208 | |
| 1209 // Update the net log and notify registered observers. | |
| 1210 OnFinishRequest(source_net_log, request_net_log, request_id, info, | |
| 1211 net_error, | |
| 1212 0 /* os_error (unknown since from cache) */); | |
| 1213 | |
| 1214 return net_error; | |
| 1215 } | |
| 1216 } | |
| 1217 | |
| 1218 if (info.only_use_cached_response()) { // Not allowed to do a real lookup. | |
| 1219 OnFinishRequest(source_net_log, | |
| 1220 request_net_log, | |
| 1221 request_id, | |
| 1222 info, | |
| 1223 ERR_NAME_NOT_RESOLVED, | |
| 1224 0); | |
| 1225 return ERR_NAME_NOT_RESOLVED; | |
| 1226 } | 1161 } |
| 1227 | 1162 |
| 1228 // Create a handle for this request, and pass it back to the user if they | 1163 // Create a handle for this request, and pass it back to the user if they |
| 1229 // asked for it (out_req != NULL). | 1164 // asked for it (out_req != NULL). |
| 1230 Request* req = new Request(source_net_log, request_net_log, request_id, info, | 1165 Request* req = new Request(source_net_log, request_net_log, request_id, info, |
| 1231 callback, addresses); | 1166 callback, addresses); |
| 1232 if (out_req) | 1167 if (out_req) |
| 1233 *out_req = reinterpret_cast<RequestHandle>(req); | 1168 *out_req = reinterpret_cast<RequestHandle>(req); |
| 1234 | 1169 |
| 1235 // Next we need to attach our request to a "job". This job is responsible for | 1170 // Next we need to attach our request to a "job". This job is responsible for |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1247 CreateAndStartJob(req); | 1182 CreateAndStartJob(req); |
| 1248 } else { | 1183 } else { |
| 1249 return EnqueueRequest(pool, req); | 1184 return EnqueueRequest(pool, req); |
| 1250 } | 1185 } |
| 1251 } | 1186 } |
| 1252 | 1187 |
| 1253 // Completion happens during OnJobComplete(Job*). | 1188 // Completion happens during OnJobComplete(Job*). |
| 1254 return ERR_IO_PENDING; | 1189 return ERR_IO_PENDING; |
| 1255 } | 1190 } |
| 1256 | 1191 |
| 1192 int HostResolverImpl::ResolveHelper(int request_id, | |
| 1193 const Key& key, | |
|
cbentzel
2011/08/04 21:18:36
Ah, I guess the OnStartRequest/OnFinishRequest can
| |
| 1194 const RequestInfo& info, | |
| 1195 AddressList* addresses, | |
| 1196 const BoundNetLog& request_net_log, | |
| 1197 const BoundNetLog& source_net_log) { | |
|
wtc
2011/10/11 02:42:53
ResolveHelper does not use its source_net_log argu
| |
| 1198 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. | |
| 1199 // On Windows it gives the default interface's address, whereas on Linux it | |
| 1200 // gives an error. We will make it fail on all platforms for consistency. | |
| 1201 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) | |
| 1202 return ERR_NAME_NOT_RESOLVED; | |
| 1203 | |
| 1204 int net_error = ERR_UNEXPECTED; | |
| 1205 if (ResolveAsIP(key, info, &net_error, addresses)) | |
| 1206 return net_error; | |
| 1207 net_error = ERR_DNS_CACHE_MISS; | |
| 1208 ServeFromCache(key, info, request_net_log, &net_error, addresses); | |
| 1209 return net_error; | |
| 1210 } | |
| 1211 | |
| 1212 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, | |
| 1213 AddressList* addresses, | |
| 1214 const BoundNetLog& source_net_log) { | |
| 1215 DCHECK(CalledOnValidThread()); | |
| 1216 DCHECK(addresses); | |
| 1217 | |
| 1218 // Choose a unique ID number for observers to see. | |
| 1219 int request_id = next_request_id_++; | |
| 1220 | |
| 1221 // Make a log item for the request. | |
| 1222 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, | |
| 1223 NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); | |
| 1224 | |
| 1225 // Update the net log and notify registered observers. | |
| 1226 OnStartRequest(source_net_log, request_net_log, request_id, info); | |
| 1227 | |
| 1228 // Build a key that identifies the request in the cache and in the | |
| 1229 // outstanding jobs map. | |
| 1230 Key key = GetEffectiveKeyForRequest(info); | |
| 1231 | |
| 1232 int rv = ResolveHelper(request_id, key, info, addresses, request_net_log, | |
| 1233 source_net_log); | |
| 1234 OnFinishRequest(source_net_log, request_net_log, request_id, info, | |
| 1235 rv, | |
| 1236 0 /* os_error (unknown since from cache) */); | |
| 1237 return rv; | |
| 1238 } | |
| 1239 | |
| 1257 // See OnJobComplete(Job*) for why it is important not to clean out | 1240 // See OnJobComplete(Job*) for why it is important not to clean out |
| 1258 // cancelled requests from Job::requests_. | 1241 // cancelled requests from Job::requests_. |
| 1259 void HostResolverImpl::CancelRequest(RequestHandle req_handle) { | 1242 void HostResolverImpl::CancelRequest(RequestHandle req_handle) { |
| 1260 DCHECK(CalledOnValidThread()); | 1243 DCHECK(CalledOnValidThread()); |
| 1261 Request* req = reinterpret_cast<Request*>(req_handle); | 1244 Request* req = reinterpret_cast<Request*>(req_handle); |
| 1262 DCHECK(req); | 1245 DCHECK(req); |
| 1263 | 1246 |
| 1264 scoped_ptr<Request> request_deleter; // Frees at end of function. | 1247 scoped_ptr<Request> request_deleter; // Frees at end of function. |
| 1265 | 1248 |
| 1266 if (!req->job()) { | 1249 if (!req->job()) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1306 } | 1289 } |
| 1307 | 1290 |
| 1308 AddressFamily HostResolverImpl::GetDefaultAddressFamily() const { | 1291 AddressFamily HostResolverImpl::GetDefaultAddressFamily() const { |
| 1309 return default_address_family_; | 1292 return default_address_family_; |
| 1310 } | 1293 } |
| 1311 | 1294 |
| 1312 HostResolverImpl* HostResolverImpl::GetAsHostResolverImpl() { | 1295 HostResolverImpl* HostResolverImpl::GetAsHostResolverImpl() { |
| 1313 return this; | 1296 return this; |
| 1314 } | 1297 } |
| 1315 | 1298 |
| 1299 | |
| 1300 bool HostResolverImpl::ResolveAsIP(const Key& key, | |
| 1301 const RequestInfo& info, | |
| 1302 int* net_error, | |
| 1303 AddressList* addresses) { | |
| 1304 DCHECK(addresses); | |
| 1305 DCHECK(net_error); | |
| 1306 IPAddressNumber ip_number; | |
| 1307 if (!ParseIPLiteralToNumber(key.hostname, &ip_number)) | |
| 1308 return false; | |
| 1309 | |
| 1310 DCHECK_EQ(key.host_resolver_flags & | |
| 1311 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | | |
| 1312 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), | |
| 1313 0) << " Unhandled flag"; | |
| 1314 bool ipv6_disabled = default_address_family_ == ADDRESS_FAMILY_IPV4 && | |
| 1315 !ipv6_probe_monitoring_; | |
| 1316 *net_error = OK; | |
| 1317 if (ip_number.size() == 16 && ipv6_disabled) { | |
| 1318 *net_error = ERR_NAME_NOT_RESOLVED; | |
| 1319 } else { | |
| 1320 *addresses = AddressList::CreateFromIPAddressWithCname( | |
| 1321 ip_number, info.port(), | |
| 1322 (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)); | |
| 1323 } | |
| 1324 return true; | |
| 1325 } | |
| 1326 | |
| 1327 bool HostResolverImpl::ServeFromCache(const Key& key, | |
| 1328 const RequestInfo& info, | |
| 1329 const BoundNetLog& request_net_log, | |
| 1330 int* net_error, | |
| 1331 AddressList* addresses) { | |
| 1332 DCHECK(addresses); | |
| 1333 DCHECK(net_error); | |
| 1334 if (!info.allow_cached_response() || !cache_.get()) | |
| 1335 return false; | |
| 1336 | |
| 1337 const HostCache::Entry* cache_entry = cache_->Lookup( | |
| 1338 key, base::TimeTicks::Now()); | |
| 1339 if (!cache_entry) | |
| 1340 return false; | |
| 1341 | |
| 1342 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); | |
| 1343 *net_error = cache_entry->error; | |
| 1344 if (*net_error == OK) | |
| 1345 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port()); | |
| 1346 return true; | |
| 1347 } | |
| 1348 | |
| 1316 void HostResolverImpl::AddOutstandingJob(Job* job) { | 1349 void HostResolverImpl::AddOutstandingJob(Job* job) { |
| 1317 scoped_refptr<Job>& found_job = jobs_[job->key()]; | 1350 scoped_refptr<Job>& found_job = jobs_[job->key()]; |
| 1318 DCHECK(!found_job); | 1351 DCHECK(!found_job); |
| 1319 found_job = job; | 1352 found_job = job; |
| 1320 | 1353 |
| 1321 JobPool* pool = GetPoolForRequest(job->initial_request()); | 1354 JobPool* pool = GetPoolForRequest(job->initial_request()); |
| 1322 pool->AdjustNumOutstandingJobs(1); | 1355 pool->AdjustNumOutstandingJobs(1); |
| 1323 } | 1356 } |
| 1324 | 1357 |
| 1325 HostResolverImpl::Job* HostResolverImpl::FindOutstandingJob(const Key& key) { | 1358 HostResolverImpl::Job* HostResolverImpl::FindOutstandingJob(const Key& key) { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1605 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; | 1638 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; |
| 1606 } else { | 1639 } else { |
| 1607 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; | 1640 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; |
| 1608 } | 1641 } |
| 1609 #endif | 1642 #endif |
| 1610 AbortAllInProgressJobs(); | 1643 AbortAllInProgressJobs(); |
| 1611 // |this| may be deleted inside AbortAllInProgressJobs(). | 1644 // |this| may be deleted inside AbortAllInProgressJobs(). |
| 1612 } | 1645 } |
| 1613 | 1646 |
| 1614 } // namespace net | 1647 } // namespace net |
| OLD | NEW |