summaryrefslogtreecommitdiffstats
path: root/net/base/dnsrr_resolver.cc
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-13 20:27:50 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-13 20:27:50 +0000
commitb1d8c25b97a98dbde3d4e8c8c298b8f46a3ddb29 (patch)
tree841a45d29cb2a0b87d322f520560422b135a9051 /net/base/dnsrr_resolver.cc
parentb16df4c69cedc3862c05c85cba62e2673a1ce345 (diff)
downloadchromium_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.cc90
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();
}