]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/doh.hh
Merge pull request #8760 from rgacogne/ddist-doh-exact-match
[thirdparty/pdns.git] / pdns / doh.hh
1 #pragma once
2 #include "iputils.hh"
3 #include "libssl.hh"
4
5 struct DOHServerConfig;
6
7 class DOHResponseMapEntry
8 {
9 public:
10 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)
11 {
12 }
13
14 bool matches(const std::string& path) const
15 {
16 return d_regex.match(path);
17 }
18
19 uint16_t getStatusCode() const
20 {
21 return d_status;
22 }
23
24 const std::string& getContent() const
25 {
26 return d_content;
27 }
28
29 const boost::optional<std::vector<std::pair<std::string, std::string>>>& getHeaders() const
30 {
31 return d_customHeaders;
32 }
33
34 private:
35 Regex d_regex;
36 boost::optional<std::vector<std::pair<std::string, std::string>>> d_customHeaders;
37 std::string d_content;
38 uint16_t d_status;
39 };
40
41 struct DOHFrontend
42 {
43 DOHFrontend()
44 {
45 }
46
47 std::shared_ptr<DOHServerConfig> d_dsc{nullptr};
48 std::vector<std::shared_ptr<DOHResponseMapEntry>> d_responsesMap;
49 TLSConfig d_tlsConfig;
50 TLSErrorCounters d_tlsCounters;
51 std::string d_serverTokens{"h2o/dnsdist"};
52 std::vector<std::pair<std::string, std::string>> d_customResponseHeaders;
53 ComboAddress d_local;
54
55 uint32_t d_idleTimeout{30}; // HTTP idle timeout in seconds
56 std::vector<std::string> d_urls;
57
58 std::atomic<uint64_t> d_httpconnects{0}; // number of TCP/IP connections established
59 std::atomic<uint64_t> d_getqueries{0}; // valid DNS queries received via GET
60 std::atomic<uint64_t> d_postqueries{0}; // valid DNS queries received via POST
61 std::atomic<uint64_t> d_badrequests{0}; // request could not be converted to dns query
62 std::atomic<uint64_t> d_errorresponses{0}; // dnsdist set 'error' on response
63 std::atomic<uint64_t> d_redirectresponses{0}; // dnsdist set 'redirect' on response
64 std::atomic<uint64_t> d_validresponses{0}; // valid responses sent out
65
66 struct HTTPVersionStats
67 {
68 std::atomic<uint64_t> d_nbQueries{0}; // valid DNS queries received
69 std::atomic<uint64_t> d_nb200Responses{0};
70 std::atomic<uint64_t> d_nb400Responses{0};
71 std::atomic<uint64_t> d_nb403Responses{0};
72 std::atomic<uint64_t> d_nb500Responses{0};
73 std::atomic<uint64_t> d_nb502Responses{0};
74 std::atomic<uint64_t> d_nbOtherResponses{0};
75 };
76
77 HTTPVersionStats d_http1Stats;
78 HTTPVersionStats d_http2Stats;
79 bool d_sendCacheControlHeaders{true};
80
81 time_t getTicketsKeyRotationDelay() const
82 {
83 return d_tlsConfig.d_ticketsKeyRotationDelay;
84 }
85
86 #ifndef HAVE_DNS_OVER_HTTPS
87 void setup()
88 {
89 }
90
91 void reloadCertificates()
92 {
93 }
94
95 void rotateTicketsKey(time_t now)
96 {
97 }
98
99 void loadTicketsKeys(const std::string& keyFile)
100 {
101 }
102
103 void handleTicketsKeyRotation()
104 {
105 }
106
107 time_t getNextTicketsKeyRotation() const
108 {
109 return 0;
110 }
111
112 size_t getTicketsKeysCount() const
113 {
114 size_t res = 0;
115 return res;
116 }
117
118 #else
119 void setup();
120 void reloadCertificates();
121
122 void rotateTicketsKey(time_t now);
123 void loadTicketsKeys(const std::string& keyFile);
124 void handleTicketsKeyRotation();
125 time_t getNextTicketsKeyRotation() const;
126 size_t getTicketsKeysCount() const;
127 #endif /* HAVE_DNS_OVER_HTTPS */
128 };
129
130 #ifndef HAVE_DNS_OVER_HTTPS
131 struct DOHUnit
132 {
133 };
134
135 #else /* HAVE_DNS_OVER_HTTPS */
136 #include <unordered_map>
137
138 struct st_h2o_req_t;
139
140 struct DOHUnit
141 {
142 DOHUnit()
143 {
144 }
145 DOHUnit(const DOHUnit&) = delete;
146 DOHUnit& operator=(const DOHUnit&) = delete;
147
148 void get()
149 {
150 ++d_refcnt;
151 }
152
153 void release()
154 {
155 if (--d_refcnt == 0) {
156 delete this;
157 }
158 }
159
160 std::string query;
161 std::string response;
162 ComboAddress remote;
163 ComboAddress dest;
164 st_h2o_req_t* req{nullptr};
165 DOHUnit** self{nullptr};
166 std::string contentType;
167 std::atomic<uint64_t> d_refcnt{1};
168 int rsock;
169 uint16_t qtype;
170 /* the status_code is set from
171 processDOHQuery() (which is executed in
172 the DOH client thread) so that the correct
173 response can be sent in on_dnsdist(),
174 after the DOHUnit has been passed back to
175 the main DoH thread.
176 */
177 uint16_t status_code{200};
178 bool ednsAdded{false};
179
180 std::string getHTTPPath() const;
181 std::string getHTTPHost() const;
182 std::string getHTTPScheme() const;
183 std::string getHTTPQueryString() const;
184 std::unordered_map<std::string, std::string> getHTTPHeaders() const;
185 void setHTTPResponse(uint16_t statusCode, const std::string& body, const std::string& contentType="");
186 };
187
188 #endif /* HAVE_DNS_OVER_HTTPS */
189
190 void handleDOHTimeout(DOHUnit* oldDU);