diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-13 20:27:50 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-13 20:27:50 +0000 |
commit | b1d8c25b97a98dbde3d4e8c8c298b8f46a3ddb29 (patch) | |
tree | 841a45d29cb2a0b87d322f520560422b135a9051 /net/base/dnsrr_resolver.cc | |
parent | b16df4c69cedc3862c05c85cba62e2673a1ce345 (diff) | |
download | chromium_src-b1d8c25b97a98dbde3d4e8c8c298b8f46a3ddb29.zip chromium_src-b1d8c25b97a98dbde3d4e8c8c298b8f46a3ddb29.tar.gz chromium_src-b1d8c25b97a98dbde3d4e8c8c298b8f46a3ddb29.tar.bz2 |
net: enable DnsRRResolver on Windows
(Note that this code was developed by try-server so if something appears
to be terribly wrong, it probably is.)
BUG=none
TEST=net_unittests
http://codereview.chromium.org/6180001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71349 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/dnsrr_resolver.cc')
-rw-r--r-- | net/base/dnsrr_resolver.cc | 90 |
1 files changed, 86 insertions, 4 deletions
diff --git a/net/base/dnsrr_resolver.cc b/net/base/dnsrr_resolver.cc index 14b7b93..203ae52 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(); } |