OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/dns/dns_response.h" | 5 #include "net/dns/dns_response.h" |
6 | 6 |
| 7 #include "base/time.h" |
| 8 #include "net/base/address_list.h" |
7 #include "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
| 10 #include "net/base/net_util.h" |
| 11 #include "net/base/sys_addrinfo.h" |
8 #include "net/dns/dns_protocol.h" | 12 #include "net/dns/dns_protocol.h" |
9 #include "net/dns/dns_query.h" | 13 #include "net/dns/dns_query.h" |
| 14 #include "net/dns/dns_test_util.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
11 | 16 |
12 namespace net { | 17 namespace net { |
13 | 18 |
14 namespace { | 19 namespace { |
15 | 20 |
16 TEST(DnsRecordParserTest, Constructor) { | 21 TEST(DnsRecordParserTest, Constructor) { |
17 const char data[] = { 0 }; | 22 const char data[] = { 0 }; |
18 | 23 |
19 EXPECT_FALSE(DnsRecordParser().IsValid()); | 24 EXPECT_FALSE(DnsRecordParser().IsValid()); |
20 EXPECT_TRUE(DnsRecordParser(data, 1, 0).IsValid()); | 25 EXPECT_TRUE(DnsRecordParser(data, 1, 0).IsValid()); |
21 EXPECT_TRUE(DnsRecordParser(data, 1, 1).IsValid()); | 26 EXPECT_TRUE(DnsRecordParser(data, 1, 1).IsValid()); |
22 | 27 |
23 EXPECT_FALSE(DnsRecordParser(data, 1, 0).AtEnd()); | 28 EXPECT_FALSE(DnsRecordParser(data, 1, 0).AtEnd()); |
24 EXPECT_TRUE(DnsRecordParser(data, 1, 1).AtEnd()); | 29 EXPECT_TRUE(DnsRecordParser(data, 1, 1).AtEnd()); |
25 } | 30 } |
26 | 31 |
27 TEST(DnsRecordParserTest, ParseName) { | 32 TEST(DnsRecordParserTest, ReadName) { |
28 const uint8 data[] = { | 33 const uint8 data[] = { |
29 // all labels "foo.example.com" | 34 // all labels "foo.example.com" |
30 0x03, 'f', 'o', 'o', | 35 0x03, 'f', 'o', 'o', |
31 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', | 36 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', |
32 0x03, 'c', 'o', 'm', | 37 0x03, 'c', 'o', 'm', |
33 // byte 0x10 | 38 // byte 0x10 |
34 0x00, | 39 0x00, |
35 // byte 0x11 | 40 // byte 0x11 |
36 // part label, part pointer, "bar.example.com" | 41 // part label, part pointer, "bar.example.com" |
37 0x03, 'b', 'a', 'r', | 42 0x03, 'b', 'a', 'r', |
38 0xc0, 0x04, | 43 0xc0, 0x04, |
39 // byte 0x17 | 44 // byte 0x17 |
40 // all pointer to "bar.example.com", 2 jumps | 45 // all pointer to "bar.example.com", 2 jumps |
41 0xc0, 0x11, | 46 0xc0, 0x11, |
42 // byte 0x1a | 47 // byte 0x1a |
43 }; | 48 }; |
44 | 49 |
45 std::string out; | 50 std::string out; |
46 DnsRecordParser parser(data, sizeof(data), 0); | 51 DnsRecordParser parser(data, sizeof(data), 0); |
47 ASSERT_TRUE(parser.IsValid()); | 52 ASSERT_TRUE(parser.IsValid()); |
48 | 53 |
49 EXPECT_EQ(0x11, parser.ParseName(data + 0x00, &out)); | 54 EXPECT_EQ(0x11u, parser.ReadName(data + 0x00, &out)); |
50 EXPECT_EQ("foo.example.com", out); | 55 EXPECT_EQ("foo.example.com", out); |
51 // Check that the last "." is never stored. | 56 // Check that the last "." is never stored. |
52 out.clear(); | 57 out.clear(); |
53 EXPECT_EQ(0x1, parser.ParseName(data + 0x10, &out)); | 58 EXPECT_EQ(0x1u, parser.ReadName(data + 0x10, &out)); |
54 EXPECT_EQ("", out); | 59 EXPECT_EQ("", out); |
55 out.clear(); | 60 out.clear(); |
56 EXPECT_EQ(0x6, parser.ParseName(data + 0x11, &out)); | 61 EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, &out)); |
57 EXPECT_EQ("bar.example.com", out); | 62 EXPECT_EQ("bar.example.com", out); |
58 out.clear(); | 63 out.clear(); |
59 EXPECT_EQ(0x2, parser.ParseName(data + 0x17, &out)); | 64 EXPECT_EQ(0x2u, parser.ReadName(data + 0x17, &out)); |
60 EXPECT_EQ("bar.example.com", out); | 65 EXPECT_EQ("bar.example.com", out); |
61 | 66 |
62 // Parse name without storing it. | 67 // Parse name without storing it. |
63 EXPECT_EQ(0x11, parser.ParseName(data + 0x00, NULL)); | 68 EXPECT_EQ(0x11u, parser.ReadName(data + 0x00, NULL)); |
64 EXPECT_EQ(0x1, parser.ParseName(data + 0x10, NULL)); | 69 EXPECT_EQ(0x1u, parser.ReadName(data + 0x10, NULL)); |
65 EXPECT_EQ(0x6, parser.ParseName(data + 0x11, NULL)); | 70 EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, NULL)); |
66 EXPECT_EQ(0x2, parser.ParseName(data + 0x17, NULL)); | 71 EXPECT_EQ(0x2u, parser.ReadName(data + 0x17, NULL)); |
67 | 72 |
68 // Check that it works even if initial position is different. | 73 // Check that it works even if initial position is different. |
69 parser = DnsRecordParser(data, sizeof(data), 0x12); | 74 parser = DnsRecordParser(data, sizeof(data), 0x12); |
70 EXPECT_EQ(0x6, parser.ParseName(data + 0x11, NULL)); | 75 EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, NULL)); |
71 } | 76 } |
72 | 77 |
73 TEST(DnsRecordParserTest, ParseNameFail) { | 78 TEST(DnsRecordParserTest, ReadNameFail) { |
74 const uint8 data[] = { | 79 const uint8 data[] = { |
75 // label length beyond packet | 80 // label length beyond packet |
76 0x30, 'x', 'x', | 81 0x30, 'x', 'x', |
77 0x00, | 82 0x00, |
78 // pointer offset beyond packet | 83 // pointer offset beyond packet |
79 0xc0, 0x20, | 84 0xc0, 0x20, |
80 // pointer loop | 85 // pointer loop |
81 0xc0, 0x08, | 86 0xc0, 0x08, |
82 0xc0, 0x06, | 87 0xc0, 0x06, |
83 // incorrect label type (currently supports only direct and pointer) | 88 // incorrect label type (currently supports only direct and pointer) |
84 0x80, 0x00, | 89 0x80, 0x00, |
85 // truncated name (missing root label) | 90 // truncated name (missing root label) |
86 0x02, 'x', 'x', | 91 0x02, 'x', 'x', |
87 }; | 92 }; |
88 | 93 |
89 DnsRecordParser parser(data, sizeof(data), 0); | 94 DnsRecordParser parser(data, sizeof(data), 0); |
90 ASSERT_TRUE(parser.IsValid()); | 95 ASSERT_TRUE(parser.IsValid()); |
91 | 96 |
92 std::string out; | 97 std::string out; |
93 EXPECT_EQ(0, parser.ParseName(data + 0x00, &out)); | 98 EXPECT_EQ(0u, parser.ReadName(data + 0x00, &out)); |
94 EXPECT_EQ(0, parser.ParseName(data + 0x04, &out)); | 99 EXPECT_EQ(0u, parser.ReadName(data + 0x04, &out)); |
95 EXPECT_EQ(0, parser.ParseName(data + 0x08, &out)); | 100 EXPECT_EQ(0u, parser.ReadName(data + 0x08, &out)); |
96 EXPECT_EQ(0, parser.ParseName(data + 0x0a, &out)); | 101 EXPECT_EQ(0u, parser.ReadName(data + 0x0a, &out)); |
97 EXPECT_EQ(0, parser.ParseName(data + 0x0c, &out)); | 102 EXPECT_EQ(0u, parser.ReadName(data + 0x0c, &out)); |
98 EXPECT_EQ(0, parser.ParseName(data + 0x0e, &out)); | 103 EXPECT_EQ(0u, parser.ReadName(data + 0x0e, &out)); |
99 } | 104 } |
100 | 105 |
101 TEST(DnsRecordParserTest, ParseRecord) { | 106 TEST(DnsRecordParserTest, ReadRecord) { |
102 const uint8 data[] = { | 107 const uint8 data[] = { |
103 // Type CNAME record. | 108 // Type CNAME record. |
104 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', | 109 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', |
105 0x03, 'c', 'o', 'm', | 110 0x03, 'c', 'o', 'm', |
106 0x00, | 111 0x00, |
107 0x00, 0x05, // TYPE is CNAME. | 112 0x00, 0x05, // TYPE is CNAME. |
108 0x00, 0x01, // CLASS is IN. | 113 0x00, 0x01, // CLASS is IN. |
109 0x00, 0x01, 0x24, 0x74, // TTL is 0x00012474. | 114 0x00, 0x01, 0x24, 0x74, // TTL is 0x00012474. |
110 0x00, 0x06, // RDLENGTH is 6 bytes. | 115 0x00, 0x06, // RDLENGTH is 6 bytes. |
111 0x03, 'f', 'o', 'o', // compressed name in record | 116 0x03, 'f', 'o', 'o', // compressed name in record |
112 0xc0, 0x00, | 117 0xc0, 0x00, |
113 // Type A record. | 118 // Type A record. |
114 0x03, 'b', 'a', 'r', // compressed owner name | 119 0x03, 'b', 'a', 'r', // compressed owner name |
115 0xc0, 0x00, | 120 0xc0, 0x00, |
116 0x00, 0x01, // TYPE is A. | 121 0x00, 0x01, // TYPE is A. |
117 0x00, 0x01, // CLASS is IN. | 122 0x00, 0x01, // CLASS is IN. |
118 0x00, 0x20, 0x13, 0x55, // TTL is 0x00201355. | 123 0x00, 0x20, 0x13, 0x55, // TTL is 0x00201355. |
119 0x00, 0x04, // RDLENGTH is 4 bytes. | 124 0x00, 0x04, // RDLENGTH is 4 bytes. |
120 0x7f, 0x02, 0x04, 0x01, // IP is 127.2.4.1 | 125 0x7f, 0x02, 0x04, 0x01, // IP is 127.2.4.1 |
121 }; | 126 }; |
122 | 127 |
123 std::string out; | 128 std::string out; |
124 DnsRecordParser parser(data, sizeof(data), 0); | 129 DnsRecordParser parser(data, sizeof(data), 0); |
125 | 130 |
126 DnsResourceRecord record; | 131 DnsResourceRecord record; |
127 EXPECT_TRUE(parser.ParseRecord(&record)); | 132 EXPECT_TRUE(parser.ReadRecord(&record)); |
128 EXPECT_EQ("example.com", record.name); | 133 EXPECT_EQ("example.com", record.name); |
129 EXPECT_EQ(dns_protocol::kTypeCNAME, record.type); | 134 EXPECT_EQ(dns_protocol::kTypeCNAME, record.type); |
130 EXPECT_EQ(dns_protocol::kClassIN, record.klass); | 135 EXPECT_EQ(dns_protocol::kClassIN, record.klass); |
131 EXPECT_EQ(0x00012474u, record.ttl); | 136 EXPECT_EQ(0x00012474u, record.ttl); |
132 EXPECT_EQ(6u, record.rdata.length()); | 137 EXPECT_EQ(6u, record.rdata.length()); |
133 EXPECT_EQ(6, parser.ParseName(record.rdata.data(), &out)); | 138 EXPECT_EQ(6u, parser.ReadName(record.rdata.data(), &out)); |
134 EXPECT_EQ("foo.example.com", out); | 139 EXPECT_EQ("foo.example.com", out); |
135 EXPECT_FALSE(parser.AtEnd()); | 140 EXPECT_FALSE(parser.AtEnd()); |
136 | 141 |
137 EXPECT_TRUE(parser.ParseRecord(&record)); | 142 EXPECT_TRUE(parser.ReadRecord(&record)); |
138 EXPECT_EQ("bar.example.com", record.name); | 143 EXPECT_EQ("bar.example.com", record.name); |
139 EXPECT_EQ(dns_protocol::kTypeA, record.type); | 144 EXPECT_EQ(dns_protocol::kTypeA, record.type); |
140 EXPECT_EQ(dns_protocol::kClassIN, record.klass); | 145 EXPECT_EQ(dns_protocol::kClassIN, record.klass); |
141 EXPECT_EQ(0x00201355u, record.ttl); | 146 EXPECT_EQ(0x00201355u, record.ttl); |
142 EXPECT_EQ(4u, record.rdata.length()); | 147 EXPECT_EQ(4u, record.rdata.length()); |
143 EXPECT_EQ(base::StringPiece("\x7f\x02\x04\x01"), record.rdata); | 148 EXPECT_EQ(base::StringPiece("\x7f\x02\x04\x01"), record.rdata); |
144 EXPECT_TRUE(parser.AtEnd()); | 149 EXPECT_TRUE(parser.AtEnd()); |
145 | 150 |
146 // Test truncated record. | 151 // Test truncated record. |
147 parser = DnsRecordParser(data, sizeof(data) - 2, 0); | 152 parser = DnsRecordParser(data, sizeof(data) - 2, 0); |
148 EXPECT_TRUE(parser.ParseRecord(&record)); | 153 EXPECT_TRUE(parser.ReadRecord(&record)); |
149 EXPECT_FALSE(parser.AtEnd()); | 154 EXPECT_FALSE(parser.AtEnd()); |
150 EXPECT_FALSE(parser.ParseRecord(&record)); | 155 EXPECT_FALSE(parser.ReadRecord(&record)); |
151 } | 156 } |
152 | 157 |
153 TEST(DnsResponseTest, InitParse) { | 158 TEST(DnsResponseTest, InitParse) { |
154 // This includes \0 at the end. | 159 // This includes \0 at the end. |
155 const char qname_data[] = "\x0A""codereview""\x08""chromium""\x03""org"; | 160 const char qname_data[] = "\x0A""codereview""\x08""chromium""\x03""org"; |
156 const base::StringPiece qname(qname_data, sizeof(qname_data)); | 161 const base::StringPiece qname(qname_data, sizeof(qname_data)); |
157 // Compilers want to copy when binding temporary to const &, so must use heap. | 162 // Compilers want to copy when binding temporary to const &, so must use heap. |
158 scoped_ptr<DnsQuery> query(new DnsQuery(0xcafe, qname, dns_protocol::kTypeA)); | 163 scoped_ptr<DnsQuery> query(new DnsQuery(0xcafe, qname, dns_protocol::kTypeA)); |
159 | 164 |
160 const uint8 response_data[] = { | 165 const uint8 response_data[] = { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 EXPECT_FALSE(resp.InitParse(sizeof(response_data), *wrong_query)); | 223 EXPECT_FALSE(resp.InitParse(sizeof(response_data), *wrong_query)); |
219 EXPECT_FALSE(resp.IsValid()); | 224 EXPECT_FALSE(resp.IsValid()); |
220 | 225 |
221 // Accept matching question. | 226 // Accept matching question. |
222 EXPECT_TRUE(resp.InitParse(sizeof(response_data), *query)); | 227 EXPECT_TRUE(resp.InitParse(sizeof(response_data), *query)); |
223 EXPECT_TRUE(resp.IsValid()); | 228 EXPECT_TRUE(resp.IsValid()); |
224 | 229 |
225 // Check header access. | 230 // Check header access. |
226 EXPECT_EQ(0x8180, resp.flags()); | 231 EXPECT_EQ(0x8180, resp.flags()); |
227 EXPECT_EQ(0x0, resp.rcode()); | 232 EXPECT_EQ(0x0, resp.rcode()); |
228 EXPECT_EQ(2, resp.answer_count()); | 233 EXPECT_EQ(2u, resp.answer_count()); |
229 | 234 |
230 // Check question access. | 235 // Check question access. |
231 EXPECT_EQ(query->qname(), resp.qname()); | 236 EXPECT_EQ(query->qname(), resp.qname()); |
232 EXPECT_EQ(query->qtype(), resp.qtype()); | 237 EXPECT_EQ(query->qtype(), resp.qtype()); |
233 EXPECT_EQ("codereview.chromium.org", resp.GetDottedName()); | 238 EXPECT_EQ("codereview.chromium.org", resp.GetDottedName()); |
234 | 239 |
235 DnsResourceRecord record; | 240 DnsResourceRecord record; |
236 DnsRecordParser parser = resp.Parser(); | 241 DnsRecordParser parser = resp.Parser(); |
237 EXPECT_TRUE(parser.ParseRecord(&record)); | 242 EXPECT_TRUE(parser.ReadRecord(&record)); |
238 EXPECT_FALSE(parser.AtEnd()); | 243 EXPECT_FALSE(parser.AtEnd()); |
239 EXPECT_TRUE(parser.ParseRecord(&record)); | 244 EXPECT_TRUE(parser.ReadRecord(&record)); |
240 EXPECT_TRUE(parser.AtEnd()); | 245 EXPECT_TRUE(parser.AtEnd()); |
241 EXPECT_FALSE(parser.ParseRecord(&record)); | 246 EXPECT_FALSE(parser.ReadRecord(&record)); |
| 247 } |
| 248 |
| 249 void VerifyAddressList(const std::vector<const char*>& ip_addresses, |
| 250 const AddressList& addrlist) { |
| 251 ASSERT_GT(ip_addresses.size(), 0u); |
| 252 ASSERT_NE(static_cast<addrinfo*>(NULL), addrlist.head()); |
| 253 |
| 254 IPAddressNumber ip_number; |
| 255 const struct addrinfo* ainfo = addrlist.head(); |
| 256 for (std::vector<const char*>::const_iterator i = ip_addresses.begin(); |
| 257 i != ip_addresses.end(); ++i, ainfo = ainfo->ai_next) { |
| 258 ASSERT_NE(static_cast<addrinfo*>(NULL), ainfo); |
| 259 EXPECT_EQ(sizeof(struct sockaddr_in), |
| 260 static_cast<size_t>(ainfo->ai_addrlen)); |
| 261 |
| 262 const struct sockaddr* sa = ainfo->ai_addr; |
| 263 EXPECT_STREQ(*i, NetAddressToString(sa, ainfo->ai_addrlen).c_str()); |
| 264 } |
| 265 ASSERT_EQ(static_cast<addrinfo*>(NULL), ainfo); |
| 266 } |
| 267 |
| 268 TEST(DnsResponseTest, ParseToAddressList) { |
| 269 const struct TestCase { |
| 270 size_t query_size; |
| 271 const uint8* response_data; |
| 272 size_t response_size; |
| 273 const char* const* expected_addresses; |
| 274 size_t num_expected_addresses; |
| 275 const char* expected_cname; |
| 276 int expected_ttl_sec; |
| 277 } cases[] = { |
| 278 { |
| 279 kT0QuerySize, |
| 280 kT0ResponseDatagram, arraysize(kT0ResponseDatagram), |
| 281 kT0IpAddresses, arraysize(kT0IpAddresses), |
| 282 kT0CanonName, |
| 283 kT0TTL, |
| 284 }, |
| 285 { |
| 286 kT1QuerySize, |
| 287 kT1ResponseDatagram, arraysize(kT1ResponseDatagram), |
| 288 kT1IpAddresses, arraysize(kT1IpAddresses), |
| 289 kT1CanonName, |
| 290 kT1TTL, |
| 291 }, |
| 292 { |
| 293 kT2QuerySize, |
| 294 kT2ResponseDatagram, arraysize(kT2ResponseDatagram), |
| 295 kT2IpAddresses, arraysize(kT2IpAddresses), |
| 296 kT2CanonName, |
| 297 kT2TTL, |
| 298 }, |
| 299 { |
| 300 kT3QuerySize, |
| 301 kT3ResponseDatagram, arraysize(kT3ResponseDatagram), |
| 302 kT3IpAddresses, arraysize(kT3IpAddresses), |
| 303 kT3CanonName, |
| 304 kT3TTL, |
| 305 }, |
| 306 }; |
| 307 |
| 308 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
| 309 const TestCase& t = cases[i]; |
| 310 DnsResponse response(t.response_data, t.response_size, t.query_size); |
| 311 AddressList addr_list; |
| 312 base::TimeDelta ttl; |
| 313 EXPECT_EQ(DnsResponse::DNS_SUCCESS, |
| 314 response.ParseToAddressList(&addr_list, &ttl)); |
| 315 std::vector<const char*> expected_addresses( |
| 316 t.expected_addresses, |
| 317 t.expected_addresses + t.num_expected_addresses); |
| 318 VerifyAddressList(expected_addresses, addr_list); |
| 319 std::string cname; |
| 320 ASSERT_TRUE(addr_list.GetCanonicalName(&cname)); |
| 321 EXPECT_EQ(t.expected_cname, cname); |
| 322 EXPECT_EQ(base::TimeDelta::FromSeconds(t.expected_ttl_sec), ttl); |
| 323 } |
| 324 } |
| 325 |
| 326 const uint8 kResponseTruncatedRecord[] = { |
| 327 // Header: 1 question, 1 answer RR |
| 328 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, |
| 329 // Question: name = 'a', type = A (0x1) |
| 330 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
| 331 // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
| 332 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 333 0x00, 0x04, 0x0A, 0x0A, 0x0A, // Truncated RDATA. |
| 334 }; |
| 335 |
| 336 const uint8 kResponseTruncatedCNAME[] = { |
| 337 // Header: 1 question, 1 answer RR |
| 338 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, |
| 339 // Question: name = 'a', type = A (0x1) |
| 340 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
| 341 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'foo' (truncated) |
| 342 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 343 0x00, 0x03, 0x03, 'f', 'o', // Truncated name. |
| 344 }; |
| 345 |
| 346 const uint8 kResponseNameMismatch[] = { |
| 347 // Header: 1 question, 1 answer RR |
| 348 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, |
| 349 // Question: name = 'a', type = A (0x1) |
| 350 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
| 351 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
| 352 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 353 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
| 354 }; |
| 355 |
| 356 const uint8 kResponseNameMismatchInChain[] = { |
| 357 // Header: 1 question, 3 answer RR |
| 358 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, |
| 359 // Question: name = 'a', type = A (0x1) |
| 360 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
| 361 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = "b" |
| 362 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 363 0x00, 0x03, 0x01, 'b', 0x00, |
| 364 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
| 365 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 366 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
| 367 // Answer: name = 'c', type = A, TTL = 0xFF, RDATA = 10.10.10.11 |
| 368 0x01, 'c', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 369 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0B, |
| 370 }; |
| 371 |
| 372 const uint8 kResponseSizeMismatch[] = { |
| 373 // Header: 1 answer RR |
| 374 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, |
| 375 // Question: name = 'a', type = AAAA (0x1c) |
| 376 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, |
| 377 // Answer: name = 'a', type = AAAA, TTL = 0xFF, RDATA = 10.10.10.10 |
| 378 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 379 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
| 380 }; |
| 381 |
| 382 const uint8 kResponseCNAMEAfterAddress[] = { |
| 383 // Header: 2 answer RR |
| 384 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, |
| 385 // Question: name = 'a', type = A (0x1) |
| 386 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
| 387 // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10. |
| 388 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 389 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
| 390 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = "b" |
| 391 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 392 0x00, 0x03, 0x01, 'b', 0x00, |
| 393 }; |
| 394 |
| 395 const uint8 kResponseTTLMismatch[] = { |
| 396 // Header: 1 question, 3 answer RR |
| 397 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, |
| 398 // Question: name = 'a', type = A (0x1) |
| 399 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
| 400 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = "b" |
| 401 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 402 0x00, 0x03, 0x01, 'b', 0x00, |
| 403 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
| 404 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 405 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
| 406 // Answer: name = 'b', type = A, TTL = 0xBB, RDATA = 10.10.10.11 |
| 407 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xBB, |
| 408 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0B, |
| 409 }; |
| 410 |
| 411 const uint8 kResponseNoAddresses[] = { |
| 412 // Header: 1 question, 1 answer RR, 1 authority RR |
| 413 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, |
| 414 // Question: name = 'a', type = A (0x1) |
| 415 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
| 416 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = "b" |
| 417 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 418 0x00, 0x03, 0x01, 'b', 0x00, |
| 419 // Authority section |
| 420 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
| 421 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, |
| 422 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
| 423 }; |
| 424 |
| 425 TEST(DnsResponseTest, ParseToAddressListFail) { |
| 426 const struct TestCase { |
| 427 const uint8* data; |
| 428 size_t size; |
| 429 DnsResponse::Result expected_result; |
| 430 } cases[] = { |
| 431 { kResponseTruncatedRecord, arraysize(kResponseTruncatedRecord), |
| 432 DnsResponse::DNS_MALFORMED_RESPONSE }, |
| 433 { kResponseTruncatedCNAME, arraysize(kResponseTruncatedCNAME), |
| 434 DnsResponse::DNS_MALFORMED_CNAME }, |
| 435 { kResponseNameMismatch, arraysize(kResponseNameMismatch), |
| 436 DnsResponse::DNS_NAME_MISMATCH }, |
| 437 { kResponseNameMismatchInChain, arraysize(kResponseNameMismatchInChain), |
| 438 DnsResponse::DNS_NAME_MISMATCH }, |
| 439 { kResponseSizeMismatch, arraysize(kResponseSizeMismatch), |
| 440 DnsResponse::DNS_SIZE_MISMATCH }, |
| 441 { kResponseCNAMEAfterAddress, arraysize(kResponseCNAMEAfterAddress), |
| 442 DnsResponse::DNS_CNAME_AFTER_ADDRESS }, |
| 443 { kResponseTTLMismatch, arraysize(kResponseTTLMismatch), |
| 444 DnsResponse::DNS_ADDRESS_TTL_MISMATCH }, |
| 445 { kResponseNoAddresses, arraysize(kResponseNoAddresses), |
| 446 DnsResponse::DNS_NO_ADDRESSES }, |
| 447 }; |
| 448 |
| 449 const size_t kQuerySize = 12 + 7; |
| 450 |
| 451 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
| 452 const TestCase& t = cases[i]; |
| 453 |
| 454 DnsResponse response(t.data, t.size, kQuerySize); |
| 455 AddressList addr_list; |
| 456 base::TimeDelta ttl; |
| 457 EXPECT_EQ(t.expected_result, |
| 458 response.ParseToAddressList(&addr_list, &ttl)); |
| 459 } |
242 } | 460 } |
243 | 461 |
244 } // namespace | 462 } // namespace |
245 | 463 |
246 } // namespace net | 464 } // namespace net |
OLD | NEW |