Chromium Code Reviews| Index: net/dns/dns_response.cc |
| diff --git a/net/dns/dns_response.cc b/net/dns/dns_response.cc |
| index 760bd5b68064dbc60c6a0f5b14b63e3e9d9b6f71..ae2d386ec8a9000db31d0ea46754170ce368c24f 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,53 @@ const dns_protocol::Header* DnsResponse::header() const { |
| return reinterpret_cast<const dns_protocol::Header*>(io_buffer_->data()); |
| } |
| +bool DnsResponse::ParseAddressList(AddressList* addr_list, |
| + base::TimeDelta* ttl) const { |
| + DCHECK(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 = GetDottedName(); |
|
cbentzel
2012/02/14 02:01:54
It looks like both DNSDomainToString and ParseName
|
| + |
| + uint16 expected_type = qtype(); |
| + size_t expected_size = (qtype() == dns_protocol::kTypeAAAA) |
|
cbentzel
2012/02/14 02:01:54
Could use expected_type instead of qtype().
|
| + ? kIPv6AddressSize : kIPv4AddressSize; |
|
cbentzel
2012/02/14 02:01:54
Do you want to make sure the qtype is only one of
|
| + |
| + // 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 = Parser(); |
| + DnsResourceRecord record; |
| + while (parser.ParseRecord(&record)) { |
|
cbentzel
2012/02/14 02:01:54
Looks like this would accept a response for an A q
szym
2012/02/14 15:56:24
To answer both this and the next question:
I look
cbentzel
2012/02/14 18:01:27
I think that makes sense - this is unlikely to be
|
| + 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)) { |
|
cbentzel
2012/02/14 02:01:54
Are these guaranteed to always be in order of the
|
| + return false; |
| + } |
| + } else if (record.type == expected_type && |
| + record.rdata.size() == expected_size) { |
| + ip_addresses.push_back(IPAddressNumber(record.rdata.begin(), |
| + record.rdata.end())); |
| + ttl_sec = std::min(ttl_sec, record.ttl); |
|
cbentzel
2012/02/14 02:01:54
I thought TTL for all RRSet entries needed to be i
szym
2012/02/14 17:44:39
Not clear on this one. C-ares does not bundle the
cbentzel
2012/02/14 18:01:27
See http://tools.ietf.org/html/rfc2181#section-5 5
szym
2012/02/14 18:07:20
A good strategy could be to be strict initially, b
mmenke
2012/02/14 18:46:00
Agree that it would be great to have a number of n
mmenke
2012/02/14 18:46:00
I believe I saw a discussion somewhere (Maybe in a
|
| + 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 |