blob: 7ce4dfeee81d3dcb50bcc38563060b024f86e8cb [file] [log] [blame]
robpercival6e7096f2016-07-25 13:34:001// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_CERTIFICATE_TRANSPARENCY_MOCK_LOG_DNS_TRAFFIC_H_
6#define COMPONENTS_CERTIFICATE_TRANSPARENCY_MOCK_LOG_DNS_TRAFFIC_H_
7
8#include <stdint.h>
9
10#include <memory>
11#include <string>
12#include <vector>
13
robpercival7038ecd2016-10-20 17:05:4914#include "base/compiler_specific.h"
robpercival6e7096f2016-07-25 13:34:0015#include "base/macros.h"
16#include "base/strings/string_piece.h"
17#include "net/dns/dns_client.h"
18#include "net/dns/dns_config_service.h"
19#include "net/socket/socket_test_util.h"
20
21namespace certificate_transparency {
22
robpercival6e7096f2016-07-25 13:34:0023// Mocks DNS requests and responses for a Certificate Transparency (CT) log.
24// This is implemented using mock sockets. Call the CreateDnsClient() method to
25// get a net::DnsClient wired up to these mock sockets.
26// The Expect*() methods must be called from within a GTest test case.
robpercival3106d3f2016-10-18 08:40:3227//
28// Example Usage:
29// // net::DnsClient requires an I/O message loop for async operations.
30// base::MessageLoopForIO message_loop;
31//
32// // Create a mock NetworkChangeNotifier to propagate DNS config.
33// std::unique_ptr<net::NetworkChangeNotifier> net_change_notifier(
34// net::NetworkChangeNotifier::CreateMock());
35//
36// MockLogDnsTraffic mock_dns;
37// mock_dns.InitializeDnsConfig();
38// // Use the Expect* methods to define expected DNS requests and responses.
39// mock_dns.ExpectLeafIndexRequestAndResponse(
40// "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.",
41// "123456");
42//
43// LogDnsClient log_client(mock_dns.CreateDnsClient(), ...);
44// log_client.QueryAuditProof("ct.test", ..., base::Bind(...));
robpercival6e7096f2016-07-25 13:34:0045class MockLogDnsTraffic {
46 public:
47 MockLogDnsTraffic();
48 ~MockLogDnsTraffic();
49
50 // Expect a CT DNS request for the domain |qname|.
51 // Such a request will receive a DNS response indicating that the error
52 // specified by |rcode| occurred. See RFC1035, Section 4.1.1 for |rcode|
53 // values.
robpercival7038ecd2016-10-20 17:05:4954 // Returns false if any of the arguments are invalid.
55 WARN_UNUSED_RESULT
56 bool ExpectRequestAndErrorResponse(base::StringPiece qname, uint8_t rcode);
robpercival3106d3f2016-10-18 08:40:3257
robpercival6e7096f2016-07-25 13:34:0058 // Expect a CT DNS request for the domain |qname|.
robpercival3106d3f2016-10-18 08:40:3259 // Such a request will trigger a socket error of type |error|.
robpercival7038ecd2016-10-20 17:05:4960 // Returns false if any of the arguments are invalid.
61 WARN_UNUSED_RESULT
62 bool ExpectRequestAndSocketError(base::StringPiece qname, net::Error error);
robpercival3106d3f2016-10-18 08:40:3263
robpercival6e7096f2016-07-25 13:34:0064 // Expect a CT DNS request for the domain |qname|.
65 // Such a request will timeout.
66 // This will reduce the DNS timeout to minimize test duration.
robpercival7038ecd2016-10-20 17:05:4967 // Returns false if |qname| is invalid.
68 WARN_UNUSED_RESULT
69 bool ExpectRequestAndTimeout(base::StringPiece qname);
robpercival3106d3f2016-10-18 08:40:3270
robpercival6e7096f2016-07-25 13:34:0071 // Expect a CT DNS request for the domain |qname|.
robpercival9dc75a82016-10-05 13:29:4472 // Such a request will receive a DNS TXT response containing |txt_strings|.
robpercival7038ecd2016-10-20 17:05:4973 // Returns false if any of the arguments are invalid.
74 WARN_UNUSED_RESULT
75 bool ExpectRequestAndResponse(
76 base::StringPiece qname,
77 const std::vector<base::StringPiece>& txt_strings);
78
robpercival9dc75a82016-10-05 13:29:4479 // Expect a CT DNS request for the domain |qname|.
robpercival6e7096f2016-07-25 13:34:0080 // Such a request will receive a DNS response containing |leaf_index|.
81 // A description of such a request and response can be seen here:
82 // https://github.com/google/certificate-transparency-rfcs/blob/c8844de6bd0b5d3d16bac79865e6edef533d760b/dns/draft-ct-over-dns.md#hash-query-hashquery
robpercival7038ecd2016-10-20 17:05:4983 // Returns false if any of the arguments are invalid.
84 WARN_UNUSED_RESULT
85 bool ExpectLeafIndexRequestAndResponse(base::StringPiece qname,
robpercival9dc75a82016-10-05 13:29:4486 uint64_t leaf_index);
robpercival7038ecd2016-10-20 17:05:4987
robpercival6e7096f2016-07-25 13:34:0088 // Expect a CT DNS request for the domain |qname|.
89 // Such a request will receive a DNS response containing the inclusion proof
90 // nodes between |audit_path_start| and |audit_path_end|.
91 // A description of such a request and response can be seen here:
92 // https://github.com/google/certificate-transparency-rfcs/blob/c8844de6bd0b5d3d16bac79865e6edef533d760b/dns/draft-ct-over-dns.md#tree-query-treequery
robpercival7038ecd2016-10-20 17:05:4993 // Returns false if any of the arguments are invalid.
94 WARN_UNUSED_RESULT
95 bool ExpectAuditProofRequestAndResponse(
robpercival6e7096f2016-07-25 13:34:0096 base::StringPiece qname,
97 std::vector<std::string>::const_iterator audit_path_start,
98 std::vector<std::string>::const_iterator audit_path_end);
99
100 // Sets the initial DNS config appropriate for testing.
101 // Requires that net::NetworkChangeNotifier is initialized first.
102 // The DNS config is propogated to NetworkChangeNotifier::DNSObservers
103 // asynchronously.
104 void InitializeDnsConfig();
105
106 // Sets the DNS config to |config|.
107 // Requires that net::NetworkChangeNotifier is initialized first.
108 // The DNS config is propogated to NetworkChangeNotifier::DNSObservers
109 // asynchronously.
110 void SetDnsConfig(const net::DnsConfig& config);
111
112 // Creates a DNS client that uses mock sockets.
113 // It is this DNS client that the expectations will be tested against.
114 std::unique_ptr<net::DnsClient> CreateDnsClient();
115
robpercival3106d3f2016-10-18 08:40:32116 private:
117 // Allows tests to change socket read mode. Only the LogDnsClient tests should
118 // need to do so, to ensure consistent behaviour regardless of mode.
119 friend class LogDnsClientTest;
120
121 class MockSocketData;
122
robpercival6e7096f2016-07-25 13:34:00123 // Sets whether mock reads should complete synchronously or asynchronously.
robpercival3106d3f2016-10-18 08:40:32124 // By default, they complete asynchronously.
robpercival6e7096f2016-07-25 13:34:00125 void SetSocketReadMode(net::IoMode read_mode) {
126 socket_read_mode_ = read_mode;
127 }
128
robpercival6e7096f2016-07-25 13:34:00129 // Constructs MockSocketData from |args| and adds it to |socket_factory_|.
130 template <typename... Args>
131 void EmplaceMockSocketData(Args&&... args);
132
133 // Sets the timeout used for DNS queries.
134 // Requires that net::NetworkChangeNotifier is initialized first.
135 // The new timeout is propogated to NetworkChangeNotifier::DNSObservers
136 // asynchronously.
137 void SetDnsTimeout(const base::TimeDelta& timeout);
138
139 // One MockSocketData for each socket that is created. This corresponds to one
140 // for each DNS request sent.
robpercival3106d3f2016-10-18 08:40:32141 std::vector<std::unique_ptr<MockSocketData>> mock_socket_data_;
robpercival6e7096f2016-07-25 13:34:00142 // Provides as many mock sockets as there are entries in |mock_socket_data_|.
143 net::MockClientSocketFactory socket_factory_;
144 // Controls whether mock socket reads are asynchronous.
145 net::IoMode socket_read_mode_;
146
147 DISALLOW_COPY_AND_ASSIGN(MockLogDnsTraffic);
148};
149
150} // namespace certificate_transparency
151
152#endif // COMPONENTS_CERTIFICATE_TRANSPARENCY_MOCK_LOG_DNS_TRAFFIC_H_