]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/doh.hh
Replace include guard ifdef/define with pragma once
[thirdparty/pdns.git] / pdns / doh.hh
1 /*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22 #pragma once
23 #include "iputils.hh"
24 #include "libssl.hh"
25
26 struct DOHServerConfig;
27
28 class DOHResponseMapEntry
29 {
30 public:
31 DOHResponseMapEntry(const std::string& regex, uint16_t status, const std::string& content, const boost::optional<std::vector<std::pair<std::string, std::string>>>& headers): d_regex(regex), d_customHeaders(headers), d_content(content), d_status(status)
32 {
33 }
34
35 bool matches(const std::string& path) const
36 {
37 return d_regex.match(path);
38 }
39
40 uint16_t getStatusCode() const
41 {
42 return d_status;
43 }
44
45 const std::string& getContent() const
46 {
47 return d_content;
48 }
49
50 const boost::optional<std::vector<std::pair<std::string, std::string>>>& getHeaders() const
51 {
52 return d_customHeaders;
53 }
54
55 private:
56 Regex d_regex;
57 boost::optional<std::vector<std::pair<std::string, std::string>>> d_customHeaders;
58 std::string d_content;
59 uint16_t d_status;
60 };
61
62 struct DOHFrontend
63 {
64 DOHFrontend()
65 {
66 }
67
68 std::shared_ptr<DOHServerConfig> d_dsc{nullptr};
69 std::vector<std::shared_ptr<DOHResponseMapEntry>> d_responsesMap;
70 TLSConfig d_tlsConfig;
71 TLSErrorCounters d_tlsCounters;
72 std::string d_serverTokens{"h2o/dnsdist"};
73 std::vector<std::pair<std::string, std::string>> d_customResponseHeaders;
74 ComboAddress d_local;
75
76 uint32_t d_idleTimeout{30}; // HTTP idle timeout in seconds
77 std::vector<std::string> d_urls;
78
79 std::atomic<uint64_t> d_httpconnects{0}; // number of TCP/IP connections established
80 std::atomic<uint64_t> d_getqueries{0}; // valid DNS queries received via GET
81 std::atomic<uint64_t> d_postqueries{0}; // valid DNS queries received via POST
82 std::atomic<uint64_t> d_badrequests{0}; // request could not be converted to dns query
83 std::atomic<uint64_t> d_errorresponses{0}; // dnsdist set 'error' on response
84 std::atomic<uint64_t> d_redirectresponses{0}; // dnsdist set 'redirect' on response
85 std::atomic<uint64_t> d_validresponses{0}; // valid responses sent out
86
87 struct HTTPVersionStats
88 {
89 std::atomic<uint64_t> d_nbQueries{0}; // valid DNS queries received
90 std::atomic<uint64_t> d_nb200Responses{0};
91 std::atomic<uint64_t> d_nb400Responses{0};
92 std::atomic<uint64_t> d_nb403Responses{0};
93 std::atomic<uint64_t> d_nb500Responses{0};
94 std::atomic<uint64_t> d_nb502Responses{0};
95 std::atomic<uint64_t> d_nbOtherResponses{0};
96 };
97
98 HTTPVersionStats d_http1Stats;
99 HTTPVersionStats d_http2Stats;
100 bool d_sendCacheControlHeaders{true};
101
102 time_t getTicketsKeyRotationDelay() const
103 {
104 return d_tlsConfig.d_ticketsKeyRotationDelay;
105 }
106
107 #ifndef HAVE_DNS_OVER_HTTPS
108 void setup()
109 {
110 }
111
112 void reloadCertificates()
113 {
114 }
115
116 void rotateTicketsKey(time_t now)
117 {
118 }
119
120 void loadTicketsKeys(const std::string& keyFile)
121 {
122 }
123
124 void handleTicketsKeyRotation()
125 {
126 }
127
128 time_t getNextTicketsKeyRotation() const
129 {
130 return 0;
131 }
132
133 size_t getTicketsKeysCount() const
134 {
135 size_t res = 0;
136 return res;
137 }
138
139 #else
140 void setup();
141 void reloadCertificates();
142
143 void rotateTicketsKey(time_t now);
144 void loadTicketsKeys(const std::string& keyFile);
145 void handleTicketsKeyRotation();
146 time_t getNextTicketsKeyRotation() const;
147 size_t getTicketsKeysCount() const;
148 #endif /* HAVE_DNS_OVER_HTTPS */
149 };
150
151 #ifndef HAVE_DNS_OVER_HTTPS
152 struct DOHUnit
153 {
154 };
155
156 #else /* HAVE_DNS_OVER_HTTPS */
157 #include <unordered_map>
158
159 struct st_h2o_req_t;
160
161 struct DOHUnit
162 {
163 DOHUnit()
164 {
165 }
166 DOHUnit(const DOHUnit&) = delete;
167 DOHUnit& operator=(const DOHUnit&) = delete;
168
169 void get()
170 {
171 ++d_refcnt;
172 }
173
174 void release()
175 {
176 if (--d_refcnt == 0) {
177 delete this;
178 }
179 }
180
181 std::string query;
182 std::string response;
183 ComboAddress remote;
184 ComboAddress dest;
185 st_h2o_req_t* req{nullptr};
186 DOHUnit** self{nullptr};
187 std::string contentType;
188 std::atomic<uint64_t> d_refcnt{1};
189 int rsock;
190 uint16_t qtype;
191 /* the status_code is set from
192 processDOHQuery() (which is executed in
193 the DOH client thread) so that the correct
194 response can be sent in on_dnsdist(),
195 after the DOHUnit has been passed back to
196 the main DoH thread.
197 */
198 uint16_t status_code{200};
199 bool ednsAdded{false};
200
201 std::string getHTTPPath() const;
202 std::string getHTTPHost() const;
203 std::string getHTTPScheme() const;
204 std::string getHTTPQueryString() const;
205 std::unordered_map<std::string, std::string> getHTTPHeaders() const;
206 void setHTTPResponse(uint16_t statusCode, const std::string& body, const std::string& contentType="");
207 };
208
209 #endif /* HAVE_DNS_OVER_HTTPS */
210
211 void handleDOHTimeout(DOHUnit* oldDU);