Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: net/base/host_resolver_impl.cc

Issue 7492059: HostResolver: don't interpret NULL callback argument as a request to do synchronous resolution. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged common code from Resolve and ResolveFromCache to a single function. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/host_resolver_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/host_resolver_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698