| Index: net/dns/dns_response.cc
|
| diff --git a/net/dns/dns_response.cc b/net/dns/dns_response.cc
|
| index 760bd5b68064dbc60c6a0f5b14b63e3e9d9b6f71..0df83c4b88eafad6bfef2e119e5fac050da0f045 100644
|
| --- a/net/dns/dns_response.cc
|
| +++ b/net/dns/dns_response.cc
|
| @@ -5,6 +5,7 @@
|
| #include "net/dns/dns_response.h"
|
|
|
| #include "base/sys_byteorder.h"
|
| +#include "net/base/address_list.h"
|
| #include "net/base/big_endian.h"
|
| #include "net/base/dns_util.h"
|
| #include "net/base/io_buffer.h"
|
| @@ -220,4 +221,51 @@ const dns_protocol::Header* DnsResponse::header() const {
|
| return reinterpret_cast<const dns_protocol::Header*>(io_buffer_->data());
|
| }
|
|
|
| +bool DnsResponseToAddressList(const DnsResponse* response,
|
| + AddressList* addr_list,
|
| + base::TimeDelta* ttl) {
|
| + DCHECK(response->IsValid());
|
| + // DnsTransaction already verified that |response| matches the issued query
|
| + // in terms of query header. We still need to determine if there is a valid
|
| + // chain of CNAMEs from the query name to the RR owner name.
|
| +
|
| + // Expected owner of record.
|
| + std::string expected_name = response->GetDottedName();
|
| +
|
| + // getcanonname in eglibc returns the first owner name of an A or AAAA RR.
|
| + std::string canon_name;
|
| +
|
| + uint32 ttl_sec = kuint32max;
|
| + IPAddressList ip_addresses;
|
| + DnsRecordParser parser = response->Parser();
|
| + DnsResourceRecord record;
|
| + while (parser.ParseRecord(&record)) {
|
| + if (record.name != expected_name) {
|
| + // We ignore records owned by unexpected name.
|
| + continue;
|
| + }
|
| + if (record.type == dns_protocol::kTypeCNAME) {
|
| + // New |hostname|, following the CNAME chain.
|
| + if (!parser.ParseName(record.rdata.begin(), &expected_name)) {
|
| + return false;
|
| + }
|
| + } else if (record.type == response->qtype() &&
|
| + (record.rdata.size() == kIPv4AddressSize ||
|
| + record.rdata.size() == kIPv6AddressSize)) {
|
| + ip_addresses.push_back(IPAddressNumber(record.rdata.begin(),
|
| + record.rdata.end()));
|
| + ttl_sec = std::min(ttl_sec, record.ttl);
|
| + if (canon_name.empty())
|
| + canon_name = record.name;
|
| + }
|
| + }
|
| + if (ip_addresses.empty())
|
| + return false;
|
| +
|
| + *addr_list = AddressList::CreateFromIPAddressList(ip_addresses,
|
| + canon_name);
|
| + *ttl = base::TimeDelta::FromSeconds(ttl_sec);
|
| + return true;
|
| +}
|
| +
|
| } // namespace net
|
|
|