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

Side by Side Diff: components/certificate_transparency/mock_log_dns_traffic.cc

Issue 2389993003: MockLogDnsTraffic now returns bool instead of CHECKing bad arguments (Closed)
Patch Set: Rebase Created 4 years, 2 months 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
« no previous file with comments | « components/certificate_transparency/mock_log_dns_traffic.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/certificate_transparency/mock_log_dns_traffic.h" 5 #include "components/certificate_transparency/mock_log_dns_traffic.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <numeric> 8 #include <numeric>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 27 matching lines...) Expand all
38 net::NetworkChangeNotifier::SetDnsConfig(config); 38 net::NetworkChangeNotifier::SetDnsConfig(config);
39 } 39 }
40 }; 40 };
41 41
42 // Always return min, to simplify testing. 42 // Always return min, to simplify testing.
43 // This should result in the DNS query ID always being 0. 43 // This should result in the DNS query ID always being 0.
44 int FakeRandInt(int min, int max) { 44 int FakeRandInt(int min, int max) {
45 return min; 45 return min;
46 } 46 }
47 47
48 std::vector<char> CreateDnsTxtRequest(base::StringPiece qname) { 48 bool CreateDnsTxtRequest(base::StringPiece qname, std::vector<char>* request) {
49 std::string encoded_qname; 49 std::string encoded_qname;
50 CHECK(net::DNSDomainFromDot(qname, &encoded_qname)); 50 if (!net::DNSDomainFromDot(qname, &encoded_qname)) {
51 // |qname| is an invalid domain name.
52 return false;
53 }
51 54
52 // DNS query section: 55 // DNS query section:
53 // N bytes - qname 56 // N bytes - qname
54 // 2 bytes - record type 57 // 2 bytes - record type
55 // 2 bytes - record class 58 // 2 bytes - record class
56 // Total = N + 4 bytes 59 // Total = N + 4 bytes
57 const size_t query_section_size = encoded_qname.size() + 4; 60 const size_t query_section_size = encoded_qname.size() + 4;
58 61
59 std::vector<char> request(sizeof(net::dns_protocol::Header) + 62 request->resize(sizeof(net::dns_protocol::Header) + query_section_size);
60 query_section_size); 63 base::BigEndianWriter writer(request->data(), request->size());
61 base::BigEndianWriter writer(request.data(), request.size());
62 64
63 // Header 65 // Header
64 net::dns_protocol::Header header = {}; 66 net::dns_protocol::Header header = {};
65 header.flags = base::HostToNet16(net::dns_protocol::kFlagRD); 67 header.flags = base::HostToNet16(net::dns_protocol::kFlagRD);
66 header.qdcount = base::HostToNet16(1); 68 header.qdcount = base::HostToNet16(1);
67 CHECK(writer.WriteBytes(&header, sizeof(header)));
68 // Query section
69 CHECK(writer.WriteBytes(encoded_qname.data(), encoded_qname.size()));
70 CHECK(writer.WriteU16(net::dns_protocol::kTypeTXT));
71 CHECK(writer.WriteU16(net::dns_protocol::kClassIN));
72 CHECK_EQ(0, writer.remaining());
73 69
74 return request; 70 if (!writer.WriteBytes(&header, sizeof(header)) ||
71 !writer.WriteBytes(encoded_qname.data(), encoded_qname.size()) ||
72 !writer.WriteU16(net::dns_protocol::kTypeTXT) ||
73 !writer.WriteU16(net::dns_protocol::kClassIN)) {
74 return false;
75 }
76
77 if (writer.remaining() != 0) {
78 // Less than the expected amount of data was written.
79 return false;
80 }
81
82 return true;
75 } 83 }
76 84
77 std::vector<char> CreateDnsTxtResponse(const std::vector<char>& request, 85 bool CreateDnsTxtResponse(const std::vector<char>& request,
78 base::StringPiece answer) { 86 base::StringPiece answer,
87 std::vector<char>* response) {
79 // DNS answers section: 88 // DNS answers section:
80 // 2 bytes - qname pointer 89 // 2 bytes - qname pointer
81 // 2 bytes - record type 90 // 2 bytes - record type
82 // 2 bytes - record class 91 // 2 bytes - record class
83 // 4 bytes - time-to-live 92 // 4 bytes - time-to-live
84 // 2 bytes - size of answer (N) 93 // 2 bytes - size of answer (N)
85 // N bytes - answer 94 // N bytes - answer
86 // Total = 12 + N bytes 95 // Total = 12 + N bytes
87 const size_t answers_section_size = 12 + answer.size(); 96 const size_t answers_section_size = 12 + answer.size();
88 constexpr uint32_t ttl = 86400; // seconds 97 constexpr uint32_t ttl = 86400; // seconds
89 98
90 std::vector<char> response(request.size() + answers_section_size); 99 response->resize(request.size() + answers_section_size);
91 std::copy(request.begin(), request.end(), response.begin()); 100 std::copy(request.begin(), request.end(), response->begin());
101
92 // Modify the header 102 // Modify the header
93 net::dns_protocol::Header* header = 103 net::dns_protocol::Header* header =
94 reinterpret_cast<net::dns_protocol::Header*>(response.data()); 104 reinterpret_cast<net::dns_protocol::Header*>(response->data());
95 header->ancount = base::HostToNet16(1); 105 header->ancount = base::HostToNet16(1);
96 header->flags |= base::HostToNet16(net::dns_protocol::kFlagResponse); 106 header->flags |= base::HostToNet16(net::dns_protocol::kFlagResponse);
97 107
108 // The qname is at the start of the query section (just after the header).
109 const uint8_t qname_ptr = sizeof(*header);
110
98 // Write the answer section 111 // Write the answer section
99 base::BigEndianWriter writer(response.data() + request.size(), 112 base::BigEndianWriter writer(response->data() + request.size(),
100 response.size() - request.size()); 113 response->size() - request.size());
101 CHECK(writer.WriteU8(0xc0)); // qname is a pointer 114 if (!writer.WriteU8(net::dns_protocol::kLabelPointer) ||
102 CHECK(writer.WriteU8( 115 !writer.WriteU8(qname_ptr) ||
103 sizeof(*header))); // address of qname (start of query section) 116 !writer.WriteU16(net::dns_protocol::kTypeTXT) ||
104 CHECK(writer.WriteU16(net::dns_protocol::kTypeTXT)); 117 !writer.WriteU16(net::dns_protocol::kClassIN) || !writer.WriteU32(ttl) ||
105 CHECK(writer.WriteU16(net::dns_protocol::kClassIN)); 118 !writer.WriteU16(answer.size()) ||
106 CHECK(writer.WriteU32(ttl)); 119 !writer.WriteBytes(answer.data(), answer.size())) {
107 CHECK(writer.WriteU16(answer.size())); 120 return false;
108 CHECK(writer.WriteBytes(answer.data(), answer.size())); 121 }
109 CHECK_EQ(0, writer.remaining());
110 122
111 return response; 123 if (writer.remaining() != 0) {
124 // Less than the expected amount of data was written.
125 return false;
126 }
127
128 return true;
112 } 129 }
113 130
114 std::vector<char> CreateDnsErrorResponse(const std::vector<char>& request, 131 bool CreateDnsErrorResponse(const std::vector<char>& request,
115 uint8_t rcode) { 132 uint8_t rcode,
116 std::vector<char> response(request); 133 std::vector<char>* response) {
134 *response = request;
117 // Modify the header 135 // Modify the header
118 net::dns_protocol::Header* header = 136 net::dns_protocol::Header* header =
119 reinterpret_cast<net::dns_protocol::Header*>(response.data()); 137 reinterpret_cast<net::dns_protocol::Header*>(response->data());
120 header->ancount = base::HostToNet16(1); 138 header->ancount = base::HostToNet16(1);
121 header->flags |= base::HostToNet16(net::dns_protocol::kFlagResponse | rcode); 139 header->flags |= base::HostToNet16(net::dns_protocol::kFlagResponse | rcode);
122 140 return true;
123 return response;
124 } 141 }
125 142
126 } // namespace 143 } // namespace
127 144
128 // A container for all of the data needed for simulating a socket. 145 // A container for all of the data needed for simulating a socket.
129 // This is useful because Mock{Read,Write}, SequencedSocketData and 146 // This is useful because Mock{Read,Write}, SequencedSocketData and
130 // MockClientSocketFactory all do not take ownership of or copy their arguments, 147 // MockClientSocketFactory all do not take ownership of or copy their arguments,
131 // so it is necessary to manage the lifetime of those arguments. Wrapping all 148 // so it is necessary to manage the lifetime of those arguments. Wrapping all
132 // of that up in a single class simplifies this. 149 // of that up in a single class simplifies this.
133 class MockLogDnsTraffic::MockSocketData { 150 class MockLogDnsTraffic::MockSocketData {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 private: 197 private:
181 // This class only supports one write and one read, so just need to store one 198 // This class only supports one write and one read, so just need to store one
182 // payload each. 199 // payload each.
183 const std::vector<char> expected_write_payload_; 200 const std::vector<char> expected_write_payload_;
184 const std::vector<char> expected_read_payload_; 201 const std::vector<char> expected_read_payload_;
185 202
186 // Encapsulates the data that is expected to be written to a socket. 203 // Encapsulates the data that is expected to be written to a socket.
187 net::MockWrite expected_write_; 204 net::MockWrite expected_write_;
188 205
189 // Encapsulates the data/error that should be returned when reading from a 206 // Encapsulates the data/error that should be returned when reading from a
190 // socket. The second "expected" read is a sentinel that causes socket reads 207 // socket. The second "expected" read is a sentinel (see |kNoMoreData|).
191 // beyond the first to hang until they timeout. This results in better
192 // test failure messages (rather than a CHECK-fail due to a socket read
193 // overrunning the MockRead array) and behaviour more like a real socket when
194 // an unexpected second socket read occurs.
195 net::MockRead expected_reads_[2]; 208 net::MockRead expected_reads_[2];
196 209
197 // Holds pointers to |expected_write_| and |expected_reads_|. This is what is 210 // Holds pointers to |expected_write_| and |expected_reads_|. This is what is
198 // added to net::MockClientSocketFactory to prepare a mock socket. 211 // added to net::MockClientSocketFactory to prepare a mock socket.
199 net::SequencedSocketData socket_data_; 212 net::SequencedSocketData socket_data_;
200 213
201 DISALLOW_COPY_AND_ASSIGN(MockSocketData); 214 DISALLOW_COPY_AND_ASSIGN(MockSocketData);
202 }; 215 };
203 216
204 MockLogDnsTraffic::MockLogDnsTraffic() : socket_read_mode_(net::ASYNC) {} 217 MockLogDnsTraffic::MockLogDnsTraffic() : socket_read_mode_(net::ASYNC) {}
205 218
206 MockLogDnsTraffic::~MockLogDnsTraffic() {} 219 MockLogDnsTraffic::~MockLogDnsTraffic() {}
207 220
208 void MockLogDnsTraffic::ExpectRequestAndErrorResponse(base::StringPiece qname, 221 bool MockLogDnsTraffic::ExpectRequestAndErrorResponse(base::StringPiece qname,
209 uint8_t rcode) { 222 uint8_t rcode) {
210 std::vector<char> request = CreateDnsTxtRequest(qname); 223 std::vector<char> request;
211 EmplaceMockSocketData(CreateDnsTxtRequest(qname), 224 if (!CreateDnsTxtRequest(qname, &request)) {
212 CreateDnsErrorResponse(request, rcode)); 225 return false;
226 }
227
228 std::vector<char> response;
229 if (!CreateDnsErrorResponse(request, rcode, &response)) {
230 return false;
231 }
232
233 EmplaceMockSocketData(request, response);
234 return true;
213 } 235 }
214 236
215 void MockLogDnsTraffic::ExpectRequestAndSocketError(base::StringPiece qname, 237 bool MockLogDnsTraffic::ExpectRequestAndSocketError(base::StringPiece qname,
216 net::Error error) { 238 net::Error error) {
217 EmplaceMockSocketData(CreateDnsTxtRequest(qname), error); 239 std::vector<char> request;
240 if (!CreateDnsTxtRequest(qname, &request)) {
241 return false;
242 }
243
244 EmplaceMockSocketData(request, error);
245 return true;
218 } 246 }
219 247
220 void MockLogDnsTraffic::ExpectRequestAndTimeout(base::StringPiece qname) { 248 bool MockLogDnsTraffic::ExpectRequestAndTimeout(base::StringPiece qname) {
221 EmplaceMockSocketData(CreateDnsTxtRequest(qname)); 249 std::vector<char> request;
250 if (!CreateDnsTxtRequest(qname, &request)) {
251 return false;
252 }
253
254 EmplaceMockSocketData(request);
222 255
223 // Speed up timeout tests. 256 // Speed up timeout tests.
224 SetDnsTimeout(TestTimeouts::tiny_timeout()); 257 SetDnsTimeout(TestTimeouts::tiny_timeout());
258
259 return true;
225 } 260 }
226 261
227 void MockLogDnsTraffic::ExpectRequestAndResponse( 262 bool MockLogDnsTraffic::ExpectRequestAndResponse(
228 base::StringPiece qname, 263 base::StringPiece qname,
229 const std::vector<base::StringPiece>& txt_strings) { 264 const std::vector<base::StringPiece>& txt_strings) {
230 std::string answer; 265 std::string answer;
231 for (base::StringPiece str : txt_strings) { 266 for (base::StringPiece str : txt_strings) {
232 // The size of the string must precede it. The size must fit into 1 byte. 267 // The size of the string must precede it. The size must fit into 1 byte.
233 answer.insert(answer.end(), base::checked_cast<uint8_t>(str.size())); 268 answer.insert(answer.end(), base::checked_cast<uint8_t>(str.size()));
234 str.AppendToString(&answer); 269 str.AppendToString(&answer);
235 } 270 }
236 271
237 std::vector<char> request = CreateDnsTxtRequest(qname); 272 std::vector<char> request;
238 EmplaceMockSocketData(request, CreateDnsTxtResponse(request, answer)); 273 if (!CreateDnsTxtRequest(qname, &request)) {
274 return false;
275 }
276
277 std::vector<char> response;
278 if (!CreateDnsTxtResponse(request, answer, &response)) {
279 return false;
280 }
281
282 EmplaceMockSocketData(request, response);
283 return true;
239 } 284 }
240 285
241 void MockLogDnsTraffic::ExpectLeafIndexRequestAndResponse( 286 bool MockLogDnsTraffic::ExpectLeafIndexRequestAndResponse(
242 base::StringPiece qname, 287 base::StringPiece qname,
243 uint64_t leaf_index) { 288 uint64_t leaf_index) {
244 ExpectRequestAndResponse(qname, { base::Uint64ToString(leaf_index) }); 289 return ExpectRequestAndResponse(qname, {base::Uint64ToString(leaf_index)});
245 } 290 }
246 291
247 void MockLogDnsTraffic::ExpectAuditProofRequestAndResponse( 292 bool MockLogDnsTraffic::ExpectAuditProofRequestAndResponse(
248 base::StringPiece qname, 293 base::StringPiece qname,
249 std::vector<std::string>::const_iterator audit_path_start, 294 std::vector<std::string>::const_iterator audit_path_start,
250 std::vector<std::string>::const_iterator audit_path_end) { 295 std::vector<std::string>::const_iterator audit_path_end) {
251 // Join nodes in the audit path into a single string. 296 // Join nodes in the audit path into a single string.
252 std::string proof = 297 std::string proof =
253 std::accumulate(audit_path_start, audit_path_end, std::string()); 298 std::accumulate(audit_path_start, audit_path_end, std::string());
254 299
255 ExpectRequestAndResponse(qname, { proof }); 300 return ExpectRequestAndResponse(qname, {proof});
256 } 301 }
257 302
258 void MockLogDnsTraffic::InitializeDnsConfig() { 303 void MockLogDnsTraffic::InitializeDnsConfig() {
259 net::DnsConfig dns_config; 304 net::DnsConfig dns_config;
260 // Use an invalid nameserver address. This prevents the tests accidentally 305 // Use an invalid nameserver address. This prevents the tests accidentally
261 // sending real DNS queries. The mock sockets don't care that the address 306 // sending real DNS queries. The mock sockets don't care that the address
262 // is invalid. 307 // is invalid.
263 dns_config.nameservers.push_back(net::IPEndPoint()); 308 dns_config.nameservers.push_back(net::IPEndPoint());
264 // Don't attempt retransmissions - just fail. 309 // Don't attempt retransmissions - just fail.
265 dns_config.attempts = 1; 310 dns_config.attempts = 1;
(...skipping 25 matching lines...) Expand all
291 } 336 }
292 337
293 void MockLogDnsTraffic::SetDnsTimeout(const base::TimeDelta& timeout) { 338 void MockLogDnsTraffic::SetDnsTimeout(const base::TimeDelta& timeout) {
294 net::DnsConfig dns_config; 339 net::DnsConfig dns_config;
295 DnsChangeNotifier::GetDnsConfig(&dns_config); 340 DnsChangeNotifier::GetDnsConfig(&dns_config);
296 dns_config.timeout = timeout; 341 dns_config.timeout = timeout;
297 DnsChangeNotifier::SetDnsConfig(dns_config); 342 DnsChangeNotifier::SetDnsConfig(dns_config);
298 } 343 }
299 344
300 } // namespace certificate_transparency 345 } // namespace certificate_transparency
OLDNEW
« no previous file with comments | « components/certificate_transparency/mock_log_dns_traffic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698