Chromium Code Reviews| Index: net/base/dnsrr_resolver.cc |
| diff --git a/net/base/dnsrr_resolver.cc b/net/base/dnsrr_resolver.cc |
| index 14b7b93ce9075314af82d6eddfd3456caebbddab..f650c3f4d2d7944060d6d8074d031070c4078eda 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) { |
|
eroman
2011/01/12 05:21:39
Isn't this condition reversed? I thought success w
agl
2011/01/12 15:52:25
All the documentation says is "Returns success con
|
| + 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 += std::string(&len8, 1); |
|
eroman
2011/01/12 05:21:39
why not:
rdata->append(len8);
agl
2011/01/12 15:52:25
I can't see an append(charT) method documented on
|
| + 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(); |
| } |