Chromium Code Reviews| Index: net/dns/async_host_resolver.cc |
| diff --git a/net/dns/async_host_resolver.cc b/net/dns/async_host_resolver.cc |
| index 1666e04ce2eb3cd15ad9f6bef7c8c4df98720188..121ac1cbc4a83aff4ebc269fc05a3642a8e8a8e0 100644 |
| --- a/net/dns/async_host_resolver.cc |
| +++ b/net/dns/async_host_resolver.cc |
| @@ -8,12 +8,16 @@ |
| #include "base/bind.h" |
| #include "base/logging.h" |
| +#include "base/message_loop.h" |
| #include "base/rand_util.h" |
| #include "base/stl_util.h" |
| #include "base/values.h" |
| #include "net/base/address_list.h" |
| #include "net/base/dns_util.h" |
| #include "net/base/net_errors.h" |
| +#include "net/dns/dns_protocol.h" |
| +#include "net/dns/dns_response.h" |
| +#include "net/dns/dns_session.h" |
| #include "net/socket/client_socket_factory.h" |
| namespace net { |
| @@ -22,7 +26,7 @@ namespace { |
| // TODO(agayev): fix this when IPv6 support is added. |
| uint16 QueryTypeFromAddressFamily(AddressFamily address_family) { |
| - return kDNS_A; |
| + return dns_protocol::kTypeA; |
| } |
| class RequestParameters : public NetLog::EventParameters { |
| @@ -60,13 +64,18 @@ HostResolver* CreateAsyncHostResolver(size_t max_concurrent_resolves, |
| if (max_transactions == 0) |
| max_transactions = 20; |
| size_t max_pending_requests = max_transactions * 100; |
| + DnsConfig config; |
| + config.nameservers.push_back(IPEndPoint(dns_ip, 53)); |
| + DnsSession* session = new DnsSession( |
| + config, |
| + ClientSocketFactory::GetDefaultFactory(), |
| + base::Bind(&base::RandInt), |
| + net_log); |
| HostResolver* resolver = new AsyncHostResolver( |
| - IPEndPoint(dns_ip, 53), |
| max_transactions, |
| max_pending_requests, |
| - base::Bind(&base::RandInt), |
| HostCache::CreateDefaultCache(), |
| - NULL, |
| + DnsClient::CreateClient(session), |
| net_log); |
| return resolver; |
| } |
| @@ -193,19 +202,15 @@ class AsyncHostResolver::Request { |
| }; |
| //----------------------------------------------------------------------------- |
| -AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server, |
| - size_t max_transactions, |
| +AsyncHostResolver::AsyncHostResolver(size_t max_transactions, |
| size_t max_pending_requests, |
| - const RandIntCallback& rand_int_cb, |
| HostCache* cache, |
| - ClientSocketFactory* factory, |
| + DnsClient* client, |
| NetLog* net_log) |
| : max_transactions_(max_transactions), |
| max_pending_requests_(max_pending_requests), |
| - dns_server_(dns_server), |
| - rand_int_cb_(rand_int_cb), |
| cache_(cache), |
| - factory_(factory), |
| + client_(client), |
| net_log_(net_log) { |
| } |
| @@ -216,7 +221,7 @@ AsyncHostResolver::~AsyncHostResolver() { |
| STLDeleteElements(&it->second); |
| // Destroy transactions. |
| - STLDeleteElements(&transactions_); |
| + STLDeleteElements(&dns_requests_); |
| // Destroy pending requests. |
| for (size_t i = 0; i < arraysize(pending_requests_); ++i) |
| @@ -240,7 +245,7 @@ int AsyncHostResolver::Resolve(const RequestInfo& info, |
| rv = request->result(); |
| else if (AttachToRequestList(request.get())) |
| rv = ERR_IO_PENDING; |
| - else if (transactions_.size() < max_transactions_) |
| + else if (dns_requests_.size() < max_transactions_) |
| rv = StartNewTransactionFor(request.get()); |
| else |
| rv = Enqueue(request.get()); |
| @@ -327,26 +332,45 @@ HostCache* AsyncHostResolver::GetHostCache() { |
| return cache_.get(); |
| } |
| -void AsyncHostResolver::OnTransactionComplete( |
| +void AsyncHostResolver::OnRequestComplete( |
| + DnsClient::Request* dns_req, |
| int result, |
| - const DnsTransaction* transaction, |
| - const IPAddressList& ip_addresses) { |
| - DCHECK(std::find(transactions_.begin(), transactions_.end(), transaction) |
| - != transactions_.end()); |
| - DCHECK(requestlist_map_.find(transaction->key()) != requestlist_map_.end()); |
| + const DnsResponse* response) { |
| + DCHECK(std::find(dns_requests_.begin(), dns_requests_.end(), dns_req) |
| + != dns_requests_.end()); |
| // If by the time requests that caused |transaction| are cancelled, we do |
| // not have a port number to associate with the result, therefore, we |
| // assume the most common port, otherwise we use the port number of the |
| // first request. |
| - RequestList& requests = requestlist_map_[transaction->key()]; |
| + KeyRequestListMap::iterator rit = requestlist_map_.find( |
| + std::make_pair(dns_req->qname(), dns_req->qtype())); |
| + DCHECK(rit != requestlist_map_.end()); |
| + RequestList& requests = rit->second; |
| int port = requests.empty() ? 80 : requests.front()->info().port(); |
| + // Extract AddressList out of DnsResponse. |
| + AddressList addrlist; |
|
mmenke
2011/12/02 00:53:55
nit: Should be an underscore between words: addr
szym
2011/12/05 23:06:28
Done.
|
| + if (result == OK) { |
| + IPAddressList ip_addresses; |
| + DnsRecordParser parser = response->Parser(); |
| + DnsResourceRecord record; |
| + // TODO(szym): add stricter checking of names, aliases and address lengths |
|
mmenke
2011/12/02 00:53:55
Nit: Capitalize "add", add period.
szym
2011/12/05 23:06:28
Done.
|
| + while (parser.ParseRecord(&record)) { |
| + if (record.type == dns_req->qtype() && |
| + (record.rdata.size() == kIPv4AddressSize || |
| + record.rdata.size() == kIPv6AddressSize)) |
|
mmenke
2011/12/02 00:53:55
Chrome style is to use braces on if statements, wh
szym
2011/12/05 23:06:28
Done.
|
| + ip_addresses.push_back(IPAddressNumber(record.rdata.begin(), |
| + record.rdata.end())); |
| + } |
| + if (!ip_addresses.empty()) |
| + addrlist = AddressList::CreateFromIPAddressList(ip_addresses, port); |
| + else |
| + result = ERR_DNS_MALFORMED_RESPONSE; |
| + } |
| + |
| // Run callback of every request that was depending on this transaction, |
| // also notify observers. |
| - AddressList addrlist; |
| - if (result == OK) |
| - addrlist = AddressList::CreateFromIPAddressList(ip_addresses, port); |
| for (RequestList::iterator it = requests.begin(); it != requests.end(); |
| ++it) |
| (*it)->OnAsyncComplete(result, addrlist); |
| @@ -372,11 +396,11 @@ void AsyncHostResolver::OnTransactionComplete( |
| // Cleanup requests. |
| STLDeleteElements(&requests); |
| - requestlist_map_.erase(transaction->key()); |
| + requestlist_map_.erase(rit); |
| // Cleanup transaction and start a new one if there are pending requests. |
| - delete transaction; |
| - transactions_.remove(transaction); |
| + delete dns_req; |
| + dns_requests_.remove(dns_req); |
| ProcessPending(); |
| } |
| @@ -401,23 +425,19 @@ bool AsyncHostResolver::AttachToRequestList(Request* request) { |
| int AsyncHostResolver::StartNewTransactionFor(Request* request) { |
| DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end()); |
| - DCHECK(transactions_.size() < max_transactions_); |
| + DCHECK(dns_requests_.size() < max_transactions_); |
| request->request_net_log().AddEvent( |
| NetLog::TYPE_ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION, NULL); |
| requestlist_map_[request->key()].push_back(request); |
| - DnsTransaction* transaction = new DnsTransaction( |
| - dns_server_, |
| + DnsClient::Request* dns_req = client_->CreateRequest( |
| request->key().first, |
| request->key().second, |
| - rand_int_cb_, |
| - factory_, |
| - request->request_net_log(), |
| - net_log_); |
| - transaction->SetDelegate(this); |
| - transactions_.push_back(transaction); |
| - return transaction->Start(); |
| + base::Bind(&AsyncHostResolver::OnRequestComplete, base::Unretained(this)), |
| + request->request_net_log()); |
| + dns_requests_.push_back(dns_req); |
| + return dns_req->Start(); |
| } |
| int AsyncHostResolver::Enqueue(Request* request) { |