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 |