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) { |