| Index: net/base/dnsrr_resolver.cc
|
| diff --git a/net/base/dnsrr_resolver.cc b/net/base/dnsrr_resolver.cc
|
| index 14b7b93ce9075314af82d6eddfd3456caebbddab..203ae523c556fc3a898b4fed866db9acc6cb4917 100644
|
| --- a/net/base/dnsrr_resolver.cc
|
| +++ b/net/base/dnsrr_resolver.cc
|
| @@ -8,6 +8,10 @@
|
| #include <resolv.h>
|
| #endif
|
|
|
| +#if defined(OS_WIN)
|
| +#include <windns.h>
|
| +#endif
|
| +
|
| #include "base/lock.h"
|
| #include "base/message_loop.h"
|
| #include "base/scoped_ptr.h"
|
| @@ -70,10 +74,30 @@
|
| //
|
| // Post
|
|
|
| -
|
| -
|
| namespace net {
|
|
|
| +#if defined(OS_WIN)
|
| +// DnsRRIsParsedByWindows returns true if Windows knows how to parse the given
|
| +// RR type. RR data is returned in a DNS_RECORD structure which may be raw (if
|
| +// Windows doesn't parse it) or may be a parse result. It's unclear how this
|
| +// API is intended to evolve in the future. If Windows adds support for new RR
|
| +// types in a future version a client which expected raw data will break.
|
| +// See http://msdn.microsoft.com/en-us/library/ms682082(v=vs.85).aspx
|
| +static bool DnsRRIsParsedByWindows(uint16 rrtype) {
|
| + // We only cover the types which are defined in dns_util.h
|
| + switch (rrtype) {
|
| + case kDNS_CNAME:
|
| + case kDNS_TXT:
|
| + case kDNS_DS:
|
| + case kDNS_RRSIG:
|
| + case kDNS_DNSKEY:
|
| + return true;
|
| + default:
|
| + return false;
|
| + }
|
| +}
|
| +#endif
|
| +
|
| static const uint16 kClassIN = 1;
|
| // kMaxCacheEntries is the number of RRResponse objects that we'll cache.
|
| static const unsigned kMaxCacheEntries = 32;
|
| @@ -233,9 +257,67 @@ class RRResolverWorker {
|
| return;
|
| }
|
|
|
| + // See http://msdn.microsoft.com/en-us/library/ms682016(v=vs.85).aspx
|
| + PDNS_RECORD record = NULL;
|
| + DNS_STATUS status =
|
| + DnsQuery_A(name_.c_str(), rrtype_, DNS_QUERY_STANDARD,
|
| + NULL /* pExtra (reserved) */, &record, NULL /* pReserved */);
|
| response_.fetch_time = base::Time::Now();
|
| - response_.negative = true;
|
| - result_ = ERR_NAME_NOT_RESOLVED;
|
| + response_.name = name_;
|
| + response_.dnssec = false;
|
| + response_.ttl = 0;
|
| +
|
| + if (status != 0) {
|
| + response_.negative = true;
|
| + result_ = ERR_NAME_NOT_RESOLVED;
|
| + } else {
|
| + response_.negative = false;
|
| + result_ = OK;
|
| + for (DNS_RECORD* cur = record; cur; cur = cur->pNext) {
|
| + if (cur->wType == rrtype_) {
|
| + response_.ttl = record->dwTtl;
|
| + // Windows will parse some types of resource records. If we want one
|
| + // of these types then we have to reserialise the record.
|
| + switch (rrtype_) {
|
| + case kDNS_TXT: {
|
| + // http://msdn.microsoft.com/en-us/library/ms682109(v=vs.85).aspx
|
| + const DNS_TXT_DATA* txt = &cur->Data.TXT;
|
| + std::string rrdata;
|
| +
|
| + for (DWORD i = 0; i < txt->dwStringCount; i++) {
|
| + // Although the string is typed as a PWSTR, it's actually just
|
| + // an ASCII byte-string. Also, the string must be < 256
|
| + // elements because the length in the DNS packet is a single
|
| + // byte.
|
| + const char* s = reinterpret_cast<char*>(txt->pStringArray[i]);
|
| + size_t len = strlen(s);
|
| + DCHECK_LT(len, 256u);
|
| + char len8 = static_cast<char>(len);
|
| + rrdata.push_back(len8);
|
| + rrdata += s;
|
| + }
|
| + response_.rrdatas.push_back(rrdata);
|
| + break;
|
| + }
|
| + default:
|
| + if (DnsRRIsParsedByWindows(rrtype_)) {
|
| + // Windows parses this type, but we don't have code to unparse
|
| + // it.
|
| + NOTREACHED() << "you need to add code for the RR type here";
|
| + response_.negative = true;
|
| + result_ = ERR_INVALID_ARGUMENT;
|
| + } else {
|
| + // This type is given to us raw.
|
| + response_.rrdatas.push_back(
|
| + std::string(reinterpret_cast<char*>(&cur->Data),
|
| + cur->wDataLength));
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + DnsRecordListFree(record, DnsFreeRecordList);
|
| Finish();
|
| }
|
|
|
|
|