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/time.h" | 7 #include "base/time/time.h" |
8 #include "net/base/address_list.h" | 8 #include "net/base/address_list.h" |
9 #include "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
10 #include "net/base/net_util.h" | 10 #include "net/base/net_util.h" |
11 #include "net/dns/dns_protocol.h" | 11 #include "net/dns/dns_protocol.h" |
12 #include "net/dns/dns_query.h" | 12 #include "net/dns/dns_query.h" |
13 #include "net/dns/dns_test_util.h" | 13 #include "net/dns/dns_test_util.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
15 | 15 |
16 namespace net { | 16 namespace net { |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 TEST(DnsRecordParserTest, Constructor) { | 20 TEST(DnsRecordParserTest, Constructor) { |
21 const char data[] = { 0 }; | 21 const char data[] = {0}; |
22 | 22 |
23 EXPECT_FALSE(DnsRecordParser().IsValid()); | 23 EXPECT_FALSE(DnsRecordParser().IsValid()); |
24 EXPECT_TRUE(DnsRecordParser(data, 1, 0).IsValid()); | 24 EXPECT_TRUE(DnsRecordParser(data, 1, 0).IsValid()); |
25 EXPECT_TRUE(DnsRecordParser(data, 1, 1).IsValid()); | 25 EXPECT_TRUE(DnsRecordParser(data, 1, 1).IsValid()); |
26 | 26 |
27 EXPECT_FALSE(DnsRecordParser(data, 1, 0).AtEnd()); | 27 EXPECT_FALSE(DnsRecordParser(data, 1, 0).AtEnd()); |
28 EXPECT_TRUE(DnsRecordParser(data, 1, 1).AtEnd()); | 28 EXPECT_TRUE(DnsRecordParser(data, 1, 1).AtEnd()); |
29 } | 29 } |
30 | 30 |
31 TEST(DnsRecordParserTest, ReadName) { | 31 TEST(DnsRecordParserTest, ReadName) { |
32 const uint8 data[] = { | 32 const uint8 data[] = {// all labels "foo.example.com" |
33 // all labels "foo.example.com" | 33 0x03, 'f', 'o', 'o', 0x07, 'e', 'x', 'a', |
34 0x03, 'f', 'o', 'o', | 34 'm', 'p', 'l', 'e', 0x03, 'c', 'o', 'm', |
35 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', | 35 // byte 0x10 |
36 0x03, 'c', 'o', 'm', | 36 0x00, |
37 // byte 0x10 | 37 // byte 0x11 |
38 0x00, | 38 // part label, part pointer, "bar.example.com" |
39 // byte 0x11 | 39 0x03, 'b', 'a', 'r', 0xc0, 0x04, |
40 // part label, part pointer, "bar.example.com" | 40 // byte 0x17 |
41 0x03, 'b', 'a', 'r', | 41 // all pointer to "bar.example.com", 2 jumps |
42 0xc0, 0x04, | 42 0xc0, 0x11, |
43 // byte 0x17 | 43 // byte 0x1a |
44 // all pointer to "bar.example.com", 2 jumps | |
45 0xc0, 0x11, | |
46 // byte 0x1a | |
47 }; | 44 }; |
48 | 45 |
49 std::string out; | 46 std::string out; |
50 DnsRecordParser parser(data, sizeof(data), 0); | 47 DnsRecordParser parser(data, sizeof(data), 0); |
51 ASSERT_TRUE(parser.IsValid()); | 48 ASSERT_TRUE(parser.IsValid()); |
52 | 49 |
53 EXPECT_EQ(0x11u, parser.ReadName(data + 0x00, &out)); | 50 EXPECT_EQ(0x11u, parser.ReadName(data + 0x00, &out)); |
54 EXPECT_EQ("foo.example.com", out); | 51 EXPECT_EQ("foo.example.com", out); |
55 // Check that the last "." is never stored. | 52 // Check that the last "." is never stored. |
56 out.clear(); | 53 out.clear(); |
(...skipping 13 matching lines...) Expand all Loading... |
70 EXPECT_EQ(0x2u, parser.ReadName(data + 0x17, NULL)); | 67 EXPECT_EQ(0x2u, parser.ReadName(data + 0x17, NULL)); |
71 | 68 |
72 // Check that it works even if initial position is different. | 69 // Check that it works even if initial position is different. |
73 parser = DnsRecordParser(data, sizeof(data), 0x12); | 70 parser = DnsRecordParser(data, sizeof(data), 0x12); |
74 EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, NULL)); | 71 EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, NULL)); |
75 } | 72 } |
76 | 73 |
77 TEST(DnsRecordParserTest, ReadNameFail) { | 74 TEST(DnsRecordParserTest, ReadNameFail) { |
78 const uint8 data[] = { | 75 const uint8 data[] = { |
79 // label length beyond packet | 76 // label length beyond packet |
80 0x30, 'x', 'x', | 77 0x30, 'x', 'x', 0x00, |
81 0x00, | |
82 // pointer offset beyond packet | 78 // pointer offset beyond packet |
83 0xc0, 0x20, | 79 0xc0, 0x20, |
84 // pointer loop | 80 // pointer loop |
85 0xc0, 0x08, | 81 0xc0, 0x08, 0xc0, 0x06, |
86 0xc0, 0x06, | |
87 // incorrect label type (currently supports only direct and pointer) | 82 // incorrect label type (currently supports only direct and pointer) |
88 0x80, 0x00, | 83 0x80, 0x00, |
89 // truncated name (missing root label) | 84 // truncated name (missing root label) |
90 0x02, 'x', 'x', | 85 0x02, 'x', 'x', |
91 }; | 86 }; |
92 | 87 |
93 DnsRecordParser parser(data, sizeof(data), 0); | 88 DnsRecordParser parser(data, sizeof(data), 0); |
94 ASSERT_TRUE(parser.IsValid()); | 89 ASSERT_TRUE(parser.IsValid()); |
95 | 90 |
96 std::string out; | 91 std::string out; |
97 EXPECT_EQ(0u, parser.ReadName(data + 0x00, &out)); | 92 EXPECT_EQ(0u, parser.ReadName(data + 0x00, &out)); |
98 EXPECT_EQ(0u, parser.ReadName(data + 0x04, &out)); | 93 EXPECT_EQ(0u, parser.ReadName(data + 0x04, &out)); |
99 EXPECT_EQ(0u, parser.ReadName(data + 0x08, &out)); | 94 EXPECT_EQ(0u, parser.ReadName(data + 0x08, &out)); |
100 EXPECT_EQ(0u, parser.ReadName(data + 0x0a, &out)); | 95 EXPECT_EQ(0u, parser.ReadName(data + 0x0a, &out)); |
101 EXPECT_EQ(0u, parser.ReadName(data + 0x0c, &out)); | 96 EXPECT_EQ(0u, parser.ReadName(data + 0x0c, &out)); |
102 EXPECT_EQ(0u, parser.ReadName(data + 0x0e, &out)); | 97 EXPECT_EQ(0u, parser.ReadName(data + 0x0e, &out)); |
103 } | 98 } |
104 | 99 |
105 TEST(DnsRecordParserTest, ReadRecord) { | 100 TEST(DnsRecordParserTest, ReadRecord) { |
106 const uint8 data[] = { | 101 const uint8 data[] = { |
107 // Type CNAME record. | 102 // Type CNAME record. |
108 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', | 103 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', |
109 0x03, 'c', 'o', 'm', | 104 0x03, 'c', 'o', 'm', 0x00, 0x00, 0x05, // TYPE is CNAME. |
110 0x00, | 105 0x00, 0x01, // CLASS is IN. |
111 0x00, 0x05, // TYPE is CNAME. | 106 0x00, 0x01, 0x24, 0x74, // TTL is 0x00012474. |
112 0x00, 0x01, // CLASS is IN. | 107 0x00, 0x06, // RDLENGTH is 6 bytes. |
113 0x00, 0x01, 0x24, 0x74, // TTL is 0x00012474. | 108 0x03, 'f', 'o', 'o', // compressed name in record |
114 0x00, 0x06, // RDLENGTH is 6 bytes. | |
115 0x03, 'f', 'o', 'o', // compressed name in record | |
116 0xc0, 0x00, | 109 0xc0, 0x00, |
117 // Type A record. | 110 // Type A record. |
118 0x03, 'b', 'a', 'r', // compressed owner name | 111 0x03, 'b', 'a', 'r', // compressed owner name |
119 0xc0, 0x00, | 112 0xc0, 0x00, 0x00, 0x01, // TYPE is A. |
120 0x00, 0x01, // TYPE is A. | |
121 0x00, 0x01, // CLASS is IN. | 113 0x00, 0x01, // CLASS is IN. |
122 0x00, 0x20, 0x13, 0x55, // TTL is 0x00201355. | 114 0x00, 0x20, 0x13, 0x55, // TTL is 0x00201355. |
123 0x00, 0x04, // RDLENGTH is 4 bytes. | 115 0x00, 0x04, // RDLENGTH is 4 bytes. |
124 0x7f, 0x02, 0x04, 0x01, // IP is 127.2.4.1 | 116 0x7f, 0x02, 0x04, 0x01, // IP is 127.2.4.1 |
125 }; | 117 }; |
126 | 118 |
127 std::string out; | 119 std::string out; |
128 DnsRecordParser parser(data, sizeof(data), 0); | 120 DnsRecordParser parser(data, sizeof(data), 0); |
129 | 121 |
130 DnsResourceRecord record; | 122 DnsResourceRecord record; |
(...skipping 18 matching lines...) Expand all Loading... |
149 | 141 |
150 // Test truncated record. | 142 // Test truncated record. |
151 parser = DnsRecordParser(data, sizeof(data) - 2, 0); | 143 parser = DnsRecordParser(data, sizeof(data) - 2, 0); |
152 EXPECT_TRUE(parser.ReadRecord(&record)); | 144 EXPECT_TRUE(parser.ReadRecord(&record)); |
153 EXPECT_FALSE(parser.AtEnd()); | 145 EXPECT_FALSE(parser.AtEnd()); |
154 EXPECT_FALSE(parser.ReadRecord(&record)); | 146 EXPECT_FALSE(parser.ReadRecord(&record)); |
155 } | 147 } |
156 | 148 |
157 TEST(DnsResponseTest, InitParse) { | 149 TEST(DnsResponseTest, InitParse) { |
158 // This includes \0 at the end. | 150 // This includes \0 at the end. |
159 const char qname_data[] = "\x0A""codereview""\x08""chromium""\x03""org"; | 151 const char qname_data[] = |
| 152 "\x0A" |
| 153 "codereview" |
| 154 "\x08" |
| 155 "chromium" |
| 156 "\x03" |
| 157 "org"; |
160 const base::StringPiece qname(qname_data, sizeof(qname_data)); | 158 const base::StringPiece qname(qname_data, sizeof(qname_data)); |
161 // Compilers want to copy when binding temporary to const &, so must use heap. | 159 // Compilers want to copy when binding temporary to const &, so must use heap. |
162 scoped_ptr<DnsQuery> query(new DnsQuery(0xcafe, qname, dns_protocol::kTypeA)); | 160 scoped_ptr<DnsQuery> query(new DnsQuery(0xcafe, qname, dns_protocol::kTypeA)); |
163 | 161 |
164 const uint8 response_data[] = { | 162 const uint8 response_data[] = { |
165 // Header | 163 // Header |
166 0xca, 0xfe, // ID | 164 0xca, 0xfe, // ID |
167 0x81, 0x80, // Standard query response, RA, no error | 165 0x81, 0x80, // Standard query response, RA, no error |
168 0x00, 0x01, // 1 question | 166 0x00, 0x01, // 1 question |
169 0x00, 0x02, // 2 RRs (answers) | 167 0x00, 0x02, // 2 RRs (answers) |
170 0x00, 0x00, // 0 authority RRs | 168 0x00, 0x00, // 0 authority RRs |
171 0x00, 0x00, // 0 additional RRs | 169 0x00, 0x00, // 0 additional RRs |
172 | 170 |
173 // Question | 171 // Question |
174 // This part is echoed back from the respective query. | 172 // This part is echoed back from the respective query. |
175 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', | 173 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', |
176 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', | 174 'e', 'w', 0x08, 'c', 'h', 'r', 'o', 'm', 'i', |
177 0x03, 'o', 'r', 'g', | 175 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00, 0x01, // TYPE is A. |
178 0x00, | 176 0x00, 0x01, // CLASS is IN. |
179 0x00, 0x01, // TYPE is A. | |
180 0x00, 0x01, // CLASS is IN. | |
181 | 177 |
182 // Answer 1 | 178 // Answer 1 |
183 0xc0, 0x0c, // NAME is a pointer to name in Question section. | 179 0xc0, 0x0c, // NAME is a pointer to name in Question section. |
184 0x00, 0x05, // TYPE is CNAME. | 180 0x00, 0x05, // TYPE is CNAME. |
185 0x00, 0x01, // CLASS is IN. | 181 0x00, 0x01, // CLASS is IN. |
186 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. | 182 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. |
187 0x24, 0x74, | 183 0x24, 0x74, 0x00, 0x12, // RDLENGTH is 18 bytes. |
188 0x00, 0x12, // RDLENGTH is 18 bytes. | 184 // ghs.l.google.com in DNS format. |
189 // ghs.l.google.com in DNS format. | 185 0x03, 'g', 'h', 's', 0x01, 'l', 0x06, 'g', 'o', |
190 0x03, 'g', 'h', 's', | 186 'o', 'g', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00, |
191 0x01, 'l', | |
192 0x06, 'g', 'o', 'o', 'g', 'l', 'e', | |
193 0x03, 'c', 'o', 'm', | |
194 0x00, | |
195 | 187 |
196 // Answer 2 | 188 // Answer 2 |
197 0xc0, 0x35, // NAME is a pointer to name in Answer 1. | 189 0xc0, 0x35, // NAME is a pointer to name in Answer 1. |
198 0x00, 0x01, // TYPE is A. | 190 0x00, 0x01, // TYPE is A. |
199 0x00, 0x01, // CLASS is IN. | 191 0x00, 0x01, // CLASS is IN. |
200 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | 192 0x00, 0x00, // TTL (4 bytes) is 53 seconds. |
201 0x00, 0x35, | 193 0x00, 0x35, 0x00, 0x04, // RDLENGTH is 4 bytes. |
202 0x00, 0x04, // RDLENGTH is 4 bytes. | 194 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 |
203 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | 195 0x5f, 0x79, |
204 0x5f, 0x79, | |
205 }; | 196 }; |
206 | 197 |
207 DnsResponse resp; | 198 DnsResponse resp; |
208 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); | 199 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); |
209 | 200 |
210 // Reject too short. | 201 // Reject too short. |
211 EXPECT_FALSE(resp.InitParse(query->io_buffer()->size() - 1, *query)); | 202 EXPECT_FALSE(resp.InitParse(query->io_buffer()->size() - 1, *query)); |
212 EXPECT_FALSE(resp.IsValid()); | 203 EXPECT_FALSE(resp.IsValid()); |
213 | 204 |
214 // Reject wrong id. | 205 // Reject wrong id. |
(...skipping 25 matching lines...) Expand all Loading... |
240 DnsRecordParser parser = resp.Parser(); | 231 DnsRecordParser parser = resp.Parser(); |
241 EXPECT_TRUE(parser.ReadRecord(&record)); | 232 EXPECT_TRUE(parser.ReadRecord(&record)); |
242 EXPECT_FALSE(parser.AtEnd()); | 233 EXPECT_FALSE(parser.AtEnd()); |
243 EXPECT_TRUE(parser.ReadRecord(&record)); | 234 EXPECT_TRUE(parser.ReadRecord(&record)); |
244 EXPECT_TRUE(parser.AtEnd()); | 235 EXPECT_TRUE(parser.AtEnd()); |
245 EXPECT_FALSE(parser.ReadRecord(&record)); | 236 EXPECT_FALSE(parser.ReadRecord(&record)); |
246 } | 237 } |
247 | 238 |
248 TEST(DnsResponseTest, InitParseWithoutQuery) { | 239 TEST(DnsResponseTest, InitParseWithoutQuery) { |
249 DnsResponse resp; | 240 DnsResponse resp; |
250 memcpy(resp.io_buffer()->data(), kT0ResponseDatagram, | 241 memcpy(resp.io_buffer()->data(), |
| 242 kT0ResponseDatagram, |
251 sizeof(kT0ResponseDatagram)); | 243 sizeof(kT0ResponseDatagram)); |
252 | 244 |
253 // Accept matching question. | 245 // Accept matching question. |
254 EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(kT0ResponseDatagram))); | 246 EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(kT0ResponseDatagram))); |
255 EXPECT_TRUE(resp.IsValid()); | 247 EXPECT_TRUE(resp.IsValid()); |
256 | 248 |
257 // Check header access. | 249 // Check header access. |
258 EXPECT_EQ(0x8180, resp.flags()); | 250 EXPECT_EQ(0x8180, resp.flags()); |
259 EXPECT_EQ(0x0, resp.rcode()); | 251 EXPECT_EQ(0x0, resp.rcode()); |
260 EXPECT_EQ(kT0RecordCount, resp.answer_count()); | 252 EXPECT_EQ(kT0RecordCount, resp.answer_count()); |
261 | 253 |
262 // Check question access. | 254 // Check question access. |
263 EXPECT_EQ(kT0Qtype, resp.qtype()); | 255 EXPECT_EQ(kT0Qtype, resp.qtype()); |
264 EXPECT_EQ(kT0HostName, resp.GetDottedName()); | 256 EXPECT_EQ(kT0HostName, resp.GetDottedName()); |
265 | 257 |
266 DnsResourceRecord record; | 258 DnsResourceRecord record; |
267 DnsRecordParser parser = resp.Parser(); | 259 DnsRecordParser parser = resp.Parser(); |
268 for (unsigned i = 0; i < kT0RecordCount; i ++) { | 260 for (unsigned i = 0; i < kT0RecordCount; i++) { |
269 EXPECT_FALSE(parser.AtEnd()); | 261 EXPECT_FALSE(parser.AtEnd()); |
270 EXPECT_TRUE(parser.ReadRecord(&record)); | 262 EXPECT_TRUE(parser.ReadRecord(&record)); |
271 } | 263 } |
272 EXPECT_TRUE(parser.AtEnd()); | 264 EXPECT_TRUE(parser.AtEnd()); |
273 EXPECT_FALSE(parser.ReadRecord(&record)); | 265 EXPECT_FALSE(parser.ReadRecord(&record)); |
274 } | 266 } |
275 | 267 |
276 TEST(DnsResponseTest, InitParseWithoutQueryNoQuestions) { | 268 TEST(DnsResponseTest, InitParseWithoutQueryNoQuestions) { |
277 const uint8 response_data[] = { | 269 const uint8 response_data[] = { |
278 // Header | 270 // Header |
279 0xca, 0xfe, // ID | 271 0xca, 0xfe, // ID |
280 0x81, 0x80, // Standard query response, RA, no error | 272 0x81, 0x80, // Standard query response, RA, no error |
281 0x00, 0x00, // No question | 273 0x00, 0x00, // No question |
282 0x00, 0x01, // 2 RRs (answers) | 274 0x00, 0x01, // 2 RRs (answers) |
283 0x00, 0x00, // 0 authority RRs | 275 0x00, 0x00, // 0 authority RRs |
284 0x00, 0x00, // 0 additional RRs | 276 0x00, 0x00, // 0 additional RRs |
285 | 277 |
286 // Answer 1 | 278 // Answer 1 |
287 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', | 279 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', |
288 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', | 280 'e', 'w', 0x08, 'c', 'h', 'r', 'o', 'm', 'i', |
289 0x03, 'o', 'r', 'g', | 281 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00, 0x01, // TYPE is A. |
290 0x00, | 282 0x00, 0x01, // CLASS is IN. |
291 0x00, 0x01, // TYPE is A. | 283 0x00, 0x00, // TTL (4 bytes) is 53 seconds. |
292 0x00, 0x01, // CLASS is IN. | 284 0x00, 0x35, 0x00, 0x04, // RDLENGTH is 4 bytes. |
293 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | 285 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 |
294 0x00, 0x35, | 286 0x5f, 0x79, |
295 0x00, 0x04, // RDLENGTH is 4 bytes. | |
296 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | |
297 0x5f, 0x79, | |
298 }; | 287 }; |
299 | 288 |
300 DnsResponse resp; | 289 DnsResponse resp; |
301 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); | 290 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); |
302 | 291 |
303 EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(response_data))); | 292 EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(response_data))); |
304 | 293 |
305 // Check header access. | 294 // Check header access. |
306 EXPECT_EQ(0x8180, resp.flags()); | 295 EXPECT_EQ(0x8180, resp.flags()); |
307 EXPECT_EQ(0x0, resp.rcode()); | 296 EXPECT_EQ(0x0, resp.rcode()); |
308 EXPECT_EQ(0x1u, resp.answer_count()); | 297 EXPECT_EQ(0x1u, resp.answer_count()); |
309 | 298 |
310 DnsResourceRecord record; | 299 DnsResourceRecord record; |
311 DnsRecordParser parser = resp.Parser(); | 300 DnsRecordParser parser = resp.Parser(); |
312 | 301 |
313 EXPECT_FALSE(parser.AtEnd()); | 302 EXPECT_FALSE(parser.AtEnd()); |
314 EXPECT_TRUE(parser.ReadRecord(&record)); | 303 EXPECT_TRUE(parser.ReadRecord(&record)); |
315 EXPECT_EQ("codereview.chromium.org", record.name); | 304 EXPECT_EQ("codereview.chromium.org", record.name); |
316 EXPECT_EQ(0x00000035u, record.ttl); | 305 EXPECT_EQ(0x00000035u, record.ttl); |
317 EXPECT_EQ(dns_protocol::kTypeA, record.type); | 306 EXPECT_EQ(dns_protocol::kTypeA, record.type); |
318 | 307 |
319 EXPECT_TRUE(parser.AtEnd()); | 308 EXPECT_TRUE(parser.AtEnd()); |
320 EXPECT_FALSE(parser.ReadRecord(&record)); | 309 EXPECT_FALSE(parser.ReadRecord(&record)); |
321 } | 310 } |
322 | 311 |
323 TEST(DnsResponseTest, InitParseWithoutQueryTwoQuestions) { | 312 TEST(DnsResponseTest, InitParseWithoutQueryTwoQuestions) { |
324 const uint8 response_data[] = { | 313 const uint8 response_data[] = { |
325 // Header | 314 // Header |
326 0xca, 0xfe, // ID | 315 0xca, 0xfe, // ID |
327 0x81, 0x80, // Standard query response, RA, no error | 316 0x81, 0x80, // Standard query response, RA, no error |
328 0x00, 0x02, // 2 questions | 317 0x00, 0x02, // 2 questions |
329 0x00, 0x01, // 2 RRs (answers) | 318 0x00, 0x01, // 2 RRs (answers) |
330 0x00, 0x00, // 0 authority RRs | 319 0x00, 0x00, // 0 authority RRs |
331 0x00, 0x00, // 0 additional RRs | 320 0x00, 0x00, // 0 additional RRs |
332 | 321 |
333 // Question 1 | 322 // Question 1 |
334 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', | 323 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', |
335 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', | 324 'e', 'w', 0x08, 'c', 'h', 'r', 'o', 'm', 'i', |
336 0x03, 'o', 'r', 'g', | 325 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00, 0x01, // TYPE is A. |
337 0x00, | 326 0x00, 0x01, // CLASS is IN. |
338 0x00, 0x01, // TYPE is A. | |
339 0x00, 0x01, // CLASS is IN. | |
340 | 327 |
341 // Question 2 | 328 // Question 2 |
342 0x0b, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', '2', | 329 0x0b, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', |
343 0xc0, 0x18, // pointer to "chromium.org" | 330 'e', 'w', '2', 0xc0, 0x18, // pointer to "chromium.org" |
344 0x00, 0x01, // TYPE is A. | 331 0x00, 0x01, // TYPE is A. |
345 0x00, 0x01, // CLASS is IN. | 332 0x00, 0x01, // CLASS is IN. |
346 | 333 |
347 // Answer 1 | 334 // Answer 1 |
348 0xc0, 0x0c, // NAME is a pointer to name in Question section. | 335 0xc0, 0x0c, // NAME is a pointer to name in Question section. |
349 0x00, 0x01, // TYPE is A. | 336 0x00, 0x01, // TYPE is A. |
350 0x00, 0x01, // CLASS is IN. | 337 0x00, 0x01, // CLASS is IN. |
351 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | 338 0x00, 0x00, // TTL (4 bytes) is 53 seconds. |
352 0x00, 0x35, | 339 0x00, 0x35, 0x00, 0x04, // RDLENGTH is 4 bytes. |
353 0x00, 0x04, // RDLENGTH is 4 bytes. | 340 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 |
354 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | 341 0x5f, 0x79, |
355 0x5f, 0x79, | |
356 }; | 342 }; |
357 | 343 |
358 DnsResponse resp; | 344 DnsResponse resp; |
359 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); | 345 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); |
360 | 346 |
361 EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(response_data))); | 347 EXPECT_TRUE(resp.InitParseWithoutQuery(sizeof(response_data))); |
362 | 348 |
363 // Check header access. | 349 // Check header access. |
364 EXPECT_EQ(0x8180, resp.flags()); | 350 EXPECT_EQ(0x8180, resp.flags()); |
365 EXPECT_EQ(0x0, resp.rcode()); | 351 EXPECT_EQ(0x0, resp.rcode()); |
366 EXPECT_EQ(0x01u, resp.answer_count()); | 352 EXPECT_EQ(0x01u, resp.answer_count()); |
367 | 353 |
368 DnsResourceRecord record; | 354 DnsResourceRecord record; |
369 DnsRecordParser parser = resp.Parser(); | 355 DnsRecordParser parser = resp.Parser(); |
370 | 356 |
371 EXPECT_FALSE(parser.AtEnd()); | 357 EXPECT_FALSE(parser.AtEnd()); |
372 EXPECT_TRUE(parser.ReadRecord(&record)); | 358 EXPECT_TRUE(parser.ReadRecord(&record)); |
373 EXPECT_EQ("codereview.chromium.org", record.name); | 359 EXPECT_EQ("codereview.chromium.org", record.name); |
374 EXPECT_EQ(0x35u, record.ttl); | 360 EXPECT_EQ(0x35u, record.ttl); |
375 EXPECT_EQ(dns_protocol::kTypeA, record.type); | 361 EXPECT_EQ(dns_protocol::kTypeA, record.type); |
376 | 362 |
377 EXPECT_TRUE(parser.AtEnd()); | 363 EXPECT_TRUE(parser.AtEnd()); |
378 EXPECT_FALSE(parser.ReadRecord(&record)); | 364 EXPECT_FALSE(parser.ReadRecord(&record)); |
379 } | 365 } |
380 | 366 |
381 TEST(DnsResponseTest, InitParseWithoutQueryPacketTooShort) { | 367 TEST(DnsResponseTest, InitParseWithoutQueryPacketTooShort) { |
382 const uint8 response_data[] = { | 368 const uint8 response_data[] = { |
383 // Header | 369 // Header |
384 0xca, 0xfe, // ID | 370 0xca, 0xfe, // ID |
385 0x81, 0x80, // Standard query response, RA, no error | 371 0x81, 0x80, // Standard query response, RA, no error |
386 0x00, 0x00, // No question | 372 0x00, 0x00, // No question |
387 }; | 373 }; |
388 | 374 |
389 DnsResponse resp; | 375 DnsResponse resp; |
390 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); | 376 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); |
391 | 377 |
392 EXPECT_FALSE(resp.InitParseWithoutQuery(sizeof(response_data))); | 378 EXPECT_FALSE(resp.InitParseWithoutQuery(sizeof(response_data))); |
393 } | 379 } |
394 | 380 |
395 void VerifyAddressList(const std::vector<const char*>& ip_addresses, | 381 void VerifyAddressList(const std::vector<const char*>& ip_addresses, |
396 const AddressList& addrlist) { | 382 const AddressList& addrlist) { |
397 ASSERT_EQ(ip_addresses.size(), addrlist.size()); | 383 ASSERT_EQ(ip_addresses.size(), addrlist.size()); |
398 | 384 |
399 for (size_t i = 0; i < addrlist.size(); ++i) { | 385 for (size_t i = 0; i < addrlist.size(); ++i) { |
400 EXPECT_EQ(ip_addresses[i], addrlist[i].ToStringWithoutPort()); | 386 EXPECT_EQ(ip_addresses[i], addrlist[i].ToStringWithoutPort()); |
401 } | 387 } |
402 } | 388 } |
403 | 389 |
404 TEST(DnsResponseTest, ParseToAddressList) { | 390 TEST(DnsResponseTest, ParseToAddressList) { |
405 const struct TestCase { | 391 const struct TestCase { |
406 size_t query_size; | 392 size_t query_size; |
407 const uint8* response_data; | 393 const uint8* response_data; |
408 size_t response_size; | 394 size_t response_size; |
409 const char* const* expected_addresses; | 395 const char* const* expected_addresses; |
410 size_t num_expected_addresses; | 396 size_t num_expected_addresses; |
411 const char* expected_cname; | 397 const char* expected_cname; |
412 int expected_ttl_sec; | 398 int expected_ttl_sec; |
413 } cases[] = { | 399 } cases[] = { |
414 { | 400 { |
415 kT0QuerySize, | 401 kT0QuerySize, kT0ResponseDatagram, arraysize(kT0ResponseDatagram), |
416 kT0ResponseDatagram, arraysize(kT0ResponseDatagram), | 402 kT0IpAddresses, arraysize(kT0IpAddresses), kT0CanonName, kT0TTL, |
417 kT0IpAddresses, arraysize(kT0IpAddresses), | 403 }, |
418 kT0CanonName, | 404 { |
419 kT0TTL, | 405 kT1QuerySize, kT1ResponseDatagram, arraysize(kT1ResponseDatagram), |
420 }, | 406 kT1IpAddresses, arraysize(kT1IpAddresses), kT1CanonName, kT1TTL, |
421 { | 407 }, |
422 kT1QuerySize, | 408 { |
423 kT1ResponseDatagram, arraysize(kT1ResponseDatagram), | 409 kT2QuerySize, kT2ResponseDatagram, arraysize(kT2ResponseDatagram), |
424 kT1IpAddresses, arraysize(kT1IpAddresses), | 410 kT2IpAddresses, arraysize(kT2IpAddresses), kT2CanonName, kT2TTL, |
425 kT1CanonName, | 411 }, |
426 kT1TTL, | 412 { |
427 }, | 413 kT3QuerySize, kT3ResponseDatagram, arraysize(kT3ResponseDatagram), |
428 { | 414 kT3IpAddresses, arraysize(kT3IpAddresses), kT3CanonName, kT3TTL, |
429 kT2QuerySize, | 415 }, |
430 kT2ResponseDatagram, arraysize(kT2ResponseDatagram), | 416 }; |
431 kT2IpAddresses, arraysize(kT2IpAddresses), | |
432 kT2CanonName, | |
433 kT2TTL, | |
434 }, | |
435 { | |
436 kT3QuerySize, | |
437 kT3ResponseDatagram, arraysize(kT3ResponseDatagram), | |
438 kT3IpAddresses, arraysize(kT3IpAddresses), | |
439 kT3CanonName, | |
440 kT3TTL, | |
441 }, | |
442 }; | |
443 | 417 |
444 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { | 418 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
445 const TestCase& t = cases[i]; | 419 const TestCase& t = cases[i]; |
446 DnsResponse response(t.response_data, t.response_size, t.query_size); | 420 DnsResponse response(t.response_data, t.response_size, t.query_size); |
447 AddressList addr_list; | 421 AddressList addr_list; |
448 base::TimeDelta ttl; | 422 base::TimeDelta ttl; |
449 EXPECT_EQ(DnsResponse::DNS_PARSE_OK, | 423 EXPECT_EQ(DnsResponse::DNS_PARSE_OK, |
450 response.ParseToAddressList(&addr_list, &ttl)); | 424 response.ParseToAddressList(&addr_list, &ttl)); |
451 std::vector<const char*> expected_addresses( | 425 std::vector<const char*> expected_addresses( |
452 t.expected_addresses, | 426 t.expected_addresses, t.expected_addresses + t.num_expected_addresses); |
453 t.expected_addresses + t.num_expected_addresses); | |
454 VerifyAddressList(expected_addresses, addr_list); | 427 VerifyAddressList(expected_addresses, addr_list); |
455 EXPECT_EQ(t.expected_cname, addr_list.canonical_name()); | 428 EXPECT_EQ(t.expected_cname, addr_list.canonical_name()); |
456 EXPECT_EQ(base::TimeDelta::FromSeconds(t.expected_ttl_sec), ttl); | 429 EXPECT_EQ(base::TimeDelta::FromSeconds(t.expected_ttl_sec), ttl); |
457 } | 430 } |
458 } | 431 } |
459 | 432 |
460 const uint8 kResponseTruncatedRecord[] = { | 433 const uint8 kResponseTruncatedRecord[] = { |
461 // Header: 1 question, 1 answer RR | 434 // Header: 1 question, 1 answer RR |
462 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, | 435 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, |
463 // Question: name = 'a', type = A (0x1) | 436 // Question: name = 'a', type = A (0x1) |
464 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, | 437 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
465 // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10 | 438 // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
466 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 439 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
467 0x00, 0x04, 0x0A, 0x0A, 0x0A, // Truncated RDATA. | 440 0x04, 0x0A, 0x0A, 0x0A, // Truncated RDATA. |
468 }; | 441 }; |
469 | 442 |
470 const uint8 kResponseTruncatedCNAME[] = { | 443 const uint8 kResponseTruncatedCNAME[] = { |
471 // Header: 1 question, 1 answer RR | 444 // Header: 1 question, 1 answer RR |
472 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, | 445 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, |
473 // Question: name = 'a', type = A (0x1) | 446 // Question: name = 'a', type = A (0x1) |
474 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, | 447 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
475 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'foo' (truncated) | 448 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'foo' (truncated) |
476 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 449 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
477 0x00, 0x03, 0x03, 'f', 'o', // Truncated name. | 450 0x03, 0x03, 'f', 'o', // Truncated name. |
478 }; | 451 }; |
479 | 452 |
480 const uint8 kResponseNameMismatch[] = { | 453 const uint8 kResponseNameMismatch[] = { |
481 // Header: 1 question, 1 answer RR | 454 // Header: 1 question, 1 answer RR |
482 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, | 455 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, |
483 // Question: name = 'a', type = A (0x1) | 456 // Question: name = 'a', type = A (0x1) |
484 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, | 457 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
485 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 | 458 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
486 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 459 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
487 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, | 460 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
488 }; | 461 }; |
489 | 462 |
490 const uint8 kResponseNameMismatchInChain[] = { | 463 const uint8 kResponseNameMismatchInChain[] = { |
491 // Header: 1 question, 3 answer RR | 464 // Header: 1 question, 3 answer RR |
492 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, | 465 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, |
493 // Question: name = 'a', type = A (0x1) | 466 // Question: name = 'a', type = A (0x1) |
494 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, | 467 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
495 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b' | 468 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b' |
496 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 469 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
497 0x00, 0x03, 0x01, 'b', 0x00, | 470 0x03, 0x01, 'b', 0x00, |
498 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 | 471 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
499 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 472 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
500 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, | 473 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
501 // Answer: name = 'c', type = A, TTL = 0xFF, RDATA = 10.10.10.11 | 474 // Answer: name = 'c', type = A, TTL = 0xFF, RDATA = 10.10.10.11 |
502 0x01, 'c', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 475 0x01, 'c', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
503 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0B, | 476 0x04, 0x0A, 0x0A, 0x0A, 0x0B, |
504 }; | 477 }; |
505 | 478 |
506 const uint8 kResponseSizeMismatch[] = { | 479 const uint8 kResponseSizeMismatch[] = { |
507 // Header: 1 answer RR | 480 // Header: 1 answer RR |
508 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, | 481 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, |
509 // Question: name = 'a', type = AAAA (0x1c) | 482 // Question: name = 'a', type = AAAA (0x1c) |
510 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, | 483 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, |
511 // Answer: name = 'a', type = AAAA, TTL = 0xFF, RDATA = 10.10.10.10 | 484 // Answer: name = 'a', type = AAAA, TTL = 0xFF, RDATA = 10.10.10.10 |
512 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 485 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
513 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, | 486 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
514 }; | 487 }; |
515 | 488 |
516 const uint8 kResponseCNAMEAfterAddress[] = { | 489 const uint8 kResponseCNAMEAfterAddress[] = { |
517 // Header: 2 answer RR | 490 // Header: 2 answer RR |
518 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, | 491 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, |
519 // Question: name = 'a', type = A (0x1) | 492 // Question: name = 'a', type = A (0x1) |
520 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, | 493 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
521 // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10. | 494 // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10. |
522 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 495 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
523 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, | 496 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
524 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b' | 497 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b' |
525 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 498 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
526 0x00, 0x03, 0x01, 'b', 0x00, | 499 0x03, 0x01, 'b', 0x00, |
527 }; | 500 }; |
528 | 501 |
529 const uint8 kResponseNoAddresses[] = { | 502 const uint8 kResponseNoAddresses[] = { |
530 // Header: 1 question, 1 answer RR, 1 authority RR | 503 // Header: 1 question, 1 answer RR, 1 authority RR |
531 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, | 504 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, |
532 // Question: name = 'a', type = A (0x1) | 505 // Question: name = 'a', type = A (0x1) |
533 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, | 506 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, |
534 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b' | 507 // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b' |
535 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 508 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
536 0x00, 0x03, 0x01, 'b', 0x00, | 509 0x03, 0x01, 'b', 0x00, |
537 // Authority section | 510 // Authority section |
538 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 | 511 // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10 |
539 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, | 512 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, |
540 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, | 513 0x04, 0x0A, 0x0A, 0x0A, 0x0A, |
541 }; | 514 }; |
542 | 515 |
543 TEST(DnsResponseTest, ParseToAddressListFail) { | 516 TEST(DnsResponseTest, ParseToAddressListFail) { |
544 const struct TestCase { | 517 const struct TestCase { |
545 const uint8* data; | 518 const uint8* data; |
546 size_t size; | 519 size_t size; |
547 DnsResponse::Result expected_result; | 520 DnsResponse::Result expected_result; |
548 } cases[] = { | 521 } cases[] = { |
549 { kResponseTruncatedRecord, arraysize(kResponseTruncatedRecord), | 522 {kResponseTruncatedRecord, arraysize(kResponseTruncatedRecord), |
550 DnsResponse::DNS_MALFORMED_RESPONSE }, | 523 DnsResponse::DNS_MALFORMED_RESPONSE}, |
551 { kResponseTruncatedCNAME, arraysize(kResponseTruncatedCNAME), | 524 {kResponseTruncatedCNAME, arraysize(kResponseTruncatedCNAME), |
552 DnsResponse::DNS_MALFORMED_CNAME }, | 525 DnsResponse::DNS_MALFORMED_CNAME}, |
553 { kResponseNameMismatch, arraysize(kResponseNameMismatch), | 526 {kResponseNameMismatch, arraysize(kResponseNameMismatch), |
554 DnsResponse::DNS_NAME_MISMATCH }, | 527 DnsResponse::DNS_NAME_MISMATCH}, |
555 { kResponseNameMismatchInChain, arraysize(kResponseNameMismatchInChain), | 528 {kResponseNameMismatchInChain, arraysize(kResponseNameMismatchInChain), |
556 DnsResponse::DNS_NAME_MISMATCH }, | 529 DnsResponse::DNS_NAME_MISMATCH}, |
557 { kResponseSizeMismatch, arraysize(kResponseSizeMismatch), | 530 {kResponseSizeMismatch, arraysize(kResponseSizeMismatch), |
558 DnsResponse::DNS_SIZE_MISMATCH }, | 531 DnsResponse::DNS_SIZE_MISMATCH}, |
559 { kResponseCNAMEAfterAddress, arraysize(kResponseCNAMEAfterAddress), | 532 {kResponseCNAMEAfterAddress, arraysize(kResponseCNAMEAfterAddress), |
560 DnsResponse::DNS_CNAME_AFTER_ADDRESS }, | 533 DnsResponse::DNS_CNAME_AFTER_ADDRESS}, |
561 // Not actually a failure, just an empty result. | 534 // Not actually a failure, just an empty result. |
562 { kResponseNoAddresses, arraysize(kResponseNoAddresses), | 535 {kResponseNoAddresses, arraysize(kResponseNoAddresses), |
563 DnsResponse::DNS_PARSE_OK }, | 536 DnsResponse::DNS_PARSE_OK}, |
564 }; | 537 }; |
565 | 538 |
566 const size_t kQuerySize = 12 + 7; | 539 const size_t kQuerySize = 12 + 7; |
567 | 540 |
568 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { | 541 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
569 const TestCase& t = cases[i]; | 542 const TestCase& t = cases[i]; |
570 | 543 |
571 DnsResponse response(t.data, t.size, kQuerySize); | 544 DnsResponse response(t.data, t.size, kQuerySize); |
572 AddressList addr_list; | 545 AddressList addr_list; |
573 base::TimeDelta ttl; | 546 base::TimeDelta ttl; |
574 EXPECT_EQ(t.expected_result, | 547 EXPECT_EQ(t.expected_result, response.ParseToAddressList(&addr_list, &ttl)); |
575 response.ParseToAddressList(&addr_list, &ttl)); | |
576 } | 548 } |
577 } | 549 } |
578 | 550 |
579 } // namespace | 551 } // namespace |
580 | 552 |
581 } // namespace net | 553 } // namespace net |
OLD | NEW |