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 |