Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: net/dns/dns_response_unittest.cc

Issue 8835011: Revert 113282 - Isolates generic DnsClient from AsyncHostResolver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/dns/dns_response.cc ('k') | net/dns/dns_session.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/bind.h"
8 #include "base/rand_util.h"
9 #include "net/base/dns_util.h"
10 #include "net/base/net_errors.h"
7 #include "net/base/io_buffer.h" 11 #include "net/base/io_buffer.h"
8 #include "net/dns/dns_protocol.h"
9 #include "net/dns/dns_query.h" 12 #include "net/dns/dns_query.h"
10 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
11 14
12 namespace net { 15 namespace net {
13 16
14 namespace { 17 // DNS response consists of a header followed by a question followed by
18 // answer. Header format, question format and response format are
19 // described below. For the meaning of specific fields, please see RFC
20 // 1035.
15 21
16 TEST(DnsRecordParserTest, Constructor) { 22 // Header format.
17 const char data[] = { 0 }; 23 // 1 1 1 1 1 1
24 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
25 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
26 // | ID |
27 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
28 // |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
29 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
30 // | QDCOUNT |
31 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
32 // | ANCOUNT |
33 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
34 // | NSCOUNT |
35 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
36 // | ARCOUNT |
37 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
18 38
19 EXPECT_FALSE(DnsRecordParser().IsValid()); 39 // Question format.
20 EXPECT_TRUE(DnsRecordParser(data, 1, 0).IsValid()); 40 // 1 1 1 1 1 1
21 EXPECT_TRUE(DnsRecordParser(data, 1, 1).IsValid()); 41 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
42 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
43 // | |
44 // / QNAME /
45 // / /
46 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
47 // | QTYPE |
48 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
49 // | QCLASS |
50 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
22 51
23 EXPECT_FALSE(DnsRecordParser(data, 1, 0).AtEnd()); 52 // Answser format.
24 EXPECT_TRUE(DnsRecordParser(data, 1, 1).AtEnd()); 53 // 1 1 1 1 1 1
25 } 54 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
55 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56 // | |
57 // / /
58 // / NAME /
59 // | |
60 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61 // | TYPE |
62 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
63 // | CLASS |
64 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
65 // | TTL |
66 // | |
67 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
68 // | RDLENGTH |
69 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
70 // / RDATA /
71 // / /
72 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
26 73
27 TEST(DnsRecordParserTest, ParseName) { 74 // TODO(agayev): add more thorough tests.
28 const uint8 data[] = { 75 TEST(DnsResponseTest, ResponseWithCnameA) {
29 // all labels "foo.example.com" 76 const std::string kQname("\012codereview\010chromium\003org", 25);
30 0x03, 'f', 'o', 'o', 77 DnsQuery q1(kQname, kDNS_A, base::Bind(&base::RandInt));
31 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 78
32 0x03, 'c', 'o', 'm', 79 uint8 id_hi = q1.id() >> 8, id_lo = q1.id() & 0xff;
33 // byte 0x10 80
34 0x00, 81 uint8 ip[] = { // codereview.chromium.org resolves to
35 // byte 0x11 82 0x4a, 0x7d, 0x5f, 0x79 // 74.125.95.121
36 // part label, part pointer, "bar.example.com"
37 0x03, 'b', 'a', 'r',
38 0xc0, 0x04,
39 // byte 0x17
40 // all pointer to "bar.example.com", 2 jumps
41 0xc0, 0x11,
42 // byte 0x1a
43 }; 83 };
44 84
45 std::string out; 85 IPAddressList expected_ips;
46 DnsRecordParser parser(data, sizeof(data), 0); 86 expected_ips.push_back(IPAddressNumber(ip, ip + arraysize(ip)));
47 ASSERT_TRUE(parser.IsValid());
48 87
49 EXPECT_EQ(0x11, parser.ParseName(data + 0x00, &out)); 88 uint8 response_data[] = {
50 EXPECT_EQ("foo.example.com", out);
51 // Check that the last "." is never stored.
52 out.clear();
53 EXPECT_EQ(0x1, parser.ParseName(data + 0x10, &out));
54 EXPECT_EQ("", out);
55 out.clear();
56 EXPECT_EQ(0x6, parser.ParseName(data + 0x11, &out));
57 EXPECT_EQ("bar.example.com", out);
58 out.clear();
59 EXPECT_EQ(0x2, parser.ParseName(data + 0x17, &out));
60 EXPECT_EQ("bar.example.com", out);
61
62 // Parse name without storing it.
63 EXPECT_EQ(0x11, parser.ParseName(data + 0x00, NULL));
64 EXPECT_EQ(0x1, parser.ParseName(data + 0x10, NULL));
65 EXPECT_EQ(0x6, parser.ParseName(data + 0x11, NULL));
66 EXPECT_EQ(0x2, parser.ParseName(data + 0x17, NULL));
67
68 // Check that it works even if initial position is different.
69 parser = DnsRecordParser(data, sizeof(data), 0x12);
70 EXPECT_EQ(0x6, parser.ParseName(data + 0x11, NULL));
71 }
72
73 TEST(DnsRecordParserTest, ParseNameFail) {
74 const uint8 data[] = {
75 // label length beyond packet
76 0x30, 'x', 'x',
77 0x00,
78 // pointer offset beyond packet
79 0xc0, 0x20,
80 // pointer loop
81 0xc0, 0x08,
82 0xc0, 0x06,
83 // incorrect label type (currently supports only direct and pointer)
84 0x80, 0x00,
85 // truncated name (missing root label)
86 0x02, 'x', 'x',
87 };
88
89 DnsRecordParser parser(data, sizeof(data), 0);
90 ASSERT_TRUE(parser.IsValid());
91
92 std::string out;
93 EXPECT_EQ(0, parser.ParseName(data + 0x00, &out));
94 EXPECT_EQ(0, parser.ParseName(data + 0x04, &out));
95 EXPECT_EQ(0, parser.ParseName(data + 0x08, &out));
96 EXPECT_EQ(0, parser.ParseName(data + 0x0a, &out));
97 EXPECT_EQ(0, parser.ParseName(data + 0x0c, &out));
98 EXPECT_EQ(0, parser.ParseName(data + 0x0e, &out));
99 }
100
101 TEST(DnsRecordParserTest, ParseRecord) {
102 const uint8 data[] = {
103 // Type CNAME record.
104 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
105 0x03, 'c', 'o', 'm',
106 0x00,
107 0x00, 0x05, // TYPE is CNAME.
108 0x00, 0x01, // CLASS is IN.
109 0x00, 0x01, 0x24, 0x74, // TTL is 0x00012474.
110 0x00, 0x06, // RDLENGTH is 6 bytes.
111 0x03, 'f', 'o', 'o', // compressed name in record
112 0xc0, 0x00,
113 // Type A record.
114 0x03, 'b', 'a', 'r', // compressed owner name
115 0xc0, 0x00,
116 0x00, 0x01, // TYPE is A.
117 0x00, 0x01, // CLASS is IN.
118 0x00, 0x20, 0x13, 0x55, // TTL is 0x00201355.
119 0x00, 0x04, // RDLENGTH is 4 bytes.
120 0x7f, 0x02, 0x04, 0x01, // IP is 127.2.4.1
121 };
122
123 std::string out;
124 DnsRecordParser parser(data, sizeof(data), 0);
125
126 DnsResourceRecord record;
127 EXPECT_TRUE(parser.ParseRecord(&record));
128 EXPECT_EQ("example.com", record.name);
129 EXPECT_EQ(dns_protocol::kTypeCNAME, record.type);
130 EXPECT_EQ(dns_protocol::kClassIN, record.klass);
131 EXPECT_EQ(0x00012474u, record.ttl);
132 EXPECT_EQ(6u, record.rdata.length());
133 EXPECT_EQ(6, parser.ParseName(record.rdata.data(), &out));
134 EXPECT_EQ("foo.example.com", out);
135 EXPECT_FALSE(parser.AtEnd());
136
137 EXPECT_TRUE(parser.ParseRecord(&record));
138 EXPECT_EQ("bar.example.com", record.name);
139 EXPECT_EQ(dns_protocol::kTypeA, record.type);
140 EXPECT_EQ(dns_protocol::kClassIN, record.klass);
141 EXPECT_EQ(0x00201355u, record.ttl);
142 EXPECT_EQ(4u, record.rdata.length());
143 EXPECT_EQ(base::StringPiece("\x7f\x02\x04\x01"), record.rdata);
144 EXPECT_TRUE(parser.AtEnd());
145
146 // Test truncated record.
147 parser = DnsRecordParser(data, sizeof(data) - 2, 0);
148 EXPECT_TRUE(parser.ParseRecord(&record));
149 EXPECT_FALSE(parser.AtEnd());
150 EXPECT_FALSE(parser.ParseRecord(&record));
151 }
152
153 TEST(DnsResponseTest, InitParse) {
154 // This includes \0 at the end.
155 const char qname_data[] = "\x0A""codereview""\x08""chromium""\x03""org";
156 const base::StringPiece qname(qname_data, sizeof(qname_data));
157 // 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));
159
160 const uint8 response_data[] = {
161 // Header 89 // Header
162 0xca, 0xfe, // ID 90 id_hi, id_lo, // ID
163 0x81, 0x80, // Standard query response, RA, no error 91 0x81, 0x80, // Standard query response, no error
164 0x00, 0x01, // 1 question 92 0x00, 0x01, // 1 question
165 0x00, 0x02, // 2 RRs (answers) 93 0x00, 0x02, // 2 RRs (answers)
166 0x00, 0x00, // 0 authority RRs 94 0x00, 0x00, // 0 authority RRs
167 0x00, 0x00, // 0 additional RRs 95 0x00, 0x00, // 0 additional RRs
168 96
169 // Question 97 // Question
170 // This part is echoed back from the respective query. 98 0x0a, 0x63, 0x6f, 0x64, // This part is echoed back from the
171 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 99 0x65, 0x72, 0x65, 0x76, // respective query.
172 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', 100 0x69, 0x65, 0x77, 0x08,
173 0x03, 'o', 'r', 'g', 101 0x63, 0x68, 0x72, 0x6f,
102 0x6d, 0x69, 0x75, 0x6d,
103 0x03, 0x6f, 0x72, 0x67,
174 0x00, 104 0x00,
175 0x00, 0x01, // TYPE is A. 105 0x00, 0x01,
176 0x00, 0x01, // CLASS is IN. 106 0x00, 0x01,
177 107
178 // Answer 1 108 // Answer 1
179 0xc0, 0x0c, // NAME is a pointer to name in Question section. 109 0xc0, 0x0c, // NAME is a pointer to name in Question section.
180 0x00, 0x05, // TYPE is CNAME. 110 0x00, 0x05, // TYPE is CNAME.
181 0x00, 0x01, // CLASS is IN. 111 0x00, 0x01, // CLASS is IN.
182 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. 112 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
183 0x24, 0x74, 113 0x24, 0x74,
184 0x00, 0x12, // RDLENGTH is 18 bytes. 114 0x00, 0x12, // RDLENGTH is 18 bytse.
185 // ghs.l.google.com in DNS format. 115 0x03, 0x67, 0x68, 0x73, // ghs.l.google.com in DNS format.
186 0x03, 'g', 'h', 's', 116 0x01, 0x6c, 0x06, 0x67,
187 0x01, 'l', 117 0x6f, 0x6f, 0x67, 0x6c,
188 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 118 0x65, 0x03, 0x63, 0x6f,
189 0x03, 'c', 'o', 'm', 119 0x6d, 0x00,
190 0x00,
191 120
192 // Answer 2 121 // Answer 2
193 0xc0, 0x35, // NAME is a pointer to name in Answer 1. 122 0xc0, 0x35, // NAME is a pointer to name in Question section.
194 0x00, 0x01, // TYPE is A. 123 0x00, 0x01, // TYPE is A.
195 0x00, 0x01, // CLASS is IN. 124 0x00, 0x01, // CLASS is IN.
196 0x00, 0x00, // TTL (4 bytes) is 53 seconds. 125 0x00, 0x00, // TTL (4 bytes) is 53 seconds.
197 0x00, 0x35, 126 0x00, 0x35,
198 0x00, 0x04, // RDLENGTH is 4 bytes. 127 0x00, 0x04, // RDLENGTH is 4 bytes.
199 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 128 ip[0], ip[1], ip[2], ip[3], // RDATA is the IP.
200 0x5f, 0x79,
201 }; 129 };
202 130
203 DnsResponse resp; 131 // Create a response object and simulate reading into it.
204 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); 132 DnsResponse r1(&q1);
133 memcpy(r1.io_buffer()->data(), &response_data[0],
134 r1.io_buffer()->size());
205 135
206 // Reject too short. 136 // Verify resolved IPs.
207 EXPECT_FALSE(resp.InitParse(query->io_buffer()->size() - 1, *query)); 137 int response_size = arraysize(response_data);
208 138 IPAddressList actual_ips;
209 // Reject wrong id. 139 EXPECT_EQ(OK, r1.Parse(response_size, &actual_ips));
210 scoped_ptr<DnsQuery> other_query(query->CloneWithNewId(0xbeef)); 140 EXPECT_EQ(expected_ips, actual_ips);
211 EXPECT_FALSE(resp.InitParse(sizeof(response_data), *other_query));
212
213 // Reject wrong question.
214 scoped_ptr<DnsQuery> wrong_query(
215 new DnsQuery(0xcafe, qname, dns_protocol::kTypeCNAME));
216 EXPECT_FALSE(resp.InitParse(sizeof(response_data), *wrong_query));
217
218 // Accept matching question.
219 EXPECT_TRUE(resp.InitParse(sizeof(response_data), *query));
220
221 // Check header access.
222 EXPECT_EQ(0x81, resp.flags0());
223 EXPECT_EQ(0x80, resp.flags1());
224 EXPECT_EQ(0x0, resp.rcode());
225 EXPECT_EQ(2, resp.answer_count());
226
227 DnsResourceRecord record;
228 DnsRecordParser parser = resp.Parser();
229 EXPECT_TRUE(parser.ParseRecord(&record));
230 EXPECT_TRUE(parser.ParseRecord(&record));
231 EXPECT_FALSE(parser.ParseRecord(&record));
232 } 141 }
233 142
234 } // namespace
235
236 } // namespace net 143 } // namespace net
OLDNEW
« no previous file with comments | « net/dns/dns_response.cc ('k') | net/dns/dns_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698