• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/dns/dns_response.h"
6 
7 #include <algorithm>
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/big_endian.h"
13 #include "base/check.h"
14 #include "base/containers/span.h"
15 #include "base/strings/string_piece.h"
16 #include "base/time/time.h"
17 #include "net/base/io_buffer.h"
18 #include "net/dns/dns_names_util.h"
19 #include "net/dns/dns_query.h"
20 #include "net/dns/dns_test_util.h"
21 #include "net/dns/public/dns_protocol.h"
22 #include "net/dns/record_rdata.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/abseil-cpp/absl/types/optional.h"
26 
27 namespace net {
28 
29 namespace {
30 
TEST(DnsRecordParserTest,Constructor)31 TEST(DnsRecordParserTest, Constructor) {
32   const char data[] = { 0 };
33 
34   EXPECT_FALSE(DnsRecordParser().IsValid());
35   EXPECT_TRUE(DnsRecordParser(data, 1, 0, 0).IsValid());
36   EXPECT_TRUE(DnsRecordParser(data, 1, 1, 0).IsValid());
37 
38   EXPECT_FALSE(DnsRecordParser(data, 1, 0, 0).AtEnd());
39   EXPECT_TRUE(DnsRecordParser(data, 1, 1, 0).AtEnd());
40 }
41 
TEST(DnsRecordParserTest,ReadName)42 TEST(DnsRecordParserTest, ReadName) {
43   const uint8_t data[] = {
44       // all labels "foo.example.com"
45       0x03, 'f', 'o', 'o', 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0x03, 'c',
46       'o', 'm',
47       // byte 0x10
48       0x00,
49       // byte 0x11
50       // part label, part pointer, "bar.example.com"
51       0x03, 'b', 'a', 'r', 0xc0, 0x04,
52       // byte 0x17
53       // all pointer to "bar.example.com", 2 jumps
54       0xc0, 0x11,
55       // byte 0x1a
56   };
57 
58   std::string out;
59   DnsRecordParser parser(data, sizeof(data), 0, /*num_records=*/0);
60   ASSERT_TRUE(parser.IsValid());
61 
62   EXPECT_EQ(0x11u, parser.ReadName(data + 0x00, &out));
63   EXPECT_EQ("foo.example.com", out);
64   // Check that the last "." is never stored.
65   out.clear();
66   EXPECT_EQ(0x1u, parser.ReadName(data + 0x10, &out));
67   EXPECT_EQ("", out);
68   out.clear();
69   EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, &out));
70   EXPECT_EQ("bar.example.com", out);
71   out.clear();
72   EXPECT_EQ(0x2u, parser.ReadName(data + 0x17, &out));
73   EXPECT_EQ("bar.example.com", out);
74 
75   // Parse name without storing it.
76   EXPECT_EQ(0x11u, parser.ReadName(data + 0x00, nullptr));
77   EXPECT_EQ(0x1u, parser.ReadName(data + 0x10, nullptr));
78   EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, nullptr));
79   EXPECT_EQ(0x2u, parser.ReadName(data + 0x17, nullptr));
80 
81   // Check that it works even if initial position is different.
82   parser = DnsRecordParser(data, sizeof(data), 0x12, /*num_records=*/0);
83   EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, nullptr));
84 }
85 
TEST(DnsRecordParserTest,ReadNameFail)86 TEST(DnsRecordParserTest, ReadNameFail) {
87   const uint8_t data[] = {
88       // label length beyond packet
89       0x30, 'x', 'x', 0x00,
90       // pointer offset beyond packet
91       0xc0, 0x20,
92       // pointer loop
93       0xc0, 0x08, 0xc0, 0x06,
94       // incorrect label type (currently supports only direct and pointer)
95       0x80, 0x00,
96       // truncated name (missing root label)
97       0x02, 'x', 'x',
98   };
99 
100   DnsRecordParser parser(data, sizeof(data), 0, /*num_records=*/0);
101   ASSERT_TRUE(parser.IsValid());
102 
103   std::string out;
104   EXPECT_EQ(0u, parser.ReadName(data + 0x00, &out));
105   EXPECT_EQ(0u, parser.ReadName(data + 0x04, &out));
106   EXPECT_EQ(0u, parser.ReadName(data + 0x08, &out));
107   EXPECT_EQ(0u, parser.ReadName(data + 0x0a, &out));
108   EXPECT_EQ(0u, parser.ReadName(data + 0x0c, &out));
109   EXPECT_EQ(0u, parser.ReadName(data + 0x0e, &out));
110 }
111 
112 // Returns an RFC 1034 style domain name with a length of |name_len|.
113 // Also writes the expected dotted string representation into |dotted_str|,
114 // which must be non-null.
BuildRfc1034Name(const size_t name_len,std::string * dotted_str)115 std::vector<uint8_t> BuildRfc1034Name(const size_t name_len,
116                                       std::string* dotted_str) {
117   // Impossible length. If length not zero, need at least 2 to allow label
118   // length and label contents.
119   CHECK_NE(name_len, 1u);
120 
121   CHECK(dotted_str != nullptr);
122   auto ChoosePrintableCharLambda = [](uint8_t n) { return n % 26 + 'A'; };
123   const size_t max_label_len = 63;
124   std::vector<uint8_t> data;
125 
126   dotted_str->clear();
127   while (data.size() < name_len) {
128     // Compute the size of the next label.
129     //
130     // No need to account for next label length because the final zero length is
131     // not considered included in overall length.
132     size_t label_len = std::min(name_len - data.size() - 1, max_label_len);
133     // Need to ensure the remainder is not 1 because that would leave room for a
134     // label length but not a label.
135     if (name_len - data.size() - label_len - 1 == 1) {
136       CHECK_GT(label_len, 1u);
137       label_len -= 1;
138     }
139 
140     // Write the length octet
141     data.push_back(label_len);
142 
143     // Write |label_len| bytes of label data
144     const size_t size_with_label = data.size() + label_len;
145     while (data.size() < size_with_label) {
146       const uint8_t chr = ChoosePrintableCharLambda(data.size());
147       data.push_back(chr);
148       dotted_str->push_back(chr);
149 
150       CHECK(data.size() <= name_len);
151     }
152 
153     // Write a trailing dot after every label
154     dotted_str->push_back('.');
155   }
156 
157   // Omit the final dot
158   if (!dotted_str->empty())
159     dotted_str->pop_back();
160 
161   CHECK(data.size() == name_len);
162 
163   // Final zero-length label (not considered included in overall length).
164   data.push_back(0);
165 
166   return data;
167 }
168 
TEST(DnsRecordParserTest,ReadNameGoodLength)169 TEST(DnsRecordParserTest, ReadNameGoodLength) {
170   const size_t name_len_cases[] = {2, 10, 40, 250, 254, 255};
171 
172   for (auto name_len : name_len_cases) {
173     std::string expected_name;
174     const std::vector<uint8_t> data_vector =
175         BuildRfc1034Name(name_len, &expected_name);
176     ASSERT_EQ(data_vector.size(), name_len + 1);
177     const uint8_t* data = data_vector.data();
178 
179     DnsRecordParser parser(data, data_vector.size(), 0, /*num_records=*/0);
180     ASSERT_TRUE(parser.IsValid());
181 
182     std::string out;
183     EXPECT_EQ(data_vector.size(), parser.ReadName(data, &out));
184     EXPECT_EQ(expected_name, out);
185   }
186 }
187 
188 // Tests against incorrect name length validation, which is anti-pattern #3 from
189 // the "NAME:WRECK" report:
190 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsRecordParserTest,ReadNameTooLongFail)191 TEST(DnsRecordParserTest, ReadNameTooLongFail) {
192   const size_t name_len_cases[] = {256, 257, 258, 300, 10000};
193 
194   for (auto name_len : name_len_cases) {
195     std::string expected_name;
196     const std::vector<uint8_t> data_vector =
197         BuildRfc1034Name(name_len, &expected_name);
198     ASSERT_EQ(data_vector.size(), name_len + 1);
199     const uint8_t* data = data_vector.data();
200 
201     DnsRecordParser parser(data, data_vector.size(), 0, /*num_records=*/0);
202     ASSERT_TRUE(parser.IsValid());
203 
204     std::string out;
205     EXPECT_EQ(0u, parser.ReadName(data, &out));
206   }
207 }
208 
209 // Tests against incorrect name compression pointer validation, which is anti-
210 // pattern #6 from the "NAME:WRECK" report:
211 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsRecordParserTest,RejectsNamesWithLoops)212 TEST(DnsRecordParserTest, RejectsNamesWithLoops) {
213   const char kData[] =
214       "\003www\007example\300\031"  // www.example with pointer to byte 25
215       "aaaaaaaaaaa"                 // Garbage data to spread things out.
216       "\003foo\300\004";            // foo with pointer to byte 4.
217 
218   DnsRecordParser parser(kData, /*length=*/sizeof(kData) - 1, /*offset=*/0,
219                          /*num_records=*/0);
220   ASSERT_TRUE(parser.IsValid());
221 
222   std::string out;
223   EXPECT_EQ(0u, parser.ReadName(kData, &out));
224 }
225 
226 // Tests against incorrect name compression pointer validation, which is anti-
227 // pattern #6 from the "NAME:WRECK" report:
228 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsRecordParserTest,RejectsNamesPointingOutsideData)229 TEST(DnsRecordParserTest, RejectsNamesPointingOutsideData) {
230   const char kData[] =
231       "\003www\007example\300\031";  // www.example with pointer to byte 25
232 
233   DnsRecordParser parser(kData, /*length=*/sizeof(kData) - 1, /*offset=*/0,
234                          /*num_records=*/0);
235   ASSERT_TRUE(parser.IsValid());
236 
237   std::string out;
238   EXPECT_EQ(0u, parser.ReadName(kData, &out));
239 }
240 
TEST(DnsRecordParserTest,ParsesValidPointer)241 TEST(DnsRecordParserTest, ParsesValidPointer) {
242   const char kData[] =
243       "\003www\007example\300\022"  // www.example with pointer to byte 25.
244       "aaaa"                        // Garbage data to spread things out.
245       "\004test\000";               // .test
246 
247   DnsRecordParser parser(kData, /*length=*/sizeof(kData) - 1, /*offset=*/0,
248                          /*num_records=*/0);
249   ASSERT_TRUE(parser.IsValid());
250 
251   std::string out;
252   EXPECT_EQ(14u, parser.ReadName(kData, &out));
253   EXPECT_EQ(out, "www.example.test");
254 }
255 
256 // Per RFC 1035, section 4.1.4, the first 2 bits of a DNS name label determine
257 // if it is a length label (if the bytes are 00) or a pointer label (if the
258 // bytes are 11). It is a common DNS parsing bug to treat 01 or 10 as pointer
259 // labels, but these are reserved and invalid. Such labels should always result
260 // in DnsRecordParser rejecting the name.
261 //
262 // Tests against incorrect name compression pointer validation, which is anti-
263 // pattern #6 from the "NAME:WRECK" report:
264 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsRecordParserTest,RejectsNamesWithInvalidLabelTypeAsPointer)265 TEST(DnsRecordParserTest, RejectsNamesWithInvalidLabelTypeAsPointer) {
266   const char kData[] =
267       "\003www\007example\200\022"  // www.example with invalid label as pointer
268       "aaaa"                        // Garbage data to spread things out.
269       "\004test\000";               // .test
270 
271   DnsRecordParser parser(kData, /*length=*/sizeof(kData) - 1, /*offset=*/0,
272                          /*num_records=*/0);
273   ASSERT_TRUE(parser.IsValid());
274 
275   std::string out;
276   EXPECT_EQ(0u, parser.ReadName(kData, &out));
277 }
278 
279 // Per RFC 1035, section 4.1.4, the first 2 bits of a DNS name label determine
280 // if it is a length label (if the bytes are 00) or a pointer label (if the
281 // bytes are 11). Such labels should always result in DnsRecordParser rejecting
282 // the name.
283 //
284 // Tests against incorrect name compression pointer validation, which is anti-
285 // pattern #6 from the "NAME:WRECK" report:
286 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsRecordParserTest,RejectsNamesWithInvalidLabelTypeAsLength)287 TEST(DnsRecordParserTest, RejectsNamesWithInvalidLabelTypeAsLength) {
288   const char kData[] =
289       "\003www\007example\104"  // www.example with invalid label as length
290       "test\000";  // test. (in case \104 is interpreted as length=4)
291 
292   // Append a bunch of zeroes to the buffer in case \104 is interpreted as a
293   // long length.
294   std::string data(kData, sizeof(kData) - 1);
295   data.append(256, '\000');
296 
297   DnsRecordParser parser(data.data(), data.size(), /*offset=*/0,
298                          /*num_records=*/0);
299   ASSERT_TRUE(parser.IsValid());
300 
301   std::string out;
302   EXPECT_EQ(0u, parser.ReadName(data.data(), &out));
303 }
304 
TEST(DnsRecordParserTest,ReadRecord)305 TEST(DnsRecordParserTest, ReadRecord) {
306   const uint8_t data[] = {
307       // Type CNAME record.
308       0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00, 0x00,
309       0x05,                    // TYPE is CNAME.
310       0x00, 0x01,              // CLASS is IN.
311       0x00, 0x01, 0x24, 0x74,  // TTL is 0x00012474.
312       0x00, 0x06,              // RDLENGTH is 6 bytes.
313       0x03, 'f', 'o', 'o',     // compressed name in record
314       0xc0, 0x00,
315       // Type A record.
316       0x03, 'b', 'a', 'r',     // compressed owner name
317       0xc0, 0x00, 0x00, 0x01,  // TYPE is A.
318       0x00, 0x01,              // CLASS is IN.
319       0x00, 0x20, 0x13, 0x55,  // TTL is 0x00201355.
320       0x00, 0x04,              // RDLENGTH is 4 bytes.
321       0x7f, 0x02, 0x04, 0x01,  // IP is 127.2.4.1
322   };
323 
324   std::string out;
325   DnsRecordParser parser(data, sizeof(data), 0, /*num_records=*/2);
326 
327   DnsResourceRecord record;
328   EXPECT_TRUE(parser.ReadRecord(&record));
329   EXPECT_EQ("example.com", record.name);
330   EXPECT_EQ(dns_protocol::kTypeCNAME, record.type);
331   EXPECT_EQ(dns_protocol::kClassIN, record.klass);
332   EXPECT_EQ(0x00012474u, record.ttl);
333   EXPECT_EQ(6u, record.rdata.length());
334   EXPECT_EQ(6u, parser.ReadName(record.rdata.data(), &out));
335   EXPECT_EQ("foo.example.com", out);
336   EXPECT_FALSE(parser.AtEnd());
337 
338   EXPECT_TRUE(parser.ReadRecord(&record));
339   EXPECT_EQ("bar.example.com", record.name);
340   EXPECT_EQ(dns_protocol::kTypeA, record.type);
341   EXPECT_EQ(dns_protocol::kClassIN, record.klass);
342   EXPECT_EQ(0x00201355u, record.ttl);
343   EXPECT_EQ(4u, record.rdata.length());
344   EXPECT_EQ(base::StringPiece("\x7f\x02\x04\x01"), record.rdata);
345   EXPECT_TRUE(parser.AtEnd());
346 
347   // Test truncated record.
348   parser = DnsRecordParser(data, sizeof(data) - 2, 0, /*num_records=*/2);
349   EXPECT_TRUE(parser.ReadRecord(&record));
350   EXPECT_FALSE(parser.AtEnd());
351   EXPECT_FALSE(parser.ReadRecord(&record));
352 }
353 
TEST(DnsRecordParserTest,ReadsRecordWithLongName)354 TEST(DnsRecordParserTest, ReadsRecordWithLongName) {
355   std::string dotted_name;
356   const std::vector<uint8_t> dns_name =
357       BuildRfc1034Name(dns_protocol::kMaxNameLength, &dotted_name);
358 
359   std::string data(reinterpret_cast<const char*>(dns_name.data()),
360                    dns_name.size());
361   data.append(
362       "\x00\x01"           // TYPE=A
363       "\x00\x01"           // CLASS=IN
364       "\x00\x01\x51\x80"   // TTL=1 day
365       "\x00\x04"           // RDLENGTH=4 bytes
366       "\xc0\xa8\x00\x01",  // 192.168.0.1
367       14);
368 
369   DnsRecordParser parser(data.data(), data.size(), 0, /*num_records=*/1);
370 
371   DnsResourceRecord record;
372   EXPECT_TRUE(parser.ReadRecord(&record));
373 }
374 
375 // Tests against incorrect name length validation, which is anti-pattern #3 from
376 // the "NAME:WRECK" report:
377 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsRecordParserTest,RejectRecordWithTooLongName)378 TEST(DnsRecordParserTest, RejectRecordWithTooLongName) {
379   std::string dotted_name;
380   const std::vector<uint8_t> dns_name =
381       BuildRfc1034Name(dns_protocol::kMaxNameLength + 1, &dotted_name);
382 
383   std::string data(reinterpret_cast<const char*>(dns_name.data()),
384                    dns_name.size());
385   data.append(
386       "\x00\x01"           // TYPE=A
387       "\x00\x01"           // CLASS=IN
388       "\x00\x01\x51\x80"   // TTL=1 day
389       "\x00\x04"           // RDLENGTH=4 bytes
390       "\xc0\xa8\x00\x01",  // 192.168.0.1
391       14);
392 
393   DnsRecordParser parser(data.data(), data.size(), 0, /*num_records=*/1);
394 
395   DnsResourceRecord record;
396   EXPECT_FALSE(parser.ReadRecord(&record));
397 }
398 
399 // Test that a record cannot be parsed with a name extending past the end of the
400 // data.
401 // Tests against incorrect name length validation, which is anti-pattern #3 from
402 // the "NAME:WRECK" report:
403 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsRecordParserTest,RejectRecordWithNonendedName)404 TEST(DnsRecordParserTest, RejectRecordWithNonendedName) {
405   const char kNonendedName[] = "\003www\006google\006www";
406 
407   DnsRecordParser parser(kNonendedName, sizeof(kNonendedName) - 1, 0,
408                          /*num_records=*/1);
409 
410   DnsResourceRecord record;
411   EXPECT_FALSE(parser.ReadRecord(&record));
412 }
413 
414 // Test that a record cannot be parsed with a name without final null
415 // termination. Parsing should assume the name has not ended and find the first
416 // byte of the TYPE field instead, making the remainder of the record
417 // unparsable.
418 // Tests against incorrect name null termination, which is anti-pattern #4 from
419 // the "NAME:WRECK" report:
420 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsRecordParserTest,RejectRecordNameMissingNullTermination)421 TEST(DnsRecordParserTest, RejectRecordNameMissingNullTermination) {
422   const char kData[] =
423       "\003www\006google\004test"  // Name without termination.
424       "\x00\x01"                   // TYPE=A
425       "\x00\x01"                   // CLASS=IN
426       "\x00\x01\x51\x80"           // TTL=1 day
427       "\x00\x04"                   // RDLENGTH=4 bytes
428       "\xc0\xa8\x00\x01";          // 192.168.0.1
429 
430   DnsRecordParser parser(kData, sizeof(kData) - 1, 0, /*num_records=*/1);
431 
432   DnsResourceRecord record;
433   EXPECT_FALSE(parser.ReadRecord(&record));
434 }
435 
436 // Test that no more records can be parsed once the claimed number of records
437 // have been parsed.
TEST(DnsRecordParserTest,RejectReadingTooManyRecords)438 TEST(DnsRecordParserTest, RejectReadingTooManyRecords) {
439   const char kData[] =
440       "\003www\006google\004test\000"
441       "\x00\x01"          // TYPE=A
442       "\x00\x01"          // CLASS=IN
443       "\x00\x01\x51\x80"  // TTL=1 day
444       "\x00\x04"          // RDLENGTH=4 bytes
445       "\xc0\xa8\x00\x01"  // 192.168.0.1
446       "\003www\010chromium\004test\000"
447       "\x00\x01"           // TYPE=A
448       "\x00\x01"           // CLASS=IN
449       "\x00\x01\x51\x80"   // TTL=1 day
450       "\x00\x04"           // RDLENGTH=4 bytes
451       "\xc0\xa8\x00\x02";  // 192.168.0.2
452 
453   DnsRecordParser parser(
454       kData, /*length=*/sizeof(kData) - 1, /*offset=*/0,
455       /*num_records=*/1);  // Claim 1 record despite there being 2 in `kData`.
456 
457   DnsResourceRecord record1;
458   EXPECT_TRUE(parser.ReadRecord(&record1));
459 
460   // Expect second record cannot be parsed because only 1 was expected.
461   DnsResourceRecord record2;
462   EXPECT_FALSE(parser.ReadRecord(&record2));
463 }
464 
465 // Test that no more records can be parsed once the end of the buffer is
466 // reached, even if more records are claimed.
TEST(DnsRecordParserTest,RejectReadingPastEnd)467 TEST(DnsRecordParserTest, RejectReadingPastEnd) {
468   const char kData[] =
469       "\003www\006google\004test\000"
470       "\x00\x01"          // TYPE=A
471       "\x00\x01"          // CLASS=IN
472       "\x00\x01\x51\x80"  // TTL=1 day
473       "\x00\x04"          // RDLENGTH=4 bytes
474       "\xc0\xa8\x00\x01"  // 192.168.0.1
475       "\003www\010chromium\004test\000"
476       "\x00\x01"           // TYPE=A
477       "\x00\x01"           // CLASS=IN
478       "\x00\x01\x51\x80"   // TTL=1 day
479       "\x00\x04"           // RDLENGTH=4 bytes
480       "\xc0\xa8\x00\x02";  // 192.168.0.2
481 
482   DnsRecordParser parser(
483       kData, /*length=*/sizeof(kData) - 1, /*offset=*/0,
484       /*num_records=*/3);  // Claim 3 record despite there being 2 in `kData`.
485 
486   DnsResourceRecord record;
487   EXPECT_TRUE(parser.ReadRecord(&record));
488   EXPECT_TRUE(parser.ReadRecord(&record));
489   EXPECT_FALSE(parser.ReadRecord(&record));
490 }
491 
TEST(DnsResponseTest,InitParse)492 TEST(DnsResponseTest, InitParse) {
493   // This includes \0 at the end.
494   const char qname[] =
495       "\x0A"
496       "codereview"
497       "\x08"
498       "chromium"
499       "\x03"
500       "org";
501   // Compilers want to copy when binding temporary to const &, so must use heap.
502   auto query = std::make_unique<DnsQuery>(
503       0xcafe, base::as_bytes(base::make_span(qname)), dns_protocol::kTypeA);
504 
505   const uint8_t response_data[] = {
506       // Header
507       0xca, 0xfe,  // ID
508       0x81, 0x80,  // Standard query response, RA, no error
509       0x00, 0x01,  // 1 question
510       0x00, 0x02,  // 2 RRs (answers)
511       0x00, 0x00,  // 0 authority RRs
512       0x00, 0x01,  // 1 additional RRs
513 
514       // Question
515       // This part is echoed back from the respective query.
516       0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x08, 'c', 'h',
517       'r', 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00,
518       0x01,        // TYPE is A.
519       0x00, 0x01,  // CLASS is IN.
520 
521       // Answer 1
522       0xc0, 0x0c,  // NAME is a pointer to name in Question section.
523       0x00, 0x05,  // TYPE is CNAME.
524       0x00, 0x01,  // CLASS is IN.
525       0x00, 0x01,  // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
526       0x24, 0x74, 0x00, 0x12,  // RDLENGTH is 18 bytes.
527       // ghs.l.google.com in DNS format.
528       0x03, 'g', 'h', 's', 0x01, 'l', 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 0x03,
529       'c', 'o', 'm', 0x00,
530 
531       // Answer 2
532       0xc0, 0x35,              // NAME is a pointer to name in Answer 1.
533       0x00, 0x01,              // TYPE is A.
534       0x00, 0x01,              // CLASS is IN.
535       0x00, 0x00,              // TTL (4 bytes) is 53 seconds.
536       0x00, 0x35, 0x00, 0x04,  // RDLENGTH is 4 bytes.
537       0x4a, 0x7d,              // RDATA is the IP: 74.125.95.121
538       0x5f, 0x79,
539 
540       // Additional 1
541       0x00,                    // NAME is empty (root domain).
542       0x00, 0x29,              // TYPE is OPT.
543       0x10, 0x00,              // CLASS is max UDP payload size (4096).
544       0x00, 0x00, 0x00, 0x00,  // TTL (4 bytes) is rcode, version and flags.
545       0x00, 0x08,              // RDLENGTH
546       0x00, 0xFF,              // OPT code
547       0x00, 0x04,              // OPT data size
548       0xDE, 0xAD, 0xBE, 0xEF   // OPT data
549   };
550 
551   DnsResponse resp;
552   memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data));
553 
554   EXPECT_FALSE(resp.id());
555 
556   // Reject too short.
557   EXPECT_FALSE(resp.InitParse(query->io_buffer()->size() - 1, *query));
558   EXPECT_FALSE(resp.IsValid());
559   EXPECT_FALSE(resp.id());
560 
561   // Reject wrong id.
562   std::unique_ptr<DnsQuery> other_query = query->CloneWithNewId(0xbeef);
563   EXPECT_FALSE(resp.InitParse(sizeof(response_data), *other_query));
564   EXPECT_FALSE(resp.IsValid());
565   EXPECT_THAT(resp.id(), testing::Optional(0xcafe));
566 
567   // Reject wrong question.
568   auto wrong_query = std::make_unique<DnsQuery>(
569       0xcafe, base::as_bytes(base::make_span(qname)), dns_protocol::kTypeCNAME);
570   EXPECT_FALSE(resp.InitParse(sizeof(response_data), *wrong_query));
571   EXPECT_FALSE(resp.IsValid());
572   EXPECT_THAT(resp.id(), testing::Optional(0xcafe));
573 
574   // Accept matching question.
575   EXPECT_TRUE(resp.InitParse(sizeof(response_data), *query));
576   EXPECT_TRUE(resp.IsValid());
577 
578   // Check header access.
579   EXPECT_THAT(resp.id(), testing::Optional(0xcafe));
580   EXPECT_EQ(0x8180, resp.flags());
581   EXPECT_EQ(0x0, resp.rcode());
582   EXPECT_EQ(2u, resp.answer_count());
583   EXPECT_EQ(1u, resp.additional_answer_count());
584 
585   // Check question access.
586   absl::optional<std::vector<uint8_t>> response_qname =
587       dns_names_util::DottedNameToNetwork(resp.GetSingleDottedName());
588   ASSERT_TRUE(response_qname.has_value());
589   EXPECT_THAT(query->qname(),
590               testing::ElementsAreArray(response_qname.value()));
591   EXPECT_EQ(query->qtype(), resp.GetSingleQType());
592   EXPECT_EQ("codereview.chromium.org", resp.GetSingleDottedName());
593 
594   DnsResourceRecord record;
595   DnsRecordParser parser = resp.Parser();
596   EXPECT_TRUE(parser.ReadRecord(&record));
597   EXPECT_FALSE(parser.AtEnd());
598   EXPECT_TRUE(parser.ReadRecord(&record));
599   EXPECT_FALSE(parser.AtEnd());
600   EXPECT_TRUE(parser.ReadRecord(&record));
601   EXPECT_TRUE(parser.AtEnd());
602   EXPECT_FALSE(parser.ReadRecord(&record));
603 }
604 
TEST(DnsResponseTest,InitParseInvalidFlags)605 TEST(DnsResponseTest, InitParseInvalidFlags) {
606   // This includes \0 at the end.
607   const char qname[] =
608       "\x0A"
609       "codereview"
610       "\x08"
611       "chromium"
612       "\x03"
613       "org";
614   // Compilers want to copy when binding temporary to const &, so must use heap.
615   auto query = std::make_unique<DnsQuery>(
616       0xcafe, base::as_bytes(base::make_span(qname)), dns_protocol::kTypeA);
617 
618   const uint8_t response_data[] = {
619       // Header
620       0xca, 0xfe,  // ID
621       0x01, 0x80,  // RA, no error. Note the absence of the required QR bit.
622       0x00, 0x01,  // 1 question
623       0x00, 0x01,  // 1 RRs (answers)
624       0x00, 0x00,  // 0 authority RRs
625       0x00, 0x00,  // 0 additional RRs
626 
627       // Question
628       // This part is echoed back from the respective query.
629       0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x08, 'c', 'h',
630       'r', 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00,
631       0x01,        // TYPE is A.
632       0x00, 0x01,  // CLASS is IN.
633 
634       // Answer 1
635       0xc0, 0x0c,  // NAME is a pointer to name in Question section.
636       0x00, 0x05,  // TYPE is CNAME.
637       0x00, 0x01,  // CLASS is IN.
638       0x00, 0x01,  // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
639       0x24, 0x74, 0x00, 0x12,  // RDLENGTH is 18 bytes.
640       // ghs.l.google.com in DNS format.
641       0x03, 'g', 'h', 's', 0x01, 'l', 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 0x03,
642       'c', 'o', 'm', 0x00,
643   };
644 
645   DnsResponse resp;
646   memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data));
647 
648   EXPECT_FALSE(resp.InitParse(sizeof(response_data), *query));
649   EXPECT_FALSE(resp.IsValid());
650   EXPECT_THAT(resp.id(), testing::Optional(0xcafe));
651 }
652 
TEST(DnsResponseTest,InitParseRejectsResponseWithoutQuestions)653 TEST(DnsResponseTest, InitParseRejectsResponseWithoutQuestions) {
654   const char kResponse[] =
655       "\x02\x45"                       // ID=581
656       "\x81\x80"                       // Standard query response, RA, no error
657       "\x00\x00"                       // 0 questions
658       "\x00\x01"                       // 1 answers
659       "\x00\x00"                       // 0 authority records
660       "\x00\x00"                       // 0 additional records
661       "\003www\006google\004test\000"  // www.google.test
662       "\x00\x01"                       // TYPE=A
663       "\x00\x01"                       // CLASS=IN
664       "\x00\x00\x2a\x30"               // TTL=3 hours
665       "\x00\x04"                       // RDLENGTH=4 bytes
666       "\xa0\xa0\xa0\xa0";              // 10.10.10.10
667 
668   DnsResponse resp;
669   memcpy(resp.io_buffer()->data(), kResponse, sizeof(kResponse) - 1);
670 
671   // Validate that the response is fine if not matching against a query.
672   ASSERT_TRUE(resp.InitParseWithoutQuery(sizeof(kResponse) - 1));
673 
674   const char kQueryName[] = "\003www\006google\004test";
675   DnsQuery query(
676       /*id=*/581, base::as_bytes(base::make_span(kQueryName)),
677       dns_protocol::kTypeA);
678   EXPECT_FALSE(resp.InitParse(sizeof(kResponse) - 1, query));
679 }
680 
TEST(DnsResponseTest,InitParseRejectsResponseWithTooManyQuestions)681 TEST(DnsResponseTest, InitParseRejectsResponseWithTooManyQuestions) {
682   const char kResponse[] =
683       "\x02\x46"                       // ID=582
684       "\x81\x80"                       // Standard query response, RA, no error
685       "\x00\x02"                       // 2 questions
686       "\x00\x00"                       // 0 answers
687       "\x00\x00"                       // 0 authority records
688       "\x00\x00"                       // 0 additional records
689       "\003www\006google\004test\000"  // www.google.test
690       "\x00\x01"                       // TYPE=A
691       "\x00\x01"                       // CLASS=IN
692       "\003www\010chromium\004test\000"  // www.chromium.test
693       "\x00\x01"                         // TYPE=A
694       "\x00\x01";                        // CLASS=IN
695 
696   DnsResponse resp;
697   memcpy(resp.io_buffer()->data(), kResponse, sizeof(kResponse) - 1);
698 
699   // Validate that the response is fine if not matching against a query.
700   ASSERT_TRUE(resp.InitParseWithoutQuery(sizeof(kResponse) - 1));
701 
702   const char kQueryName[] = "\003www\006google\004test";
703   DnsQuery query(
704       /*id=*/582, base::as_bytes(base::make_span(kQueryName)),
705       dns_protocol::kTypeA);
706   EXPECT_FALSE(resp.InitParse(sizeof(kResponse) - 1, query));
707 }
708 
TEST(DnsResponseTest,InitParseWithoutQuery)709 TEST(DnsResponseTest, InitParseWithoutQuery) {
710   DnsResponse resp;
711   memcpy(resp.io_buffer()->data(), kT0ResponseDatagram,
712          sizeof(kT0ResponseDatagram));
713 
714   // Accept matching question.
715   EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(kT0ResponseDatagram)));
716   EXPECT_TRUE(resp.IsValid());
717 
718   // Check header access.
719   EXPECT_EQ(0x8180, resp.flags());
720   EXPECT_EQ(0x0, resp.rcode());
721   EXPECT_EQ(kT0RecordCount, resp.answer_count());
722 
723   // Check question access.
724   EXPECT_EQ(kT0Qtype, resp.GetSingleQType());
725   EXPECT_EQ(kT0HostName, resp.GetSingleDottedName());
726 
727   DnsResourceRecord record;
728   DnsRecordParser parser = resp.Parser();
729   for (unsigned i = 0; i < kT0RecordCount; i ++) {
730     EXPECT_FALSE(parser.AtEnd());
731     EXPECT_TRUE(parser.ReadRecord(&record));
732   }
733   EXPECT_TRUE(parser.AtEnd());
734   EXPECT_FALSE(parser.ReadRecord(&record));
735 }
736 
TEST(DnsResponseTest,InitParseWithoutQueryNoQuestions)737 TEST(DnsResponseTest, InitParseWithoutQueryNoQuestions) {
738   const uint8_t response_data[] = {
739       // Header
740       0xca, 0xfe,  // ID
741       0x81, 0x80,  // Standard query response, RA, no error
742       0x00, 0x00,  // No question
743       0x00, 0x01,  // 2 RRs (answers)
744       0x00, 0x00,  // 0 authority RRs
745       0x00, 0x00,  // 0 additional RRs
746 
747       // Answer 1
748       0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x08, 'c', 'h',
749       'r', 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00,
750       0x01,                    // TYPE is A.
751       0x00, 0x01,              // CLASS is IN.
752       0x00, 0x00,              // TTL (4 bytes) is 53 seconds.
753       0x00, 0x35, 0x00, 0x04,  // RDLENGTH is 4 bytes.
754       0x4a, 0x7d,              // RDATA is the IP: 74.125.95.121
755       0x5f, 0x79,
756   };
757 
758   DnsResponse resp;
759   memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data));
760 
761   EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(response_data)));
762 
763   // Check header access.
764   EXPECT_THAT(resp.id(), testing::Optional(0xcafe));
765   EXPECT_EQ(0x8180, resp.flags());
766   EXPECT_EQ(0x0, resp.rcode());
767   EXPECT_EQ(0u, resp.question_count());
768   EXPECT_EQ(0x1u, resp.answer_count());
769 
770   EXPECT_THAT(resp.dotted_qnames(), testing::IsEmpty());
771   EXPECT_THAT(resp.qtypes(), testing::IsEmpty());
772 
773   DnsResourceRecord record;
774   DnsRecordParser parser = resp.Parser();
775 
776   EXPECT_FALSE(parser.AtEnd());
777   EXPECT_TRUE(parser.ReadRecord(&record));
778   EXPECT_EQ("codereview.chromium.org", record.name);
779   EXPECT_EQ(0x00000035u, record.ttl);
780   EXPECT_EQ(dns_protocol::kTypeA, record.type);
781 
782   EXPECT_TRUE(parser.AtEnd());
783   EXPECT_FALSE(parser.ReadRecord(&record));
784 }
785 
TEST(DnsResponseTest,InitParseWithoutQueryInvalidFlags)786 TEST(DnsResponseTest, InitParseWithoutQueryInvalidFlags) {
787   const uint8_t response_data[] = {
788       // Header
789       0xca, 0xfe,  // ID
790       0x01, 0x80,  // RA, no error. Note the absence of the required QR bit.
791       0x00, 0x00,  // No question
792       0x00, 0x01,  // 2 RRs (answers)
793       0x00, 0x00,  // 0 authority RRs
794       0x00, 0x00,  // 0 additional RRs
795 
796       // Answer 1
797       0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x08, 'c', 'h',
798       'r', 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00,
799       0x01,                    // TYPE is A.
800       0x00, 0x01,              // CLASS is IN.
801       0x00, 0x00,              // TTL (4 bytes) is 53 seconds.
802       0x00, 0x35, 0x00, 0x04,  // RDLENGTH is 4 bytes.
803       0x4a, 0x7d,              // RDATA is the IP: 74.125.95.121
804       0x5f, 0x79,
805   };
806 
807   DnsResponse resp;
808   memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data));
809 
810   EXPECT_FALSE(resp.InitParseWithoutQuery(sizeof(response_data)));
811   EXPECT_THAT(resp.id(), testing::Optional(0xcafe));
812 }
813 
TEST(DnsResponseTest,InitParseWithoutQueryTwoQuestions)814 TEST(DnsResponseTest, InitParseWithoutQueryTwoQuestions) {
815   const uint8_t response_data[] = {
816       // Header
817       0xca,
818       0xfe,  // ID
819       0x81,
820       0x80,  // Standard query response, RA, no error
821       0x00,
822       0x02,  // 2 questions
823       0x00,
824       0x01,  // 2 RRs (answers)
825       0x00,
826       0x00,  // 0 authority RRs
827       0x00,
828       0x00,  // 0 additional RRs
829 
830       // Question 1
831       0x0a,
832       'c',
833       'o',
834       'd',
835       'e',
836       'r',
837       'e',
838       'v',
839       'i',
840       'e',
841       'w',
842       0x08,
843       'c',
844       'h',
845       'r',
846       'o',
847       'm',
848       'i',
849       'u',
850       'm',
851       0x03,
852       'o',
853       'r',
854       'g',
855       0x00,
856       0x00,
857       0x01,  // TYPE is A.
858       0x00,
859       0x01,  // CLASS is IN.
860 
861       // Question 2
862       0x0b,
863       'c',
864       'o',
865       'd',
866       'e',
867       'r',
868       'e',
869       'v',
870       'i',
871       'e',
872       'w',
873       '2',
874       0xc0,
875       0x17,  // pointer to "chromium.org"
876       0x00,
877       0x01,  // TYPE is A.
878       0x00,
879       0x01,  // CLASS is IN.
880 
881       // Answer 1
882       0xc0,
883       0x0c,  // NAME is a pointer to name in Question section.
884       0x00,
885       0x01,  // TYPE is A.
886       0x00,
887       0x01,  // CLASS is IN.
888       0x00,
889       0x00,  // TTL (4 bytes) is 53 seconds.
890       0x00,
891       0x35,
892       0x00,
893       0x04,  // RDLENGTH is 4 bytes.
894       0x4a,
895       0x7d,  // RDATA is the IP: 74.125.95.121
896       0x5f,
897       0x79,
898   };
899 
900   DnsResponse resp;
901   memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data));
902 
903   EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(response_data)));
904 
905   // Check header access.
906   EXPECT_EQ(0x8180, resp.flags());
907   EXPECT_EQ(0x0, resp.rcode());
908   EXPECT_EQ(2u, resp.question_count());
909   EXPECT_EQ(0x01u, resp.answer_count());
910 
911   EXPECT_THAT(resp.dotted_qnames(),
912               testing::ElementsAre("codereview.chromium.org",
913                                    "codereview2.chromium.org"));
914   EXPECT_THAT(resp.qtypes(),
915               testing::ElementsAre(dns_protocol::kTypeA, dns_protocol::kTypeA));
916 
917   DnsResourceRecord record;
918   DnsRecordParser parser = resp.Parser();
919 
920   EXPECT_FALSE(parser.AtEnd());
921   EXPECT_TRUE(parser.ReadRecord(&record));
922   EXPECT_EQ("codereview.chromium.org", record.name);
923   EXPECT_EQ(0x35u, record.ttl);
924   EXPECT_EQ(dns_protocol::kTypeA, record.type);
925 
926   EXPECT_TRUE(parser.AtEnd());
927   EXPECT_FALSE(parser.ReadRecord(&record));
928 }
929 
TEST(DnsResponseTest,InitParseWithoutQueryPacketTooShort)930 TEST(DnsResponseTest, InitParseWithoutQueryPacketTooShort) {
931   const uint8_t response_data[] = {
932       // Header
933       0xca, 0xfe,  // ID
934       0x81, 0x80,  // Standard query response, RA, no error
935       0x00, 0x00,  // No question
936   };
937 
938   DnsResponse resp;
939   memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data));
940 
941   EXPECT_FALSE(resp.InitParseWithoutQuery(sizeof(response_data)));
942 }
943 
TEST(DnsResponseTest,InitParseAllowsQuestionWithLongName)944 TEST(DnsResponseTest, InitParseAllowsQuestionWithLongName) {
945   const char kResponseHeader[] =
946       "\x02\x45"   // ID=581
947       "\x81\x80"   // Standard query response, RA, no error
948       "\x00\x01"   // 1 question
949       "\x00\x00"   // 0 answers
950       "\x00\x00"   // 0 authority records
951       "\x00\x00";  // 0 additional records
952 
953   std::string dotted_name;
954   const std::vector<uint8_t> dns_name =
955       BuildRfc1034Name(dns_protocol::kMaxNameLength, &dotted_name);
956 
957   std::string response_data(kResponseHeader, sizeof(kResponseHeader) - 1);
958   response_data.append(reinterpret_cast<const char*>(dns_name.data()),
959                        dns_name.size());
960   response_data.append(
961       "\x00\x01"   // TYPE=A
962       "\x00\x01",  // CLASS=IN)
963       4);
964 
965   DnsResponse resp1;
966   memcpy(resp1.io_buffer()->data(), response_data.data(), response_data.size());
967 
968   EXPECT_TRUE(resp1.InitParseWithoutQuery(response_data.size()));
969 
970   DnsQuery query(581, dns_name, dns_protocol::kTypeA);
971 
972   DnsResponse resp2(resp1.io_buffer(), response_data.size());
973   EXPECT_TRUE(resp2.InitParse(response_data.size(), query));
974 }
975 
976 // Tests against incorrect name length validation, which is anti-pattern #3 from
977 // the "NAME:WRECK" report:
978 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsResponseTest,InitParseRejectsQuestionWithTooLongName)979 TEST(DnsResponseTest, InitParseRejectsQuestionWithTooLongName) {
980   const char kResponseHeader[] =
981       "\x02\x45"   // ID=581
982       "\x81\x80"   // Standard query response, RA, no error
983       "\x00\x01"   // 1 question
984       "\x00\x00"   // 0 answers
985       "\x00\x00"   // 0 authority records
986       "\x00\x00";  // 0 additional records
987 
988   std::string dotted_name;
989   const std::vector<uint8_t> dns_name =
990       BuildRfc1034Name(dns_protocol::kMaxNameLength + 1, &dotted_name);
991 
992   std::string response_data(kResponseHeader, sizeof(kResponseHeader) - 1);
993   response_data.append(reinterpret_cast<const char*>(dns_name.data()),
994                        dns_name.size());
995   response_data.append(
996       "\x00\x01"   // TYPE=A
997       "\x00\x01",  // CLASS=IN)
998       4);
999 
1000   DnsResponse resp;
1001   memcpy(resp.io_buffer()->data(), response_data.data(), response_data.size());
1002 
1003   EXPECT_FALSE(resp.InitParseWithoutQuery(response_data.size()));
1004 
1005   // Note that `DnsQuery` disallows construction without a valid name, so
1006   // `InitParse()` can never be tested with a `query` that matches against a
1007   // too-long name in the response. Test with an arbitrary valid query name to
1008   // ensure no issues if this code is exercised after receiving a response with
1009   // a too-long name.
1010   const char kQueryName[] = "\005query\004test";
1011   DnsQuery query(
1012       /*id=*/581, base::as_bytes(base::make_span(kQueryName)),
1013       dns_protocol::kTypeA);
1014   EXPECT_FALSE(resp.InitParse(response_data.size(), query));
1015 }
1016 
1017 // Test that `InitParse[...]()` rejects a response with a question name
1018 // extending past the end of the response.
1019 // Tests against incorrect name length validation, which is anti-pattern #3 from
1020 // the "NAME:WRECK" report:
1021 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsResponseTest,InitParseRejectsQuestionWithNonendedName)1022 TEST(DnsResponseTest, InitParseRejectsQuestionWithNonendedName) {
1023   const char kResponse[] =
1024       "\x02\x45"                    // ID
1025       "\x81\x80"                    // Standard query response, RA, no error
1026       "\x00\x01"                    // 1 question
1027       "\x00\x00"                    // 0 answers
1028       "\x00\x00"                    // 0 authority records
1029       "\x00\x00"                    // 0 additional records
1030       "\003www\006google\006test";  // Name extending past the end.
1031 
1032   DnsResponse resp;
1033   memcpy(resp.io_buffer()->data(), kResponse, sizeof(kResponse) - 1);
1034 
1035   EXPECT_FALSE(resp.InitParseWithoutQuery(sizeof(kResponse) - 1));
1036 
1037   const char kQueryName[] = "\003www\006google\006testtt";
1038   DnsQuery query(
1039       /*id=*/581, base::as_bytes(base::make_span(kQueryName)),
1040       dns_protocol::kTypeA);
1041   EXPECT_FALSE(resp.InitParse(sizeof(kResponse) - 1, query));
1042 }
1043 
1044 // Test that `InitParse[...]()` rejects responses that do not contain at least
1045 // the claimed number of questions.
1046 // Tests against incorrect record count field validation, which is anti-pattern
1047 // #5 from the "NAME:WRECK" report:
1048 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsResponseTest,InitParseRejectsResponseWithMissingQuestions)1049 TEST(DnsResponseTest, InitParseRejectsResponseWithMissingQuestions) {
1050   const char kResponse[] =
1051       "\x02\x45"                       // ID
1052       "\x81\x80"                       // Standard query response, RA, no error
1053       "\x00\x03"                       // 3 questions
1054       "\x00\x00"                       // 0 answers
1055       "\x00\x00"                       // 0 authority records
1056       "\x00\x00"                       // 0 additional records
1057       "\003www\006google\004test\000"  // www.google.test
1058       "\x00\x01"                       // TYPE=A
1059       "\x00\x01"                       // CLASS=IN
1060       "\003www\010chromium\004test\000"  // www.chromium.test
1061       "\x00\x01"                         // TYPE=A
1062       "\x00\x01";                        // CLASS=IN
1063   // Missing third question.
1064 
1065   DnsResponse resp;
1066   memcpy(resp.io_buffer()->data(), kResponse, sizeof(kResponse) - 1);
1067 
1068   EXPECT_FALSE(resp.InitParseWithoutQuery(sizeof(kResponse) - 1));
1069 
1070   const char kQueryName[] = "\003www\006google\004test";
1071   DnsQuery query(
1072       /*id=*/581, base::as_bytes(base::make_span(kQueryName)),
1073       dns_protocol::kTypeA);
1074   EXPECT_FALSE(resp.InitParse(sizeof(kResponse) - 1, query));
1075 }
1076 
1077 // Test that a parsed DnsResponse only allows parsing the number of records
1078 // claimed in the response header.
1079 // Tests against incorrect record count field validation, which is anti-pattern
1080 // #5 from the "NAME:WRECK" report:
1081 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsResponseTest,ParserLimitedToNumClaimedRecords)1082 TEST(DnsResponseTest, ParserLimitedToNumClaimedRecords) {
1083   const char kResponse[] =
1084       "\x02\x45"  // ID
1085       "\x81\x80"  // Standard query response, RA, no error
1086       "\x00\x01"  // 1 question
1087       "\x00\x01"  // 1 answers
1088       "\x00\x02"  // 2 authority records
1089       "\x00\x01"  // 1 additional records
1090       "\003www\006google\004test\000"
1091       "\x00\x01"  // TYPE=A
1092       "\x00\x01"  // CLASS=IN
1093       // 6 total records.
1094       "\003www\006google\004test\000"
1095       "\x00\x01"          // TYPE=A
1096       "\x00\x01"          // CLASS=IN
1097       "\x00\x01\x51\x80"  // TTL=1 day
1098       "\x00\x04"          // RDLENGTH=4 bytes
1099       "\xc0\xa8\x00\x01"  // 192.168.0.1
1100       "\003www\010chromium\004test\000"
1101       "\x00\x01"          // TYPE=A
1102       "\x00\x01"          // CLASS=IN
1103       "\x00\x01\x51\x80"  // TTL=1 day
1104       "\x00\x04"          // RDLENGTH=4 bytes
1105       "\xc0\xa8\x00\x02"  // 192.168.0.2
1106       "\003www\007google1\004test\000"
1107       "\x00\x01"          // TYPE=A
1108       "\x00\x01"          // CLASS=IN
1109       "\x00\x01\x51\x80"  // TTL=1 day
1110       "\x00\x04"          // RDLENGTH=4 bytes
1111       "\xc0\xa8\x00\x03"  // 192.168.0.3
1112       "\003www\011chromium1\004test\000"
1113       "\x00\x01"          // TYPE=A
1114       "\x00\x01"          // CLASS=IN
1115       "\x00\x01\x51\x80"  // TTL=1 day
1116       "\x00\x04"          // RDLENGTH=4 bytes
1117       "\xc0\xa8\x00\x04"  // 192.168.0.4
1118       "\003www\007google2\004test\000"
1119       "\x00\x01"          // TYPE=A
1120       "\x00\x01"          // CLASS=IN
1121       "\x00\x01\x51\x80"  // TTL=1 day
1122       "\x00\x04"          // RDLENGTH=4 bytes
1123       "\xc0\xa8\x00\x05"  // 192.168.0.5
1124       "\003www\011chromium2\004test\000"
1125       "\x00\x01"           // TYPE=A
1126       "\x00\x01"           // CLASS=IN
1127       "\x00\x01\x51\x80"   // TTL=1 day
1128       "\x00\x04"           // RDLENGTH=4 bytes
1129       "\xc0\xa8\x00\x06";  // 192.168.0.6
1130 
1131   DnsResponse resp1;
1132   memcpy(resp1.io_buffer()->data(), kResponse, sizeof(kResponse) - 1);
1133 
1134   ASSERT_TRUE(resp1.InitParseWithoutQuery(sizeof(kResponse) - 1));
1135   DnsRecordParser parser1 = resp1.Parser();
1136   ASSERT_TRUE(parser1.IsValid());
1137 
1138   // Response header only claims 4 records, so expect parser to only allow
1139   // parsing that many, ignoring extra records in the data.
1140   DnsResourceRecord record;
1141   EXPECT_TRUE(parser1.ReadRecord(&record));
1142   EXPECT_TRUE(parser1.ReadRecord(&record));
1143   EXPECT_TRUE(parser1.ReadRecord(&record));
1144   EXPECT_TRUE(parser1.ReadRecord(&record));
1145   EXPECT_FALSE(parser1.ReadRecord(&record));
1146   EXPECT_FALSE(parser1.ReadRecord(&record));
1147 
1148   // Repeat using InitParse()
1149   DnsResponse resp2;
1150   memcpy(resp2.io_buffer()->data(), kResponse, sizeof(kResponse) - 1);
1151 
1152   const char kQueryName[] = "\003www\006google\004test";
1153   DnsQuery query(
1154       /*id=*/581, base::as_bytes(base::make_span(kQueryName)),
1155       dns_protocol::kTypeA);
1156 
1157   ASSERT_TRUE(resp2.InitParse(sizeof(kResponse) - 1, query));
1158   DnsRecordParser parser2 = resp2.Parser();
1159   ASSERT_TRUE(parser2.IsValid());
1160 
1161   // Response header only claims 4 records, so expect parser to only allow
1162   // parsing that many, ignoring extra records in the data.
1163   EXPECT_TRUE(parser2.ReadRecord(&record));
1164   EXPECT_TRUE(parser2.ReadRecord(&record));
1165   EXPECT_TRUE(parser2.ReadRecord(&record));
1166   EXPECT_TRUE(parser2.ReadRecord(&record));
1167   EXPECT_FALSE(parser2.ReadRecord(&record));
1168   EXPECT_FALSE(parser2.ReadRecord(&record));
1169 }
1170 
1171 // Test that a parsed DnsResponse does not allow parsing past the end of the
1172 // input, even if more records are claimed in the response header.
1173 // Tests against incorrect record count field validation, which is anti-pattern
1174 // #5 from the "NAME:WRECK" report:
1175 // https://www.forescout.com/company/resources/namewreck-breaking-and-fixing-dns-implementations/
TEST(DnsResponseTest,ParserLimitedToBufferSize)1176 TEST(DnsResponseTest, ParserLimitedToBufferSize) {
1177   const char kResponse[] =
1178       "\x02\x45"  // ID
1179       "\x81\x80"  // Standard query response, RA, no error
1180       "\x00\x01"  // 1 question
1181       "\x00\x01"  // 1 answers
1182       "\x00\x02"  // 2 authority records
1183       "\x00\x01"  // 1 additional records
1184       "\003www\006google\004test\000"
1185       "\x00\x01"  // TYPE=A
1186       "\x00\x01"  // CLASS=IN
1187       // 2 total records.
1188       "\003www\006google\004test\000"
1189       "\x00\x01"          // TYPE=A
1190       "\x00\x01"          // CLASS=IN
1191       "\x00\x01\x51\x80"  // TTL=1 day
1192       "\x00\x04"          // RDLENGTH=4 bytes
1193       "\xc0\xa8\x00\x01"  // 192.168.0.1
1194       "\003www\010chromium\004test\000"
1195       "\x00\x01"           // TYPE=A
1196       "\x00\x01"           // CLASS=IN
1197       "\x00\x01\x51\x80"   // TTL=1 day
1198       "\x00\x04"           // RDLENGTH=4 bytes
1199       "\xc0\xa8\x00\x02";  // 192.168.0.2
1200 
1201   DnsResponse resp1;
1202   memcpy(resp1.io_buffer()->data(), kResponse, sizeof(kResponse) - 1);
1203 
1204   ASSERT_TRUE(resp1.InitParseWithoutQuery(sizeof(kResponse) - 1));
1205   DnsRecordParser parser1 = resp1.Parser();
1206   ASSERT_TRUE(parser1.IsValid());
1207 
1208   // Response header claims 4 records, but only 2 present in input.
1209   DnsResourceRecord record;
1210   EXPECT_TRUE(parser1.ReadRecord(&record));
1211   EXPECT_TRUE(parser1.ReadRecord(&record));
1212   EXPECT_FALSE(parser1.ReadRecord(&record));
1213   EXPECT_FALSE(parser1.ReadRecord(&record));
1214 
1215   // Repeat using InitParse()
1216   DnsResponse resp2;
1217   memcpy(resp2.io_buffer()->data(), kResponse, sizeof(kResponse) - 1);
1218 
1219   ASSERT_TRUE(resp2.InitParseWithoutQuery(sizeof(kResponse) - 1));
1220   DnsRecordParser parser2 = resp2.Parser();
1221   ASSERT_TRUE(parser2.IsValid());
1222 
1223   // Response header claims 4 records, but only 2 present in input.
1224   EXPECT_TRUE(parser2.ReadRecord(&record));
1225   EXPECT_TRUE(parser2.ReadRecord(&record));
1226   EXPECT_FALSE(parser2.ReadRecord(&record));
1227   EXPECT_FALSE(parser2.ReadRecord(&record));
1228 }
1229 
TEST(DnsResponseWriteTest,SingleARecordAnswer)1230 TEST(DnsResponseWriteTest, SingleARecordAnswer) {
1231   const uint8_t response_data[] = {
1232       0x12, 0x34,  // ID
1233       0x84, 0x00,  // flags, response with authoritative answer
1234       0x00, 0x00,  // number of questions
1235       0x00, 0x01,  // number of answer rr
1236       0x00, 0x00,  // number of name server rr
1237       0x00, 0x00,  // number of additional rr
1238       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1239       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1240       0x00,                    // null label
1241       0x00, 0x01,              // type A Record
1242       0x00, 0x01,              // class IN
1243       0x00, 0x00, 0x00, 0x78,  // TTL, 120 seconds
1244       0x00, 0x04,              // rdlength, 32 bits
1245       0xc0, 0xa8, 0x00, 0x01,  // 192.168.0.1
1246   };
1247   net::DnsResourceRecord answer;
1248   answer.name = "www.example.com";
1249   answer.type = dns_protocol::kTypeA;
1250   answer.klass = dns_protocol::kClassIN;
1251   answer.ttl = 120;  // 120 seconds.
1252   answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
1253   std::vector<DnsResourceRecord> answers(1, answer);
1254   DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/,
1255                        answers, {} /* authority_records */,
1256                        {} /* additional records */, absl::nullopt);
1257   ASSERT_NE(nullptr, response.io_buffer());
1258   EXPECT_TRUE(response.IsValid());
1259   std::string expected_response(reinterpret_cast<const char*>(response_data),
1260                                 sizeof(response_data));
1261   std::string actual_response(response.io_buffer()->data(),
1262                               response.io_buffer_size());
1263   EXPECT_EQ(expected_response, actual_response);
1264 }
1265 
TEST(DnsResponseWriteTest,SingleARecordAnswerWithFinalDotInName)1266 TEST(DnsResponseWriteTest, SingleARecordAnswerWithFinalDotInName) {
1267   const uint8_t response_data[] = {
1268       0x12, 0x34,  // ID
1269       0x84, 0x00,  // flags, response with authoritative answer
1270       0x00, 0x00,  // number of questions
1271       0x00, 0x01,  // number of answer rr
1272       0x00, 0x00,  // number of name server rr
1273       0x00, 0x00,  // number of additional rr
1274       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1275       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1276       0x00,                    // null label
1277       0x00, 0x01,              // type A Record
1278       0x00, 0x01,              // class IN
1279       0x00, 0x00, 0x00, 0x78,  // TTL, 120 seconds
1280       0x00, 0x04,              // rdlength, 32 bits
1281       0xc0, 0xa8, 0x00, 0x01,  // 192.168.0.1
1282   };
1283   net::DnsResourceRecord answer;
1284   answer.name = "www.example.com.";  // FQDN with the final dot.
1285   answer.type = dns_protocol::kTypeA;
1286   answer.klass = dns_protocol::kClassIN;
1287   answer.ttl = 120;  // 120 seconds.
1288   answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
1289   std::vector<DnsResourceRecord> answers(1, answer);
1290   DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/,
1291                        answers, {} /* authority_records */,
1292                        {} /* additional records */, absl::nullopt);
1293   ASSERT_NE(nullptr, response.io_buffer());
1294   EXPECT_TRUE(response.IsValid());
1295   std::string expected_response(reinterpret_cast<const char*>(response_data),
1296                                 sizeof(response_data));
1297   std::string actual_response(response.io_buffer()->data(),
1298                               response.io_buffer_size());
1299   EXPECT_EQ(expected_response, actual_response);
1300 }
1301 
TEST(DnsResponseWriteTest,SingleARecordAnswerWithQuestion)1302 TEST(DnsResponseWriteTest, SingleARecordAnswerWithQuestion) {
1303   const uint8_t response_data[] = {
1304       0x12, 0x34,  // ID
1305       0x84, 0x00,  // flags, response with authoritative answer
1306       0x00, 0x01,  // number of questions
1307       0x00, 0x01,  // number of answer rr
1308       0x00, 0x00,  // number of name server rr
1309       0x00, 0x00,  // number of additional rr
1310       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1311       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1312       0x00,        // null label
1313       0x00, 0x01,  // type A Record
1314       0x00, 0x01,  // class IN
1315       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1316       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1317       0x00,                    // null label
1318       0x00, 0x01,              // type A Record
1319       0x00, 0x01,              // class IN
1320       0x00, 0x00, 0x00, 0x78,  // TTL, 120 seconds
1321       0x00, 0x04,              // rdlength, 32 bits
1322       0xc0, 0xa8, 0x00, 0x01,  // 192.168.0.1
1323   };
1324   std::string dotted_name("www.example.com");
1325   absl::optional<std::vector<uint8_t>> dns_name =
1326       dns_names_util::DottedNameToNetwork(dotted_name);
1327   ASSERT_TRUE(dns_name.has_value());
1328 
1329   OptRecordRdata opt_rdata;
1330   opt_rdata.AddOpt(
1331       OptRecordRdata::UnknownOpt::CreateForTesting(255, "\xde\xad\xbe\xef"));
1332 
1333   absl::optional<DnsQuery> query;
1334   query.emplace(0x1234 /* id */, dns_name.value(), dns_protocol::kTypeA,
1335                 &opt_rdata);
1336   net::DnsResourceRecord answer;
1337   answer.name = dotted_name;
1338   answer.type = dns_protocol::kTypeA;
1339   answer.klass = dns_protocol::kClassIN;
1340   answer.ttl = 120;  // 120 seconds.
1341   answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
1342   std::vector<DnsResourceRecord> answers(1, answer);
1343   DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
1344                        {} /* authority_records */, {} /* additional records */,
1345                        query);
1346   ASSERT_NE(nullptr, response.io_buffer());
1347   EXPECT_TRUE(response.IsValid());
1348   std::string expected_response(reinterpret_cast<const char*>(response_data),
1349                                 sizeof(response_data));
1350   std::string actual_response(response.io_buffer()->data(),
1351                               response.io_buffer_size());
1352   EXPECT_EQ(expected_response, actual_response);
1353 }
1354 
TEST(DnsResponseWriteTest,SingleAnswerWithQuestionConstructedFromSizeInflatedQuery)1355 TEST(DnsResponseWriteTest,
1356      SingleAnswerWithQuestionConstructedFromSizeInflatedQuery) {
1357   const uint8_t response_data[] = {
1358       0x12, 0x34,  // ID
1359       0x84, 0x00,  // flags, response with authoritative answer
1360       0x00, 0x01,  // number of questions
1361       0x00, 0x01,  // number of answer rr
1362       0x00, 0x00,  // number of name server rr
1363       0x00, 0x00,  // number of additional rr
1364       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1365       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1366       0x00,        // null label
1367       0x00, 0x01,  // type A Record
1368       0x00, 0x01,  // class IN
1369       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1370       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1371       0x00,                    // null label
1372       0x00, 0x01,              // type A Record
1373       0x00, 0x01,              // class IN
1374       0x00, 0x00, 0x00, 0x78,  // TTL, 120 seconds
1375       0x00, 0x04,              // rdlength, 32 bits
1376       0xc0, 0xa8, 0x00, 0x01,  // 192.168.0.1
1377   };
1378   std::string dotted_name("www.example.com");
1379   absl::optional<std::vector<uint8_t>> dns_name =
1380       dns_names_util::DottedNameToNetwork(dotted_name);
1381   ASSERT_TRUE(dns_name.has_value());
1382   size_t buf_size =
1383       sizeof(dns_protocol::Header) + dns_name.value().size() + 2 /* qtype */ +
1384       2 /* qclass */ +
1385       10 /* extra bytes that inflate the internal buffer of a query */;
1386   auto buf = base::MakeRefCounted<IOBufferWithSize>(buf_size);
1387   memset(buf->data(), 0, buf->size());
1388   base::BigEndianWriter writer(buf->data(), buf_size);
1389   writer.WriteU16(0x1234);                              // id
1390   writer.WriteU16(0);                                   // flags, is query
1391   writer.WriteU16(1);                                   // qdcount
1392   writer.WriteU16(0);                                   // ancount
1393   writer.WriteU16(0);                                   // nscount
1394   writer.WriteU16(0);                                   // arcount
1395   writer.WriteBytes(dns_name.value().data(), dns_name.value().size());  // qname
1396   writer.WriteU16(dns_protocol::kTypeA);                // qtype
1397   writer.WriteU16(dns_protocol::kClassIN);              // qclass
1398   // buf contains 10 extra zero bytes.
1399   absl::optional<DnsQuery> query;
1400   query.emplace(buf);
1401   query->Parse(buf_size);
1402   net::DnsResourceRecord answer;
1403   answer.name = dotted_name;
1404   answer.type = dns_protocol::kTypeA;
1405   answer.klass = dns_protocol::kClassIN;
1406   answer.ttl = 120;  // 120 seconds.
1407   answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
1408   std::vector<DnsResourceRecord> answers(1, answer);
1409   DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
1410                        {} /* authority_records */, {} /* additional records */,
1411                        query);
1412   ASSERT_NE(nullptr, response.io_buffer());
1413   EXPECT_TRUE(response.IsValid());
1414   std::string expected_response(reinterpret_cast<const char*>(response_data),
1415                                 sizeof(response_data));
1416   std::string actual_response(response.io_buffer()->data(),
1417                               response.io_buffer_size());
1418   EXPECT_EQ(expected_response, actual_response);
1419 }
1420 
TEST(DnsResponseWriteTest,SingleQuadARecordAnswer)1421 TEST(DnsResponseWriteTest, SingleQuadARecordAnswer) {
1422   const uint8_t response_data[] = {
1423       0x12, 0x34,  // ID
1424       0x84, 0x00,  // flags, response with authoritative answer
1425       0x00, 0x00,  // number of questions
1426       0x00, 0x01,  // number of answer rr
1427       0x00, 0x00,  // number of name server rr
1428       0x00, 0x00,  // number of additional rr
1429       0x03, 'w',  'w',  'w',  0x07, 'e',  'x',  'a',
1430       'm',  'p',  'l',  'e',  0x03, 'c',  'o',  'm',
1431       0x00,                                            // null label
1432       0x00, 0x1c,                                      // type AAAA Record
1433       0x00, 0x01,                                      // class IN
1434       0x00, 0x00, 0x00, 0x78,                          // TTL, 120 seconds
1435       0x00, 0x10,                                      // rdlength, 128 bits
1436       0xfd, 0x12, 0x34, 0x56, 0x78, 0x9a, 0x00, 0x01,  // fd12:3456:789a:1::1
1437       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1438   };
1439   net::DnsResourceRecord answer;
1440   answer.name = "www.example.com";
1441   answer.type = dns_protocol::kTypeAAAA;
1442   answer.klass = dns_protocol::kClassIN;
1443   answer.ttl = 120;  // 120 seconds.
1444   answer.SetOwnedRdata(std::string(
1445       "\xfd\x12\x34\x56\x78\x9a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01", 16));
1446   std::vector<DnsResourceRecord> answers(1, answer);
1447   DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
1448                        {} /* authority_records */, {} /* additional records */,
1449                        absl::nullopt);
1450   ASSERT_NE(nullptr, response.io_buffer());
1451   EXPECT_TRUE(response.IsValid());
1452   std::string expected_response(reinterpret_cast<const char*>(response_data),
1453                                 sizeof(response_data));
1454   std::string actual_response(response.io_buffer()->data(),
1455                               response.io_buffer_size());
1456   EXPECT_EQ(expected_response, actual_response);
1457 }
1458 
TEST(DnsResponseWriteTest,SingleARecordAnswerWithQuestionAndNsecAdditionalRecord)1459 TEST(DnsResponseWriteTest,
1460      SingleARecordAnswerWithQuestionAndNsecAdditionalRecord) {
1461   const uint8_t response_data[] = {
1462       0x12, 0x34,  // ID
1463       0x84, 0x00,  // flags, response with authoritative answer
1464       0x00, 0x01,  // number of questions
1465       0x00, 0x01,  // number of answer rr
1466       0x00, 0x00,  // number of name server rr
1467       0x00, 0x01,  // number of additional rr
1468       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1469       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1470       0x00,        // null label
1471       0x00, 0x01,  // type A Record
1472       0x00, 0x01,  // class IN
1473       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1474       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1475       0x00,                    // null label
1476       0x00, 0x01,              // type A Record
1477       0x00, 0x01,              // class IN
1478       0x00, 0x00, 0x00, 0x78,  // TTL, 120 seconds
1479       0x00, 0x04,              // rdlength, 32 bits
1480       0xc0, 0xa8, 0x00, 0x01,  // 192.168.0.1
1481       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1482       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1483       0x00,                    // null label
1484       0x00, 0x2f,              // type NSEC Record
1485       0x00, 0x01,              // class IN
1486       0x00, 0x00, 0x00, 0x78,  // TTL, 120 seconds
1487       0x00, 0x05,              // rdlength, 5 bytes
1488       0xc0, 0x0c,              // pointer to the previous "www.example.com"
1489       0x00, 0x01, 0x40,        // type bit map of type A: window block 0, bitmap
1490                                // length 1, bitmap with bit 1 set
1491   };
1492   std::string dotted_name("www.example.com");
1493   absl::optional<std::vector<uint8_t>> dns_name =
1494       dns_names_util::DottedNameToNetwork(dotted_name);
1495   ASSERT_TRUE(dns_name.has_value());
1496   absl::optional<DnsQuery> query;
1497   query.emplace(0x1234 /* id */, dns_name.value(), dns_protocol::kTypeA);
1498   net::DnsResourceRecord answer;
1499   answer.name = dotted_name;
1500   answer.type = dns_protocol::kTypeA;
1501   answer.klass = dns_protocol::kClassIN;
1502   answer.ttl = 120;  // 120 seconds.
1503   answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
1504   std::vector<DnsResourceRecord> answers(1, answer);
1505   net::DnsResourceRecord additional_record;
1506   additional_record.name = dotted_name;
1507   additional_record.type = dns_protocol::kTypeNSEC;
1508   additional_record.klass = dns_protocol::kClassIN;
1509   additional_record.ttl = 120;  // 120 seconds.
1510   // Bitmap for "www.example.com" with type A set.
1511   additional_record.SetOwnedRdata(std::string("\xc0\x0c\x00\x01\x40", 5));
1512   std::vector<DnsResourceRecord> additional_records(1, additional_record);
1513   DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
1514                        {} /* authority_records */, additional_records, query);
1515   ASSERT_NE(nullptr, response.io_buffer());
1516   EXPECT_TRUE(response.IsValid());
1517   std::string expected_response(reinterpret_cast<const char*>(response_data),
1518                                 sizeof(response_data));
1519   std::string actual_response(response.io_buffer()->data(),
1520                               response.io_buffer_size());
1521   EXPECT_EQ(expected_response, actual_response);
1522 }
1523 
TEST(DnsResponseWriteTest,TwoAnswersWithAAndQuadARecords)1524 TEST(DnsResponseWriteTest, TwoAnswersWithAAndQuadARecords) {
1525   const uint8_t response_data[] = {
1526       0x12, 0x34,  // ID
1527       0x84, 0x00,  // flags, response with authoritative answer
1528       0x00, 0x00,  // number of questions
1529       0x00, 0x02,  // number of answer rr
1530       0x00, 0x00,  // number of name server rr
1531       0x00, 0x00,  // number of additional rr
1532       0x03, 'w',  'w',  'w',  0x07, 'e',  'x',  'a',  'm',  'p', 'l', 'e',
1533       0x03, 'c',  'o',  'm',
1534       0x00,                    // null label
1535       0x00, 0x01,              // type A Record
1536       0x00, 0x01,              // class IN
1537       0x00, 0x00, 0x00, 0x78,  // TTL, 120 seconds
1538       0x00, 0x04,              // rdlength, 32 bits
1539       0xc0, 0xa8, 0x00, 0x01,  // 192.168.0.1
1540       0x07, 'e',  'x',  'a',  'm',  'p',  'l',  'e',  0x03, 'o', 'r', 'g',
1541       0x00,                                            // null label
1542       0x00, 0x1c,                                      // type AAAA Record
1543       0x00, 0x01,                                      // class IN
1544       0x00, 0x00, 0x00, 0x3c,                          // TTL, 60 seconds
1545       0x00, 0x10,                                      // rdlength, 128 bits
1546       0xfd, 0x12, 0x34, 0x56, 0x78, 0x9a, 0x00, 0x01,  // fd12:3456:789a:1::1
1547       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1548   };
1549   net::DnsResourceRecord answer1;
1550   answer1.name = "www.example.com";
1551   answer1.type = dns_protocol::kTypeA;
1552   answer1.klass = dns_protocol::kClassIN;
1553   answer1.ttl = 120;  // 120 seconds.
1554   answer1.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
1555   net::DnsResourceRecord answer2;
1556   answer2.name = "example.org";
1557   answer2.type = dns_protocol::kTypeAAAA;
1558   answer2.klass = dns_protocol::kClassIN;
1559   answer2.ttl = 60;
1560   answer2.SetOwnedRdata(std::string(
1561       "\xfd\x12\x34\x56\x78\x9a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01", 16));
1562   std::vector<DnsResourceRecord> answers(2);
1563   answers[0] = answer1;
1564   answers[1] = answer2;
1565   DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
1566                        {} /* authority_records */, {} /* additional records */,
1567                        absl::nullopt);
1568   ASSERT_NE(nullptr, response.io_buffer());
1569   EXPECT_TRUE(response.IsValid());
1570   std::string expected_response(reinterpret_cast<const char*>(response_data),
1571                                 sizeof(response_data));
1572   std::string actual_response(response.io_buffer()->data(),
1573                               response.io_buffer_size());
1574   EXPECT_EQ(expected_response, actual_response);
1575 }
1576 
TEST(DnsResponseWriteTest,AnswerWithAuthorityRecord)1577 TEST(DnsResponseWriteTest, AnswerWithAuthorityRecord) {
1578   const uint8_t response_data[] = {
1579       0x12, 0x35,  // ID
1580       0x84, 0x00,  // flags, response with authoritative answer
1581       0x00, 0x00,  // number of questions
1582       0x00, 0x00,  // number of answer rr
1583       0x00, 0x01,  // number of name server rr
1584       0x00, 0x00,  // number of additional rr
1585       0x03, 'w',  'w',  'w',  0x07, 'e', 'x', 'a',
1586       'm',  'p',  'l',  'e',  0x03, 'c', 'o', 'm',
1587       0x00,                    // null label
1588       0x00, 0x01,              // type A Record
1589       0x00, 0x01,              // class IN
1590       0x00, 0x00, 0x00, 0x78,  // TTL, 120 seconds
1591       0x00, 0x04,              // rdlength, 32 bits
1592       0xc0, 0xa8, 0x00, 0x01,  // 192.168.0.1
1593   };
1594   DnsResourceRecord record;
1595   record.name = "www.example.com";
1596   record.type = dns_protocol::kTypeA;
1597   record.klass = dns_protocol::kClassIN;
1598   record.ttl = 120;  // 120 seconds.
1599   record.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
1600   std::vector<DnsResourceRecord> authority_records(1, record);
1601   DnsResponse response(0x1235 /* response_id */, true /* is_authoritative*/,
1602                        {} /* answers */, authority_records,
1603                        {} /* additional records */, absl::nullopt);
1604   ASSERT_NE(nullptr, response.io_buffer());
1605   EXPECT_TRUE(response.IsValid());
1606   std::string expected_response(reinterpret_cast<const char*>(response_data),
1607                                 sizeof(response_data));
1608   std::string actual_response(response.io_buffer()->data(),
1609                               response.io_buffer_size());
1610   EXPECT_EQ(expected_response, actual_response);
1611 }
1612 
TEST(DnsResponseWriteTest,AnswerWithRcode)1613 TEST(DnsResponseWriteTest, AnswerWithRcode) {
1614   const uint8_t response_data[] = {
1615       0x12, 0x12,  // ID
1616       0x80, 0x03,  // flags (response with non-existent domain)
1617       0x00, 0x00,  // number of questions
1618       0x00, 0x00,  // number of answer rr
1619       0x00, 0x00,  // number of name server rr
1620       0x00, 0x00,  // number of additional rr
1621   };
1622   DnsResponse response(0x1212 /* response_id */, false /* is_authoritative*/,
1623                        {} /* answers */, {} /* authority_records */,
1624                        {} /* additional records */, absl::nullopt,
1625                        dns_protocol::kRcodeNXDOMAIN);
1626   ASSERT_NE(nullptr, response.io_buffer());
1627   EXPECT_TRUE(response.IsValid());
1628   std::string expected_response(reinterpret_cast<const char*>(response_data),
1629                                 sizeof(response_data));
1630   std::string actual_response(response.io_buffer()->data(),
1631                               response.io_buffer_size());
1632   EXPECT_EQ(expected_response, actual_response);
1633   EXPECT_EQ(dns_protocol::kRcodeNXDOMAIN, response.rcode());
1634 }
1635 
1636 // CNAME answers are always allowed for any question.
TEST(DnsResponseWriteTest,AAAAQuestionAndCnameAnswer)1637 TEST(DnsResponseWriteTest, AAAAQuestionAndCnameAnswer) {
1638   const std::string kName = "www.example.com";
1639   absl::optional<std::vector<uint8_t>> dns_name =
1640       dns_names_util::DottedNameToNetwork(kName);
1641   ASSERT_TRUE(dns_name.has_value());
1642 
1643   DnsResourceRecord answer;
1644   answer.name = kName;
1645   answer.type = dns_protocol::kTypeCNAME;
1646   answer.klass = dns_protocol::kClassIN;
1647   answer.ttl = 120;  // 120 seconds.
1648   answer.SetOwnedRdata(
1649       std::string(reinterpret_cast<char*>(dns_name.value().data()),
1650                   dns_name.value().size()));
1651   std::vector<DnsResourceRecord> answers(1, answer);
1652 
1653   absl::optional<DnsQuery> query(absl::in_place, 114 /* id */, dns_name.value(),
1654                                  dns_protocol::kTypeAAAA);
1655 
1656   DnsResponse response(114 /* response_id */, true /* is_authoritative*/,
1657                        answers, {} /* authority_records */,
1658                        {} /* additional records */, query);
1659 
1660   EXPECT_TRUE(response.IsValid());
1661 }
1662 
TEST(DnsResponseWriteTest,WrittenResponseCanBeParsed)1663 TEST(DnsResponseWriteTest, WrittenResponseCanBeParsed) {
1664   std::string dotted_name("www.example.com");
1665   net::DnsResourceRecord answer;
1666   answer.name = dotted_name;
1667   answer.type = dns_protocol::kTypeA;
1668   answer.klass = dns_protocol::kClassIN;
1669   answer.ttl = 120;  // 120 seconds.
1670   answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
1671   std::vector<DnsResourceRecord> answers(1, answer);
1672   net::DnsResourceRecord additional_record;
1673   additional_record.name = dotted_name;
1674   additional_record.type = dns_protocol::kTypeNSEC;
1675   additional_record.klass = dns_protocol::kClassIN;
1676   additional_record.ttl = 120;  // 120 seconds.
1677   additional_record.SetOwnedRdata(std::string("\xc0\x0c\x00\x01\x04", 5));
1678   std::vector<DnsResourceRecord> additional_records(1, additional_record);
1679   DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/,
1680                        answers, {} /* authority_records */, additional_records,
1681                        absl::nullopt);
1682   ASSERT_NE(nullptr, response.io_buffer());
1683   EXPECT_TRUE(response.IsValid());
1684   EXPECT_THAT(response.id(), testing::Optional(0x1234));
1685   EXPECT_EQ(1u, response.answer_count());
1686   EXPECT_EQ(1u, response.additional_answer_count());
1687   auto parser = response.Parser();
1688   net::DnsResourceRecord parsed_record;
1689   EXPECT_TRUE(parser.ReadRecord(&parsed_record));
1690   // Answer with an A record.
1691   EXPECT_EQ(answer.name, parsed_record.name);
1692   EXPECT_EQ(answer.type, parsed_record.type);
1693   EXPECT_EQ(answer.klass, parsed_record.klass);
1694   EXPECT_EQ(answer.ttl, parsed_record.ttl);
1695   EXPECT_EQ(answer.owned_rdata, parsed_record.rdata);
1696   // Additional NSEC record.
1697   EXPECT_TRUE(parser.ReadRecord(&parsed_record));
1698   EXPECT_EQ(additional_record.name, parsed_record.name);
1699   EXPECT_EQ(additional_record.type, parsed_record.type);
1700   EXPECT_EQ(additional_record.klass, parsed_record.klass);
1701   EXPECT_EQ(additional_record.ttl, parsed_record.ttl);
1702   EXPECT_EQ(additional_record.owned_rdata, parsed_record.rdata);
1703 }
1704 
TEST(DnsResponseWriteTest,CreateEmptyNoDataResponse)1705 TEST(DnsResponseWriteTest, CreateEmptyNoDataResponse) {
1706   DnsResponse response = DnsResponse::CreateEmptyNoDataResponse(
1707       /*id=*/4,
1708       /*is_authoritative=*/true,
1709       base::as_bytes(base::make_span("\x04name\x04test\x00")),
1710       dns_protocol::kTypeA);
1711 
1712   EXPECT_TRUE(response.IsValid());
1713   EXPECT_THAT(response.id(), testing::Optional(4));
1714   EXPECT_TRUE(response.flags() & dns_protocol::kFlagAA);
1715   EXPECT_EQ(response.question_count(), 1u);
1716   EXPECT_EQ(response.answer_count(), 0u);
1717   EXPECT_EQ(response.authority_count(), 0u);
1718   EXPECT_EQ(response.additional_answer_count(), 0u);
1719 
1720   EXPECT_THAT(response.qtypes(), testing::ElementsAre(dns_protocol::kTypeA));
1721   EXPECT_THAT(response.dotted_qnames(), testing::ElementsAre("name.test"));
1722 }
1723 
1724 }  // namespace
1725 
1726 }  // namespace net
1727