]>
Commit | Line | Data |
---|---|---|
bc7a7b24 OM |
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 | ||
23 | #pragma once | |
24 | ||
25 | #ifdef HAVE_CONFIG_H | |
26 | #include "config.h" | |
27 | #endif | |
28 | ||
29 | #include "logger.hh" | |
d8d1d955 | 30 | #include "logr.hh" |
bc7a7b24 OM |
31 | #include "lua-recursor4.hh" |
32 | #include "mplexer.hh" | |
33 | #include "namespaces.hh" | |
34 | #include "rec-lua-conf.hh" | |
35 | #include "rec-protozero.hh" | |
36 | #include "syncres.hh" | |
eeaa1cb6 | 37 | #include "rec-snmp.hh" |
b35191d7 | 38 | #include "rec_channel.hh" |
69b39198 | 39 | #include "threadname.hh" |
5abc5e10 | 40 | #include "recpacketcache.hh" |
eeaa1cb6 OM |
41 | |
42 | #ifdef NOD_ENABLED | |
43 | #include "nod.hh" | |
44 | #endif /* NOD_ENABLED */ | |
45 | ||
46 | #ifdef HAVE_BOOST_CONTAINER_FLAT_SET_HPP | |
47 | #include <boost/container/flat_set.hpp> | |
48 | #endif | |
bc7a7b24 | 49 | |
91092a9f OM |
50 | extern std::shared_ptr<Logr::Logger> g_slogtcpin; |
51 | extern std::shared_ptr<Logr::Logger> g_slogudpin; | |
ab26d8d5 | 52 | |
bc7a7b24 | 53 | //! used to send information to a newborn mthread |
8c1cb8aa OM |
54 | struct DNSComboWriter |
55 | { | |
c4ef9cf0 | 56 | DNSComboWriter(const std::string& query, const struct timeval& now, shared_ptr<RecursorLua4> luaContext) : |
645b217b | 57 | d_mdp(true, query), d_now(now), d_query(query), d_luaContext(std::move(luaContext)) |
bc7a7b24 OM |
58 | { |
59 | } | |
60 | ||
0b9da54f | 61 | DNSComboWriter(const std::string& query, const struct timeval& now, std::unordered_set<std::string>&& policyTags, shared_ptr<RecursorLua4> luaContext, LuaContext::LuaObject&& data, std::vector<DNSRecord>&& records) : |
a4d0f523 | 62 | d_mdp(true, query), d_now(now), d_query(query), d_policyTags(std::move(policyTags)), d_gettagPolicyTags(d_policyTags), d_records(std::move(records)), d_luaContext(std::move(luaContext)), d_data(std::move(data)) |
bc7a7b24 OM |
63 | { |
64 | } | |
65 | ||
e81063e5 | 66 | // The address the query is coming from |
bc7a7b24 OM |
67 | void setRemote(const ComboAddress& sa) |
68 | { | |
8c1cb8aa | 69 | d_remote = sa; |
bc7a7b24 OM |
70 | } |
71 | ||
e81063e5 | 72 | // The address we assume the query is coming from, might be set by proxy protocol |
bc7a7b24 OM |
73 | void setSource(const ComboAddress& sa) |
74 | { | |
8c1cb8aa | 75 | d_source = sa; |
bc7a7b24 OM |
76 | } |
77 | ||
e81063e5 OM |
78 | void setMappedSource(const ComboAddress& sa) |
79 | { | |
80 | d_mappedSource = sa; | |
81 | } | |
82 | ||
bc7a7b24 OM |
83 | void setLocal(const ComboAddress& sa) |
84 | { | |
8c1cb8aa | 85 | d_local = sa; |
bc7a7b24 OM |
86 | } |
87 | ||
e81063e5 | 88 | // The address we assume the query is sent to, might be set by proxy protocol |
bc7a7b24 OM |
89 | void setDestination(const ComboAddress& sa) |
90 | { | |
8c1cb8aa | 91 | d_destination = sa; |
bc7a7b24 OM |
92 | } |
93 | ||
94 | void setSocket(int sock) | |
95 | { | |
8c1cb8aa | 96 | d_socket = sock; |
bc7a7b24 OM |
97 | } |
98 | ||
e81063e5 | 99 | // get a string repesentation of the client address, including proxy info if applicable |
bc7a7b24 OM |
100 | string getRemote() const |
101 | { | |
102 | if (d_source == d_remote) { | |
103 | return d_source.toStringWithPort(); | |
104 | } | |
105 | return d_source.toStringWithPort() + " (proxied by " + d_remote.toStringWithPort() + ")"; | |
106 | } | |
107 | ||
108 | std::vector<ProxyProtocolValue> d_proxyProtocolValues; | |
109 | MOADNSParser d_mdp; | |
110 | struct timeval d_now; | |
e81063e5 OM |
111 | |
112 | ComboAddress d_remote; // the address the query is coming from | |
113 | ComboAddress d_source; // the address we assume the query is coming from, might be set by proxy protocol | |
114 | ComboAddress d_local; // the address we received the query on | |
115 | ComboAddress d_destination; // the address we assume the query is sent to, might be set by proxy protocol | |
116 | ComboAddress d_mappedSource; // the source address after being mapped by table based proxy mapping | |
bc7a7b24 OM |
117 | RecEventTrace d_eventTrace; |
118 | boost::uuids::uuid d_uuid; | |
119 | string d_requestorId; | |
120 | string d_deviceId; | |
121 | string d_deviceName; | |
8c1cb8aa OM |
122 | struct timeval d_kernelTimestamp |
123 | { | |
124 | 0, 0 | |
125 | }; | |
bc7a7b24 OM |
126 | std::string d_query; |
127 | std::unordered_set<std::string> d_policyTags; | |
a4d0f523 | 128 | const std::unordered_set<std::string> d_gettagPolicyTags; |
bc7a7b24 OM |
129 | std::string d_routingTag; |
130 | std::vector<DNSRecord> d_records; | |
0b9da54f OM |
131 | |
132 | // d_data is tied to this LuaContext so we need to keep it alive and use it, not a newer one, as long as d_data exists | |
133 | shared_ptr<RecursorLua4> d_luaContext; | |
bc7a7b24 | 134 | LuaContext::LuaObject d_data; |
0b9da54f | 135 | |
bc7a7b24 OM |
136 | EDNSSubnetOpts d_ednssubnet; |
137 | shared_ptr<TCPConnection> d_tcpConnection; | |
138 | boost::optional<uint16_t> d_extendedErrorCode{boost::none}; | |
139 | string d_extendedErrorExtra; | |
140 | boost::optional<int> d_rcode{boost::none}; | |
141 | int d_socket{-1}; | |
142 | unsigned int d_tag{0}; | |
143 | uint32_t d_qhash{0}; | |
144 | uint32_t d_ttlCap{std::numeric_limits<uint32_t>::max()}; | |
145 | bool d_variable{false}; | |
146 | bool d_ecsFound{false}; | |
147 | bool d_ecsParsed{false}; | |
148 | bool d_followCNAMERecords{false}; | |
149 | bool d_logResponse{false}; | |
150 | bool d_tcp{false}; | |
151 | bool d_responsePaddingDisabled{false}; | |
152 | std::map<std::string, RecursorLua4::MetaValue> d_meta; | |
153 | }; | |
154 | ||
a5040968 | 155 | extern thread_local unique_ptr<FDMultiplexer> t_fdm; |
b35191d7 OM |
156 | extern uint16_t g_minUdpSourcePort; |
157 | extern uint16_t g_maxUdpSourcePort; | |
7d3d2f4f | 158 | extern bool g_regressionTestMode; |
eeaa1cb6 OM |
159 | |
160 | // you can ask this class for a UDP socket to send a query from | |
161 | // this socket is not yours, don't even think about deleting it | |
162 | // but after you call 'returnSocket' on it, don't assume anything anymore | |
163 | class UDPClientSocks | |
164 | { | |
165 | unsigned int d_numsocks; | |
8c1cb8aa | 166 | |
eeaa1cb6 | 167 | public: |
8c1cb8aa OM |
168 | UDPClientSocks() : |
169 | d_numsocks(0) | |
eeaa1cb6 OM |
170 | { |
171 | } | |
172 | ||
e8e12e8c | 173 | LWResult::Result getSocket(const ComboAddress& toaddr, int* fileDesc); |
eeaa1cb6 OM |
174 | |
175 | // return a socket to the pool, or simply erase it | |
e8e12e8c | 176 | void returnSocket(int fileDesc); |
8c1cb8aa | 177 | |
eeaa1cb6 | 178 | private: |
eeaa1cb6 OM |
179 | // returns -1 for errors which might go away, throws for ones that won't |
180 | static int makeClientSocket(int family); | |
181 | }; | |
182 | ||
8c1cb8aa OM |
183 | enum class PaddingMode |
184 | { | |
185 | Always, | |
186 | PaddedQueries | |
187 | }; | |
bc7a7b24 OM |
188 | |
189 | typedef MTasker<std::shared_ptr<PacketID>, PacketBuffer, PacketIDCompare> MT_t; | |
e8e12e8c | 190 | extern thread_local std::unique_ptr<MT_t> g_multiTasker; // the big MTasker |
39e42424 | 191 | extern std::unique_ptr<RecursorPacketCache> g_packetCache; |
bc7a7b24 | 192 | |
9472436f OM |
193 | using RemoteLoggerStats_t = std::unordered_map<std::string, RemoteLoggerInterface::Stats>; |
194 | ||
9883d3f9 | 195 | extern bool g_yamlSettings; |
bc7a7b24 OM |
196 | extern bool g_logCommonErrors; |
197 | extern size_t g_proxyProtocolMaximumSize; | |
198 | extern std::atomic<bool> g_quiet; | |
bc7a7b24 OM |
199 | extern thread_local std::shared_ptr<RecursorLua4> t_pdl; |
200 | extern bool g_gettagNeedsEDNSOptions; | |
201 | extern NetmaskGroup g_paddingFrom; | |
202 | extern unsigned int g_paddingTag; | |
eeaa1cb6 | 203 | extern PaddingMode g_paddingMode; |
bc7a7b24 OM |
204 | extern unsigned int g_maxMThreads; |
205 | extern bool g_reusePort; | |
206 | extern bool g_anyToTcp; | |
207 | extern size_t g_tcpMaxQueriesPerConn; | |
208 | extern unsigned int g_maxTCPPerClient; | |
209 | extern int g_tcpTimeout; | |
eeaa1cb6 | 210 | extern uint16_t g_udpTruncationThreshold; |
b35191d7 OM |
211 | extern double g_balancingFactor; |
212 | extern size_t g_maxUDPQueriesPerRound; | |
eeaa1cb6 | 213 | extern bool g_useKernelTimestamp; |
bd3a0469 | 214 | extern bool g_allowNoRD; |
eeaa1cb6 OM |
215 | extern thread_local std::shared_ptr<NetmaskGroup> t_allowFrom; |
216 | extern thread_local std::shared_ptr<NetmaskGroup> t_allowNotifyFrom; | |
217 | extern thread_local std::shared_ptr<notifyset_t> t_allowNotifyFor; | |
218 | extern thread_local std::unique_ptr<UDPClientSocks> t_udpclientsocks; | |
eeaa1cb6 OM |
219 | extern bool g_useIncomingECS; |
220 | extern boost::optional<ComboAddress> g_dns64Prefix; | |
221 | extern DNSName g_dns64PrefixReverse; | |
222 | extern uint64_t g_latencyStatSize; | |
eeaa1cb6 | 223 | extern NetmaskGroup g_proxyProtocolACL; |
b35191d7 | 224 | extern std::atomic<bool> g_statsWanted; |
eeaa1cb6 OM |
225 | extern uint32_t g_disthashseed; |
226 | extern int g_argc; | |
227 | extern char** g_argv; | |
228 | extern std::shared_ptr<SyncRes::domainmap_t> g_initialDomainMap; // new threads needs this to be setup | |
229 | extern std::shared_ptr<NetmaskGroup> g_initialAllowFrom; // new thread needs to be setup with this | |
230 | extern std::shared_ptr<NetmaskGroup> g_initialAllowNotifyFrom; // new threads need this to be setup | |
231 | extern std::shared_ptr<notifyset_t> g_initialAllowNotifyFor; // new threads need this to be setup | |
232 | extern thread_local std::shared_ptr<Regex> t_traceRegex; | |
f3493699 | 233 | extern thread_local FDWrapper t_tracefd; |
b35191d7 OM |
234 | extern string g_programname; |
235 | extern string g_pidfname; | |
236 | extern RecursorControlChannel g_rcc; // only active in the handler thread | |
eeaa1cb6 | 237 | |
c375521b OM |
238 | extern thread_local std::unique_ptr<ProxyMapping> t_proxyMapping; |
239 | using ProxyMappingStats_t = std::unordered_map<Netmask, ProxyMappingCounts>; | |
e81063e5 | 240 | |
eeaa1cb6 OM |
241 | #ifdef NOD_ENABLED |
242 | extern bool g_nodEnabled; | |
243 | extern DNSName g_nodLookupDomain; | |
244 | extern bool g_nodLog; | |
245 | extern SuffixMatchNode g_nodDomainWL; | |
246 | extern std::string g_nod_pbtag; | |
247 | extern bool g_udrEnabled; | |
248 | extern bool g_udrLog; | |
249 | extern std::string g_udr_pbtag; | |
250 | extern thread_local std::shared_ptr<nod::NODDB> t_nodDBp; | |
251 | extern thread_local std::shared_ptr<nod::UniqueResponseDB> t_udrDBp; | |
252 | #endif | |
253 | ||
babe9430 OM |
254 | struct ProtobufServersInfo |
255 | { | |
256 | std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>> servers; | |
257 | uint64_t generation; | |
258 | ProtobufExportConfig config; | |
259 | }; | |
260 | extern thread_local ProtobufServersInfo t_protobufServers; | |
261 | extern thread_local ProtobufServersInfo t_outgoingProtobufServers; | |
262 | ||
eeaa1cb6 | 263 | #ifdef HAVE_FSTRM |
4354beb5 FM |
264 | struct FrameStreamServersInfo |
265 | { | |
266 | std::shared_ptr<std::vector<std::unique_ptr<FrameStreamLogger>>> servers; | |
267 | uint64_t generation; | |
268 | FrameStreamExportConfig config; | |
269 | }; | |
270 | ||
afaf1b5d | 271 | extern thread_local FrameStreamServersInfo t_frameStreamServersInfo; |
9489e2b5 | 272 | extern thread_local FrameStreamServersInfo t_nodFrameStreamServersInfo; |
eeaa1cb6 OM |
273 | #endif /* HAVE_FSTRM */ |
274 | ||
275 | #ifdef HAVE_BOOST_CONTAINER_FLAT_SET_HPP | |
b35191d7 | 276 | extern boost::container::flat_set<uint16_t> g_avoidUdpSourcePorts; |
eeaa1cb6 | 277 | #else |
b35191d7 | 278 | extern std::set<uint16_t> g_avoidUdpSourcePorts; |
eeaa1cb6 OM |
279 | #endif |
280 | ||
281 | /* without reuseport, all listeners share the same sockets */ | |
f4319769 | 282 | typedef vector<pair<int, std::function<void(int, boost::any&)>>> deferredAdd_t; |
bc7a7b24 OM |
283 | |
284 | typedef map<ComboAddress, uint32_t, ComboAddress::addressOnlyLessThan> tcpClientCounts_t; | |
285 | extern thread_local std::unique_ptr<tcpClientCounts_t> t_tcpClientCounts; | |
286 | ||
bc7a7b24 OM |
287 | inline MT_t* getMT() |
288 | { | |
e8e12e8c | 289 | return g_multiTasker ? g_multiTasker.get() : nullptr; |
bc7a7b24 OM |
290 | } |
291 | ||
bc7a7b24 OM |
292 | /* this function is called with both a string and a vector<uint8_t> representing a packet */ |
293 | template <class T> | |
294 | static bool sendResponseOverTCP(const std::unique_ptr<DNSComboWriter>& dc, const T& packet) | |
295 | { | |
296 | uint8_t buf[2]; | |
297 | buf[0] = packet.size() / 256; | |
298 | buf[1] = packet.size() % 256; | |
299 | ||
300 | Utility::iovec iov[2]; | |
8c1cb8aa OM |
301 | iov[0].iov_base = (void*)buf; |
302 | iov[0].iov_len = 2; | |
303 | iov[1].iov_base = (void*)&*packet.begin(); | |
304 | iov[1].iov_len = packet.size(); | |
bc7a7b24 OM |
305 | |
306 | int wret = Utility::writev(dc->d_socket, iov, 2); | |
307 | bool hadError = true; | |
308 | ||
309 | if (wret == 0) { | |
8c1cb8aa OM |
310 | g_log << Logger::Warning << "EOF writing TCP answer to " << dc->getRemote() << endl; |
311 | } | |
312 | else if (wret < 0) { | |
bc7a7b24 OM |
313 | int err = errno; |
314 | g_log << Logger::Warning << "Error writing TCP answer to " << dc->getRemote() << ": " << strerror(err) << endl; | |
8c1cb8aa OM |
315 | } |
316 | else if ((unsigned int)wret != 2 + packet.size()) { | |
317 | g_log << Logger::Warning << "Oops, partial answer sent to " << dc->getRemote() << " for " << dc->d_mdp.d_qname << " (size=" << (2 + packet.size()) << ", sent " << wret << ")" << endl; | |
318 | } | |
319 | else { | |
bc7a7b24 OM |
320 | hadError = false; |
321 | } | |
322 | ||
323 | return hadError; | |
324 | } | |
325 | ||
4f6e00dc OM |
326 | // For communicating with our threads effectively readonly after |
327 | // startup. | |
328 | // First we have the handler thread, t_id == 0 (some other helper | |
329 | // threads like SNMP might have t_id == 0 as well) then the | |
330 | // distributor threads if any and finally the workers | |
eeaa1cb6 OM |
331 | struct RecThreadInfo |
332 | { | |
333 | struct ThreadPipeSet | |
334 | { | |
335 | int writeToThread{-1}; | |
336 | int readToThread{-1}; | |
337 | int writeFromThread{-1}; | |
338 | int readFromThread{-1}; | |
339 | int writeQueriesToThread{-1}; // this one is non-blocking | |
340 | int readQueriesToThread{-1}; | |
341 | }; | |
342 | ||
69b39198 OM |
343 | public: |
344 | static RecThreadInfo& self() | |
345 | { | |
4f6e00dc OM |
346 | return s_threadInfos.at(t_id); |
347 | } | |
348 | ||
78199711 | 349 | static RecThreadInfo& info(unsigned int index) |
4f6e00dc | 350 | { |
78199711 | 351 | return s_threadInfos.at(index); |
4f6e00dc OM |
352 | } |
353 | ||
354 | static vector<RecThreadInfo>& infos() | |
355 | { | |
356 | return s_threadInfos; | |
69b39198 OM |
357 | } |
358 | ||
78199711 | 359 | [[nodiscard]] bool isDistributor() const |
69b39198 OM |
360 | { |
361 | if (t_id == 0) { | |
362 | return false; | |
363 | } | |
364 | return s_weDistributeQueries && listener; | |
365 | } | |
366 | ||
78199711 | 367 | [[nodiscard]] bool isHandler() const |
69b39198 OM |
368 | { |
369 | if (t_id == 0) { | |
370 | return true; | |
371 | } | |
372 | return handler; | |
373 | } | |
374 | ||
78199711 | 375 | [[nodiscard]] bool isWorker() const |
69b39198 OM |
376 | { |
377 | return worker; | |
378 | } | |
379 | ||
a808ca69 | 380 | // UDP or TCP listener? |
78199711 | 381 | [[nodiscard]] bool isListener() const |
69b39198 OM |
382 | { |
383 | return listener; | |
384 | } | |
a808ca69 OM |
385 | |
386 | // A TCP-only listener? | |
78199711 OM |
387 | [[nodiscard]] bool isTCPListener() const |
388 | { | |
389 | return tcplistener; | |
390 | } | |
69b39198 | 391 | |
78199711 | 392 | [[nodiscard]] bool isTaskThread() const |
048607b4 OM |
393 | { |
394 | return taskThread; | |
395 | } | |
396 | ||
69b39198 OM |
397 | void setHandler() |
398 | { | |
399 | handler = true; | |
400 | } | |
401 | ||
402 | void setWorker() | |
403 | { | |
404 | worker = true; | |
405 | } | |
406 | ||
407 | void setListener(bool flag = true) | |
408 | { | |
409 | listener = flag; | |
410 | } | |
411 | ||
78199711 OM |
412 | void setTCPListener(bool flag = true) |
413 | { | |
a808ca69 | 414 | setListener(flag); |
78199711 OM |
415 | tcplistener = flag; |
416 | } | |
417 | ||
048607b4 OM |
418 | void setTaskThread() |
419 | { | |
420 | taskThread = true; | |
421 | } | |
422 | ||
69b39198 OM |
423 | static unsigned int id() |
424 | { | |
425 | return t_id; | |
426 | } | |
427 | ||
78199711 | 428 | static void setThreadId(unsigned int arg) |
69b39198 | 429 | { |
78199711 | 430 | t_id = arg; |
69b39198 OM |
431 | } |
432 | ||
78199711 | 433 | [[nodiscard]] std::string getName() const |
aee3ab9f OM |
434 | { |
435 | return name; | |
436 | } | |
437 | ||
048607b4 OM |
438 | static unsigned int numHandlers() |
439 | { | |
440 | return 1; | |
441 | } | |
442 | ||
443 | static unsigned int numTaskThreads() | |
444 | { | |
445 | return 1; | |
446 | } | |
447 | ||
a808ca69 | 448 | static unsigned int numUDPWorkers() |
048607b4 | 449 | { |
a808ca69 | 450 | return s_numUDPWorkerThreads; |
048607b4 OM |
451 | } |
452 | ||
78199711 OM |
453 | static unsigned int numTCPWorkers() |
454 | { | |
455 | return s_numTCPWorkerThreads; | |
456 | } | |
457 | ||
048607b4 OM |
458 | static unsigned int numDistributors() |
459 | { | |
460 | return s_numDistributorThreads; | |
461 | } | |
462 | ||
463 | static bool weDistributeQueries() | |
464 | { | |
465 | return s_weDistributeQueries; | |
466 | } | |
467 | ||
468 | static void setWeDistributeQueries(bool flag) | |
469 | { | |
470 | s_weDistributeQueries = flag; | |
471 | } | |
472 | ||
a808ca69 | 473 | static void setNumUDPWorkerThreads(unsigned int n) |
048607b4 | 474 | { |
a808ca69 | 475 | s_numUDPWorkerThreads = n; |
048607b4 OM |
476 | } |
477 | ||
78199711 OM |
478 | static void setNumTCPWorkerThreads(unsigned int n) |
479 | { | |
480 | s_numTCPWorkerThreads = n; | |
481 | } | |
482 | ||
048607b4 OM |
483 | static void setNumDistributorThreads(unsigned int n) |
484 | { | |
485 | s_numDistributorThreads = n; | |
486 | } | |
487 | ||
488 | static unsigned int numRecursorThreads() | |
489 | { | |
a808ca69 | 490 | return numHandlers() + numDistributors() + numUDPWorkers() + numTCPWorkers() + numTaskThreads(); |
048607b4 OM |
491 | } |
492 | ||
d61b8a01 OM |
493 | static int runThreads(Logr::log_t); |
494 | static void makeThreadPipes(Logr::log_t); | |
3487974d | 495 | |
78199711 | 496 | void setExitCode(int n) |
3487974d | 497 | { |
78199711 | 498 | exitCode = n; |
3487974d OM |
499 | } |
500 | ||
78199711 OM |
501 | std::set<int>& getTCPSockets() |
502 | { | |
503 | return tcpSockets; | |
504 | } | |
505 | ||
506 | void setTCPSockets(std::set<int>& socks) | |
507 | { | |
508 | tcpSockets = socks; | |
509 | } | |
510 | ||
511 | deferredAdd_t& getDeferredAdds() | |
512 | { | |
513 | return deferredAdds; | |
514 | } | |
515 | ||
a808ca69 | 516 | const ThreadPipeSet& getPipes() const |
78199711 OM |
517 | { |
518 | return pipes; | |
519 | } | |
520 | ||
521 | [[nodiscard]] uint64_t getNumberOfDistributedQueries() const | |
522 | { | |
523 | return numberOfDistributedQueries; | |
524 | } | |
525 | ||
526 | void incNumberOfDistributedQueries() | |
527 | { | |
528 | numberOfDistributedQueries++; | |
529 | } | |
530 | ||
531 | MT_t* getMT() | |
532 | { | |
533 | return mt; | |
534 | } | |
535 | ||
536 | void setMT(MT_t* theMT) | |
537 | { | |
538 | mt = theMT; | |
539 | } | |
540 | ||
541 | private: | |
048607b4 OM |
542 | // FD corresponding to TCP sockets this thread is listening on. |
543 | // These FDs are also in deferredAdds when we have one socket per | |
544 | // listener, and in g_deferredAdds instead. | |
eeaa1cb6 | 545 | std::set<int> tcpSockets; |
4f6e00dc OM |
546 | // FD corresponding to listening sockets if we have one socket per |
547 | // listener (with reuseport), otherwise all listeners share the | |
548 | // same FD and g_deferredAdds is then used instead | |
eeaa1cb6 | 549 | deferredAdd_t deferredAdds; |
4f6e00dc | 550 | |
eeaa1cb6 | 551 | struct ThreadPipeSet pipes; |
eeaa1cb6 OM |
552 | MT_t* mt{nullptr}; |
553 | uint64_t numberOfDistributedQueries{0}; | |
69b39198 | 554 | |
a808ca69 | 555 | void start(unsigned int tid, const string& tname, const std::map<unsigned int, std::set<int>>& cpusMap, Logr::log_t); |
3487974d | 556 | |
31d899b1 | 557 | std::string name; |
3487974d OM |
558 | std::thread thread; |
559 | int exitCode{0}; | |
560 | ||
048607b4 | 561 | // handle the web server, carbon, statistics and the control channel |
69b39198 | 562 | bool handler{false}; |
048607b4 | 563 | // accept incoming queries (and distributes them to the workers if pdns-distributes-queries is set) |
69b39198 | 564 | bool listener{false}; |
78199711 OM |
565 | // accept incoming TCP queries (and distributes them to the workers if pdns-distributes-queries is set) |
566 | bool tcplistener{false}; | |
048607b4 | 567 | // process queries |
69b39198 | 568 | bool worker{false}; |
e4565646 | 569 | // run async tasks: from TaskQueue and ZoneToCache |
048607b4 OM |
570 | bool taskThread{false}; |
571 | ||
69b39198 | 572 | static thread_local unsigned int t_id; |
4f6e00dc | 573 | static std::vector<RecThreadInfo> s_threadInfos; |
048607b4 OM |
574 | static bool s_weDistributeQueries; // if true, 1 or more threads listen on the incoming query sockets and distribute them to workers |
575 | static unsigned int s_numDistributorThreads; | |
a808ca69 | 576 | static unsigned int s_numUDPWorkerThreads; |
78199711 | 577 | static unsigned int s_numTCPWorkerThreads; |
eeaa1cb6 OM |
578 | }; |
579 | ||
580 | struct ThreadMSG | |
581 | { | |
582 | pipefunc_t func; | |
583 | bool wantAnswer; | |
584 | }; | |
585 | ||
d8d1d955 | 586 | void parseACLs(); |
bc7a7b24 OM |
587 | PacketBuffer GenUDPQueryResponse(const ComboAddress& dest, const string& query); |
588 | bool checkProtobufExport(LocalStateHolder<LuaConfigItems>& luaconfsLocal); | |
eeaa1cb6 | 589 | bool checkOutgoingProtobufExport(LocalStateHolder<LuaConfigItems>& luaconfsLocal); |
678915f2 | 590 | #ifdef HAVE_FSTRM |
9489e2b5 | 591 | bool checkFrameStreamExport(LocalStateHolder<LuaConfigItems>& luaconfsLocal, const FrameStreamExportConfig& config, FrameStreamServersInfo& serverInfos); |
678915f2 | 592 | #endif |
bc7a7b24 | 593 | void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* qtype, uint16_t* qclass, |
fcd32fe8 | 594 | bool& foundECS, EDNSSubnetOpts* ednssubnet, EDNSOptionViewMap* options); |
ebe2aeb8 | 595 | void protobufLogQuery(LocalStateHolder<LuaConfigItems>& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedSource, const Netmask& ednssubnet, bool tcp, uint16_t queryID, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set<std::string>& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map<std::string, RecursorLua4::MetaValue>& meta); |
bc7a7b24 OM |
596 | bool isAllowNotifyForZone(DNSName qname); |
597 | bool checkForCacheHit(bool qnameParsed, unsigned int tag, const string& data, | |
8c1cb8aa OM |
598 | DNSName& qname, uint16_t& qtype, uint16_t& qclass, |
599 | const struct timeval& now, | |
600 | string& response, uint32_t& qhash, | |
c375521b | 601 | RecursorPacketCache::OptPBData& pbData, bool tcp, const ComboAddress& source, const ComboAddress& mappedSource); |
bc7a7b24 | 602 | void protobufLogResponse(pdns::ProtoZero::RecMessage& message); |
ebe2aeb8 | 603 | void protobufLogResponse(const struct dnsheader* header, LocalStateHolder<LuaConfigItems>& luaconfsLocal, |
8c1cb8aa OM |
604 | const RecursorPacketCache::OptPBData& pbData, const struct timeval& tv, |
605 | bool tcp, const ComboAddress& source, const ComboAddress& destination, | |
e81063e5 | 606 | const ComboAddress& mappedSource, const EDNSSubnetOpts& ednssubnet, |
8c1cb8aa OM |
607 | const boost::uuids::uuid& uniqueId, const string& requestorId, const string& deviceId, |
608 | const string& deviceName, const std::map<std::string, RecursorLua4::MetaValue>& meta, | |
c837140e OM |
609 | const RecEventTrace& eventTrace, |
610 | const std::unordered_set<std::string>& policyTags); | |
bc7a7b24 | 611 | void requestWipeCaches(const DNSName& canon); |
e8e12e8c | 612 | void startDoResolve(void*); |
bc7a7b24 | 613 | bool expectProxyProtocol(const ComboAddress& from); |
c0db60c3 | 614 | void finishTCPReply(std::unique_ptr<DNSComboWriter>&, bool hadError, bool updateInFlight); |
62b191dc OM |
615 | void checkFastOpenSysctl(bool active, Logr::log_t); |
616 | void checkTFOconnect(Logr::log_t); | |
d61b8a01 | 617 | void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set<int>& tcpSockets, Logr::log_t); |
c0db60c3 | 618 | void handleNewTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t&); |
eeaa1cb6 | 619 | |
d61b8a01 | 620 | void makeUDPServerSockets(deferredAdd_t& deferredAdds, Logr::log_t); |
42ae54e3 | 621 | string doTraceRegex(FDWrapper file, vector<string>::const_iterator begin, vector<string>::const_iterator end); |
eeaa1cb6 OM |
622 | |
623 | #define LOCAL_NETS "127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10" | |
624 | #define LOCAL_NETS_INVERSE "!127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10" | |
625 | // Bad Nets taken from both: | |
626 | // http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml | |
627 | // and | |
628 | // http://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml | |
629 | // where such a network may not be considered a valid destination | |
8c1cb8aa | 630 | #define BAD_NETS "0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32" |
eeaa1cb6 | 631 | #define DONT_QUERY LOCAL_NETS ", " BAD_NETS |