• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "net/dns/record_rdata.h"
11 
12 #include <algorithm>
13 #include <memory>
14 #include <optional>
15 #include <string_view>
16 #include <utility>
17 
18 #include "base/big_endian.h"
19 #include "net/dns/dns_response.h"
20 #include "net/dns/dns_test_util.h"
21 #include "net/test/gtest_util.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 
25 namespace net {
26 namespace {
27 
28 using ::testing::ElementsAreArray;
29 using ::testing::IsNull;
30 using ::testing::NotNull;
31 using ::testing::SizeIs;
32 
MakeStringPiece(const uint8_t * data,unsigned size)33 std::string_view MakeStringPiece(const uint8_t* data, unsigned size) {
34   const char* data_cc = reinterpret_cast<const char*>(data);
35   return std::string_view(data_cc, size);
36 }
37 
TEST(RecordRdataTest,ParseSrvRecord)38 TEST(RecordRdataTest, ParseSrvRecord) {
39   // These are just the rdata portions of the DNS records, rather than complete
40   // records, but it works well enough for this test.
41 
42   const uint8_t
43       record[] =
44           {
45               0x00, 0x01, 0x00, 0x02, 0x00, 0x50, 0x03, 'w',  'w',
46               'w',  0x06, 'g',  'o',  'o',  'g',  'l',  'e',  0x03,
47               'c',  'o',  'm',  0x00, 0x01, 0x01, 0x01, 0x02, 0x01,
48               0x03, 0x04, 'w',  'w',  'w',  '2',  0xc0, 0x0a,  // Pointer to
49                                                                // "google.com"
50           };
51 
52   DnsRecordParser parser(record, 0, /*num_records=*/0);
53   const unsigned first_record_len = 22;
54   std::string_view record1_strpiece = MakeStringPiece(record, first_record_len);
55   std::string_view record2_strpiece = MakeStringPiece(
56       record + first_record_len, sizeof(record) - first_record_len);
57 
58   std::unique_ptr<SrvRecordRdata> record1_obj =
59       SrvRecordRdata::Create(record1_strpiece, parser);
60   ASSERT_TRUE(record1_obj != nullptr);
61   ASSERT_EQ(1, record1_obj->priority());
62   ASSERT_EQ(2, record1_obj->weight());
63   ASSERT_EQ(80, record1_obj->port());
64 
65   ASSERT_EQ("www.google.com", record1_obj->target());
66 
67   std::unique_ptr<SrvRecordRdata> record2_obj =
68       SrvRecordRdata::Create(record2_strpiece, parser);
69   ASSERT_TRUE(record2_obj != nullptr);
70   ASSERT_EQ(257, record2_obj->priority());
71   ASSERT_EQ(258, record2_obj->weight());
72   ASSERT_EQ(259, record2_obj->port());
73 
74   ASSERT_EQ("www2.google.com", record2_obj->target());
75 
76   ASSERT_TRUE(record1_obj->IsEqual(record1_obj.get()));
77   ASSERT_FALSE(record1_obj->IsEqual(record2_obj.get()));
78 }
79 
TEST(RecordRdataTest,ParseARecord)80 TEST(RecordRdataTest, ParseARecord) {
81   // These are just the rdata portions of the DNS records, rather than complete
82   // records, but it works well enough for this test.
83 
84   const uint8_t record[] = {
85       0x7F, 0x00, 0x00, 0x01  // 127.0.0.1
86   };
87 
88   DnsRecordParser parser(record, 0, /*num_records=*/0);
89   std::string_view record_strpiece = MakeStringPiece(record, sizeof(record));
90 
91   std::unique_ptr<ARecordRdata> record_obj =
92       ARecordRdata::Create(record_strpiece, parser);
93   ASSERT_TRUE(record_obj != nullptr);
94 
95   ASSERT_EQ("127.0.0.1", record_obj->address().ToString());
96 
97   ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
98 }
99 
TEST(RecordRdataTest,ParseAAAARecord)100 TEST(RecordRdataTest, ParseAAAARecord) {
101   // These are just the rdata portions of the DNS records, rather than complete
102   // records, but it works well enough for this test.
103 
104   const uint8_t record[] = {
105       0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
106       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09  // 1234:5678::9A
107   };
108 
109   DnsRecordParser parser(record, 0, /*num_records=*/0);
110   std::string_view record_strpiece = MakeStringPiece(record, sizeof(record));
111 
112   std::unique_ptr<AAAARecordRdata> record_obj =
113       AAAARecordRdata::Create(record_strpiece, parser);
114   ASSERT_TRUE(record_obj != nullptr);
115 
116   ASSERT_EQ("1234:5678::9", record_obj->address().ToString());
117 
118   ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
119 }
120 
TEST(RecordRdataTest,ParseCnameRecord)121 TEST(RecordRdataTest, ParseCnameRecord) {
122   // These are just the rdata portions of the DNS records, rather than complete
123   // records, but it works well enough for this test.
124 
125   const uint8_t record[] = {0x03, 'w', 'w', 'w',  0x06, 'g', 'o', 'o',
126                             'g',  'l', 'e', 0x03, 'c',  'o', 'm', 0x00};
127 
128   DnsRecordParser parser(record, 0, /*num_records=*/0);
129   std::string_view record_strpiece = MakeStringPiece(record, sizeof(record));
130 
131   std::unique_ptr<CnameRecordRdata> record_obj =
132       CnameRecordRdata::Create(record_strpiece, parser);
133   ASSERT_TRUE(record_obj != nullptr);
134 
135   ASSERT_EQ("www.google.com", record_obj->cname());
136 
137   ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
138 }
139 
TEST(RecordRdataTest,ParsePtrRecord)140 TEST(RecordRdataTest, ParsePtrRecord) {
141   // These are just the rdata portions of the DNS records, rather than complete
142   // records, but it works well enough for this test.
143 
144   const uint8_t record[] = {0x03, 'w', 'w', 'w',  0x06, 'g', 'o', 'o',
145                             'g',  'l', 'e', 0x03, 'c',  'o', 'm', 0x00};
146 
147   DnsRecordParser parser(record, 0, /*num_records=*/0);
148   std::string_view record_strpiece = MakeStringPiece(record, sizeof(record));
149 
150   std::unique_ptr<PtrRecordRdata> record_obj =
151       PtrRecordRdata::Create(record_strpiece, parser);
152   ASSERT_TRUE(record_obj != nullptr);
153 
154   ASSERT_EQ("www.google.com", record_obj->ptrdomain());
155 
156   ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
157 }
158 
TEST(RecordRdataTest,ParseTxtRecord)159 TEST(RecordRdataTest, ParseTxtRecord) {
160   // These are just the rdata portions of the DNS records, rather than complete
161   // records, but it works well enough for this test.
162 
163   const uint8_t record[] = {0x03, 'w', 'w', 'w',  0x06, 'g', 'o', 'o',
164                             'g',  'l', 'e', 0x03, 'c',  'o', 'm'};
165 
166   DnsRecordParser parser(record, 0, /*num_records=*/0);
167   std::string_view record_strpiece = MakeStringPiece(record, sizeof(record));
168 
169   std::unique_ptr<TxtRecordRdata> record_obj =
170       TxtRecordRdata::Create(record_strpiece, parser);
171   ASSERT_TRUE(record_obj != nullptr);
172 
173   std::vector<std::string> expected;
174   expected.push_back("www");
175   expected.push_back("google");
176   expected.push_back("com");
177 
178   ASSERT_EQ(expected, record_obj->texts());
179 
180   ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
181 }
182 
TEST(RecordRdataTest,ParseNsecRecord)183 TEST(RecordRdataTest, ParseNsecRecord) {
184   // These are just the rdata portions of the DNS records, rather than complete
185   // records, but it works well enough for this test.
186 
187   const uint8_t record[] = {0x03, 'w',  'w',  'w',  0x06, 'g', 'o',
188                             'o',  'g',  'l',  'e',  0x03, 'c', 'o',
189                             'm',  0x00, 0x00, 0x02, 0x40, 0x01};
190 
191   DnsRecordParser parser(record, 0, /*num_records=*/0);
192   std::string_view record_strpiece = MakeStringPiece(record, sizeof(record));
193 
194   std::unique_ptr<NsecRecordRdata> record_obj =
195       NsecRecordRdata::Create(record_strpiece, parser);
196   ASSERT_TRUE(record_obj != nullptr);
197 
198   ASSERT_EQ(16u, record_obj->bitmap_length());
199 
200   EXPECT_FALSE(record_obj->GetBit(0));
201   EXPECT_TRUE(record_obj->GetBit(1));
202   for (int i = 2; i < 15; i++) {
203     EXPECT_FALSE(record_obj->GetBit(i));
204   }
205   EXPECT_TRUE(record_obj->GetBit(15));
206 
207   ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
208 }
209 
TEST(RecordRdataTest,CreateNsecRecordWithEmptyBitmapReturnsNull)210 TEST(RecordRdataTest, CreateNsecRecordWithEmptyBitmapReturnsNull) {
211   // These are just the rdata portions of the DNS records, rather than complete
212   // records, but it works well enough for this test.
213   // This record has a bitmap that is 0 bytes long.
214   const uint8_t record[] = {0x03, 'w', 'w',  'w', 0x06, 'g', 'o',  'o',  'g',
215                             'l',  'e', 0x03, 'c', 'o',  'm', 0x00, 0x00, 0x00};
216 
217   DnsRecordParser parser(record, 0, /*num_records=*/0);
218   std::string_view record_strpiece = MakeStringPiece(record, sizeof(record));
219 
220   std::unique_ptr<NsecRecordRdata> record_obj =
221       NsecRecordRdata::Create(record_strpiece, parser);
222   ASSERT_FALSE(record_obj);
223 }
224 
TEST(RecordRdataTest,CreateNsecRecordWithOversizedBitmapReturnsNull)225 TEST(RecordRdataTest, CreateNsecRecordWithOversizedBitmapReturnsNull) {
226   // These are just the rdata portions of the DNS records, rather than complete
227   // records, but it works well enough for this test.
228   // This record has a bitmap that is 33 bytes long. The maximum size allowed by
229   // RFC 3845, Section 2.1.2, is 32 bytes.
230   const uint8_t record[] = {
231       0x03, 'w',  'w',  'w',  0x06, 'g',  'o',  'o',  'g',  'l',  'e',
232       0x03, 'c',  'o',  'm',  0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00,
233       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
236 
237   DnsRecordParser parser(record, 0, /*num_records=*/0);
238   std::string_view record_strpiece = MakeStringPiece(record, sizeof(record));
239 
240   std::unique_ptr<NsecRecordRdata> record_obj =
241       NsecRecordRdata::Create(record_strpiece, parser);
242   ASSERT_FALSE(record_obj);
243 }
244 
245 }  // namespace
246 }  // namespace net
247