]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/common_startup.cc
Add/modify tests. Also re-check for the cache case. It *is* a bit
[thirdparty/pdns.git] / pdns / common_startup.cc
CommitLineData
12c86877 1/*
12471842
PL
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 */
870a0fe4
AT
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
619e8acc 25#include "common_startup.hh"
2470b36e 26#include "ws-auth.hh"
199631c6 27#include "secpoll-auth.hh"
e903706d 28#include <sys/time.h>
29#include <sys/resource.h>
f45a622c 30#include "dynhandler.hh"
82ee5aa5 31#include "dnsseckeeper.hh"
519f5484 32#include "threadname.hh"
2211dac9 33#include "misc.hh"
20829585 34#include "query-local-address.hh"
fa8fd4d2 35
c2826d2e
RG
36#include <thread>
37
6988eae9
PL
38#ifdef HAVE_SYSTEMD
39#include <systemd/sd-daemon.h>
40#endif
b653a73d 41
357f6a75 42bool g_anyToTcp;
fc41a1a6 43bool g_8bitDNS;
8900e2e3 44#ifdef HAVE_LUA_RECORDS
cb6bd1a9 45bool g_doLuaRecord;
af68014f 46int g_luaRecordExecLimit;
a6897a16
CHB
47time_t g_luaHealthChecksInterval{5};
48time_t g_luaHealthChecksExpireDelay{3600};
8900e2e3 49#endif
619e8acc
BH
50typedef Distributor<DNSPacket,DNSPacket,PacketHandler> DNSDistributor;
51
619e8acc 52ArgvMap theArg;
abc1d928 53StatBag S; //!< Statistics are gathered across PDNS via the StatBag class S
bf269e28
RG
54AuthPacketCache PC; //!< This is the main PacketCache, shared across all threads
55AuthQueryCache QC;
c2826d2e
RG
56std::unique_ptr<DNSProxy> DP{nullptr};
57std::unique_ptr<DynListener> dl{nullptr};
619e8acc 58CommunicatorClass Communicator;
12f224ab 59shared_ptr<UDPNameserver> N;
619e8acc 60int avg_latency;
8c98b341 61unique_ptr<TCPNameserver> TN;
12f224ab
RG
62static vector<DNSDistributor*> g_distributors;
63vector<std::shared_ptr<UDPNameserver> > g_udpReceivers;
619e8acc
BH
64
65ArgvMap &arg()
66{
67 return theArg;
68}
69
619e8acc
BH
70void declareArguments()
71{
709cbf16
CH
72 ::arg().set("config-dir","Location of configuration directory (pdns.conf)")=SYSCONFDIR;
73 ::arg().set("config-name","Name of this virtual configuration - will rename the binary image")="";
9a5b0a54
PL
74 ::arg().set("socket-dir",string("Where the controlsocket will live, ")+LOCALSTATEDIR+"/pdns when unset and not chrooted"
75#ifdef HAVE_SYSTEMD
76 + ". Set to the RUNTIME_DIRECTORY environment variable when that variable has a value (e.g. under systemd).")="";
77 auto runtimeDir = getenv("RUNTIME_DIRECTORY");
78 if (runtimeDir != nullptr) {
79 ::arg().set("socket-dir") = runtimeDir;
80 }
81#else
82 )="";
83#endif
709cbf16
CH
84 ::arg().set("module-dir","Default directory for modules")=PKGLIBDIR;
85 ::arg().set("chroot","If set, chroot to this directory for more security")="";
86 ::arg().set("logging-facility","Log under a specific facility")="";
87 ::arg().set("daemon","Operate as a daemon")="no";
88
dea466f3 89 ::arg().set("local-port","The port on which we listen")="53";
d07bf7ff 90 ::arg().setSwitch("dnsupdate","Enable/Disable DNS update (RFC2136) support. Default is no.")="no";
191f2e47 91 ::arg().setSwitch("write-pid","Write a PID file")="yes";
71f758e0 92 ::arg().set("allow-dnsupdate-from","A global setting to allow DNS updates from these IP ranges.")="127.0.0.0/8,::1";
ac340505 93 ::arg().setSwitch("send-signed-notify","Send TSIG secured NOTIFY if TSIG key is configured for a domain")="yes";
771bb0b0
AT
94 ::arg().set("allow-unsigned-notify","Allow unsigned notifications for TSIG secured domains")="yes"; //FIXME: change to 'no' later
95 ::arg().set("allow-unsigned-supermaster", "Allow supermasters to create zones without TSIG signed NOTIFY")="yes";
71f758e0 96 ::arg().setSwitch("forward-dnsupdate","A global setting to allow DNS update packages that are for a Slave domain, to be forwarded to the master.")="yes";
cfccf353 97 ::arg().setSwitch("log-dns-details","If PDNS should log DNS non-erroneous details")="no";
21a303f3 98 ::arg().setSwitch("log-dns-queries","If PDNS should log all incoming DNS queries")="no";
f5ad09dc 99 ::arg().set("local-address","Local IP addresses to which we bind")="0.0.0.0, ::";
e326f785 100 ::arg().set("local-ipv6","DEPRECATED, will be removed, move your IPs to local-address")="";
5ecb2885 101 ::arg().setSwitch("local-address-nonexist-fail","Fail to start if one or more of the local-address's do not exist on this server")="yes";
fec7dd5a 102 ::arg().setSwitch("non-local-bind", "Enable binding to non-local addresses by using FREEBIND / BINDANY socket options")="no";
bca4751c 103 ::arg().setSwitch("reuseport","Enable higher performance on compliant kernels by using SO_REUSEPORT allowing each receiver thread to open its own socket")="no";
297b769e 104 ::arg().set("query-local-address","Source IP addresses for sending queries")="0.0.0.0 ::";
9cee91cb 105 ::arg().set("query-local-address6","DEPRECATED: Use query-local-address. Source IPv6 address for sending queries")="";
e7e691cc 106 ::arg().set("overload-queue-length","Maximum queuelength moving to packetcache only")="0";
dea466f3 107 ::arg().set("max-queue-length","Maximum queuelength before considering situation lost")="5000";
a1fe72a4 108
dbcb3066 109 ::arg().set("retrieval-threads", "Number of AXFR-retrieval threads for slave operation")="2";
536ab56f 110 ::arg().setSwitch("api", "Enable/disable the REST API (including HTTP listener)")="no";
479e0976 111 ::arg().set("api-key", "Static pre-shared authentication key for access to the REST API")="";
b8cd24cc 112 ::arg().setSwitch("default-api-rectify","Default API-RECTIFY value for zones")="yes";
4dfe94ae 113 ::arg().setSwitch("dname-processing", "If we should support DNAME records")="no";
dea466f3
BH
114
115 ::arg().setCmd("help","Provide a helpful message");
116 ::arg().setCmd("version","Output version and compilation date");
117 ::arg().setCmd("config","Provide configuration file on standard output");
118 ::arg().setCmd("list-modules","Lists all modules available");
119 ::arg().setCmd("no-config","Don't parse configuration file");
619e8acc 120
dea466f3
BH
121 ::arg().set("version-string","PowerDNS version in packets - full, anonymous, powerdns or custom")="full";
122 ::arg().set("control-console","Debugging switch - don't use")="no"; // but I know you will!
dea466f3 123 ::arg().set("loglevel","Amount of logging. Higher is more. Do not set below 3")="4";
b6cfa948 124 ::arg().set("disable-syslog","Disable logging to syslog, useful when running inside a supervisor that logs stdout")="no";
b18fa400 125 ::arg().set("log-timestamp","Print timestamps in log lines")="yes";
dea466f3 126 ::arg().set("default-soa-name","name to insert in the SOA record if none set in the backend")="a.misconfigured.powerdns.server";
4c538037 127 ::arg().set("default-soa-mail","mail address to insert in the SOA record if none set in the backend")="";
dea466f3 128 ::arg().set("distributor-threads","Default number of Distributor (backend) threads to start")="3";
8267bd2c 129 ::arg().set("signing-threads","Default number of signer threads to start")="3";
37e4a4c3 130 ::arg().set("receiver-threads","Default number of receiver threads to start")="1";
dea466f3 131 ::arg().set("queue-limit","Maximum number of milliseconds to queue a query")="1500";
8eccac19 132 ::arg().set("resolver","Use this resolver for ALIAS and the internal stub resolver")="no";
e77145bb 133 ::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate")="1232";
619e8acc 134
dea466f3 135 ::arg().set("config-name","Name of this virtual configuration - will rename the binary image")="";
619e8acc 136
dea466f3
BH
137 ::arg().set("load-modules","Load this module - supply absolute or relative path")="";
138 ::arg().set("launch","Which backends to launch and order to query them in")="";
139 ::arg().setSwitch("disable-axfr","Disable zonetransfers but do allow TCP queries")="no";
cbdec4ae 140 ::arg().set("allow-axfr-ips","Allow zonetransfers only to these subnets")="127.0.0.0/8,::1";
68bb0e57 141 ::arg().set("only-notify", "Only send AXFR NOTIFY to these IP addresses or netmasks")="0.0.0.0/0,::/0";
24d3239e 142 ::arg().set("also-notify", "When notifying a domain, also notify these nameservers")="";
d207ad63 143 ::arg().set("allow-notify-from","Allow AXFR NOTIFY from these IP ranges. If empty, drop all incoming notifies.")="0.0.0.0/0,::/0";
8bc65f13 144 ::arg().set("slave-cycle-interval","Schedule slave freshness checks once every .. seconds")="60";
040712e0
BH
145
146 ::arg().set("tcp-control-address","If set, PowerDNS can be controlled over TCP on this address")="";
147 ::arg().set("tcp-control-port","If set, PowerDNS can be controlled over TCP on this address")="53000";
148 ::arg().set("tcp-control-secret","If set, PowerDNS can be controlled over TCP after passing this secret")="";
149 ::arg().set("tcp-control-range","If set, remote control of PowerDNS is possible over these networks only")="127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10";
619e8acc 150
dea466f3
BH
151 ::arg().setSwitch("slave","Act as a slave")="no";
152 ::arg().setSwitch("master","Act as a master")="no";
d3dfd71e 153 ::arg().setSwitch("superslave", "Act as a superslave")="no";
5633a4af 154 ::arg().setSwitch("disable-axfr-rectify","Disable the rectify step during an outgoing AXFR. Only required for regression testing.")="no";
dea466f3 155 ::arg().setSwitch("guardian","Run within a guardian process")="no";
8db49a64 156 ::arg().setSwitch("prevent-self-notification","Don't send notifications to what we think is ourself")="yes";
536ab56f
CH
157 ::arg().setSwitch("any-to-tcp","Answer ANY queries with tc=1, shunting to TCP")="yes";
158 ::arg().setSwitch("edns-subnet-processing","If we should act on EDNS Subnet options")="no";
159
160 ::arg().setSwitch("webserver","Start a webserver for monitoring (api=yes also enables the HTTP listener)")="no";
161 ::arg().setSwitch("webserver-print-arguments","If the webserver should print arguments")="no";
162 ::arg().set("webserver-address","IP Address of webserver/API to listen on")="127.0.0.1";
163 ::arg().set("webserver-port","Port of webserver/API to listen on")="8081";
dea466f3 164 ::arg().set("webserver-password","Password required for accessing the webserver")="";
be3e1477 165 ::arg().set("webserver-allow-from","Webserver/API access is only allowed from these subnets")="127.0.0.1,::1";
8ca656a8 166 ::arg().set("webserver-loglevel", "Amount of logging in the webserver (none, normal, detailed)") = "normal";
214b034e 167 ::arg().set("webserver-max-bodysize","Webserver/API maximum request/response body size in megabytes")="2";
dea466f3 168
ec1c0ed6 169 ::arg().setSwitch("do-ipv6-additional-processing", "Do AAAA additional processing")="yes";
dea466f3 170 ::arg().setSwitch("query-logging","Hint backends that queries should be logged")="no";
952d3fcb 171
2db16252 172 ::arg().set("carbon-namespace", "If set overwrites the first part of the carbon string")="pdns";
952d3fcb 173 ::arg().set("carbon-ourname", "If set, overrides our reported hostname for carbon stats")="";
f7a645ec 174 ::arg().set("carbon-instance", "If set overwrites the the instance name default")="auth";
90217d39 175 ::arg().set("carbon-server", "If set, send metrics in carbon (graphite) format to this server IP address")="";
952d3fcb 176 ::arg().set("carbon-interval", "Number of seconds between carbon (graphite) updates")="30";
177
dea466f3 178 ::arg().set("cache-ttl","Seconds to store packets in the PacketCache")="20";
ec7f535c
PD
179 ::arg().set("negquery-cache-ttl","Seconds to store negative query results in the QueryCache")="60";
180 ::arg().set("query-cache-ttl","Seconds to store query results in the QueryCache")="20";
abc1d928 181 ::arg().set("soa-minimum-ttl","Default SOA minimum ttl")="3600";
54c4c0d8 182 ::arg().set("server-id", "Returned when queried for 'id.server' TXT or NSID, defaults to hostname - disabled or custom")="";
dea466f3
BH
183 ::arg().set("soa-refresh-default","Default SOA refresh")="10800";
184 ::arg().set("soa-retry-default","Default SOA retry")="3600";
185 ::arg().set("soa-expire-default","Default SOA expire")="604800";
4192773a
KM
186 ::arg().set("default-soa-edit","Default SOA-EDIT value")="";
187 ::arg().set("default-soa-edit-signed","Default SOA-EDIT value for signed zones")="";
030850a9
RG
188 ::arg().set("dnssec-key-cache-ttl","Seconds to cache DNSSEC keys from the database")="30";
189 ::arg().set("domain-metadata-cache-ttl","Seconds to cache domain metadata from the database")="60";
dea466f3
BH
190
191 ::arg().set("trusted-notification-proxy", "IP address of incoming notification proxy")="";
8de9c054 192 ::arg().set("slave-renotify", "If we should send out notifications for slaved updates")="no";
130a758d 193 ::arg().set("forward-notify", "IP addresses to forward received notifications to regardless of master or slave settings")="";
dea466f3
BH
194
195 ::arg().set("default-ttl","Seconds a result is valid if not set otherwise")="3600";
6ee2c056 196 ::arg().set("max-tcp-connections","Maximum number of TCP connections")="20";
cb0af1a1 197 ::arg().set("max-tcp-connections-per-client","Maximum number of simultaneous TCP connections per client")="0";
69a1b753
PD
198 ::arg().set("max-tcp-transactions-per-conn","Maximum number of subsequent queries per TCP connection")="0";
199 ::arg().set("max-tcp-connection-duration","Maximum time in seconds that a TCP DNS connection is allowed to stay open.")="0";
200 ::arg().set("tcp-idle-timeout","Maximum time in seconds that a TCP DNS connection is allowed to stay open while being idle")="5";
cb0af1a1 201
dea466f3
BH
202 ::arg().setSwitch("no-shuffle","Set this to prevent random shuffling of answers - for regression testing")="off";
203
dea466f3
BH
204 ::arg().set("setuid","If set, change user id to this uid for more security")="";
205 ::arg().set("setgid","If set, change group id to this gid for more security")="";
206
bf269e28
RG
207 ::arg().set("max-cache-entries", "Maximum number of entries in the query cache")="1000000";
208 ::arg().set("max-packet-cache-entries", "Maximum number of entries in the packet cache")="1000000";
bba84134 209 ::arg().set("max-signature-cache-entries", "Maximum number of signatures cache entries")="";
b5baefaf 210 ::arg().set("max-ent-entries", "Maximum number of empty non-terminals in a zone")="100000";
a28a204a 211 ::arg().set("entropy-source", "If set, read entropy from this file")="/dev/urandom";
5704e107 212
3e8216c8 213 ::arg().set("lua-prequery-script", "Lua script with prequery handler (DO NOT USE)")="";
0ecc1158 214 ::arg().set("lua-dnsupdate-policy-script", "Lua script with DNS update policy handler")="";
5488e86b
PD
215
216 ::arg().setSwitch("traceback-handler","Enable the traceback handler (Linux only)")="yes";
16d72778 217 ::arg().setSwitch("direct-dnskey","Fetch DNSKEY, CDS and CDNSKEY RRs from backend during DNSKEY or CDS/CDNSKEY synthesis")="no";
28080ce6 218 ::arg().set("default-ksk-algorithm","Default KSK algorithm")="ecdsa256";
36758d25 219 ::arg().set("default-ksk-size","Default KSK size (0 means default)")="0";
28080ce6 220 ::arg().set("default-zsk-algorithm","Default ZSK algorithm")="";
95cc7e8d 221 ::arg().set("default-zsk-size","Default ZSK size (0 means default)")="0";
28b66a94 222 ::arg().set("max-nsec3-iterations","Limit the number of NSEC3 hash iterations")="500"; // RFC5155 10.3
c7094551
PD
223 ::arg().set("default-publish-cdnskey","Default value for PUBLISH-CDNSKEY")="";
224 ::arg().set("default-publish-cds","Default value for PUBLISH-CDS")="";
0a862860
AT
225
226 ::arg().set("include-dir","Include *.conf files from this directory");
199631c6 227 ::arg().set("security-poll-suffix","Domain name from which to query security update notifications")="secpoll.powerdns.com.";
7f6f4d4f 228
389b7a05 229 ::arg().setSwitch("expand-alias", "Expand ALIAS records")="no";
7f6f4d4f 230 ::arg().setSwitch("outgoing-axfr-expand-alias", "Expand ALIAS records during outgoing AXFR")="no";
fc41a1a6 231 ::arg().setSwitch("8bit-dns", "Allow 8bit dns queries")="no";
af68014f 232#ifdef HAVE_LUA_RECORDS
27a630b4
CHB
233 ::arg().setSwitch("enable-lua-records", "Process LUA records for all zones (metadata overrides this)")="no";
234 ::arg().set("lua-records-exec-limit", "LUA records scripts execution limit (instructions count). Values <= 0 mean no limit")="1000";
e3982a50 235 ::arg().set("lua-health-checks-expire-delay", "Stops doing health checks after the record hasn't been used for that delay (in seconds)")="3600";
a6897a16 236 ::arg().set("lua-health-checks-interval", "LUA records health checks monitoring interval in seconds")="5";
af68014f 237#endif
0f76617d 238 ::arg().setSwitch("axfr-lower-serial", "Also AXFR a zone from a master with a lower serial")="no";
db8f9152 239
86177332 240 ::arg().set("lua-axfr-script", "Script to be used to edit incoming AXFRs")="";
db8f9152 241 ::arg().set("xfr-max-received-mbytes", "Maximum number of megabytes received from an incoming XFR")="100";
e3619f57 242 ::arg().set("axfr-fetch-timeout", "Maximum time in seconds for inbound AXFR to start or be idle after starting")="10";
940d7811
RG
243
244 ::arg().set("tcp-fast-open", "Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size")="0";
e97cb679 245
ba3d53d1
RG
246 ::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file")="0";
247
e97cb679 248 ::arg().set("rng", "Specify the random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.")="auto";
8864bdf6 249 ::arg().setDefaults();
619e8acc
BH
250}
251
22f1199c 252static time_t s_start=time(0);
e903706d 253static uint64_t uptimeOfProcess(const std::string& str)
254{
22f1199c 255 return time(0) - s_start;
e903706d 256}
257
258static uint64_t getSysUserTimeMsec(const std::string& str)
259{
260 struct rusage ru;
261 getrusage(RUSAGE_SELF, &ru);
262
a2746484 263 if(str=="sys-msec") {
e903706d 264 return (ru.ru_stime.tv_sec*1000ULL + ru.ru_stime.tv_usec/1000);
a2746484 265 }
e903706d 266 else
267 return (ru.ru_utime.tv_sec*1000ULL + ru.ru_utime.tv_usec/1000);
268
269}
270
d322f931
PD
271static uint64_t getTCPConnectionCount(const std::string& str)
272{
273 return TN->numTCPConnections();
274}
275
1a46890f 276static uint64_t getQCount(const std::string& str)
2bf07cf4 277try
1a46890f 278{
279 int totcount=0;
c2826d2e 280 for(const auto& d : g_distributors) {
ba98c6d7 281 if(!d)
282 continue;
491d03d7 283 totcount += d->getQueueSize(); // this does locking and other things, so don't get smart
1a46890f 284 }
285 return totcount;
286}
2bf07cf4 287catch(std::exception& e)
288{
e6a9dde5 289 g_log<<Logger::Error<<"Had error retrieving queue sizes: "<<e.what()<<endl;
2bf07cf4 290 return 0;
291}
292catch(PDNSException& e)
293{
e6a9dde5 294 g_log<<Logger::Error<<"Had error retrieving queue sizes: "<<e.reason<<endl;
2bf07cf4 295 return 0;
296}
1a46890f 297
298static uint64_t getLatency(const std::string& str)
299{
300 return avg_latency;
301}
302
619e8acc
BH
303void declareStats(void)
304{
305 S.declare("udp-queries","Number of UDP queries received");
9951e2d0 306 S.declare("udp-do-queries","Number of UDP queries received with DO bit");
619e8acc 307 S.declare("udp-answers","Number of answers sent out over UDP");
4b24088f 308 S.declare("udp-answers-bytes","Total size of answers sent out over UDP");
50dbdbeb
PL
309 S.declare("udp4-answers-bytes","Total size of answers sent out over UDPv4");
310 S.declare("udp6-answers-bytes","Total size of answers sent out over UDPv6");
bd852e59
BH
311
312 S.declare("udp4-answers","Number of IPv4 answers sent out over UDP");
9951e2d0 313 S.declare("udp4-queries","Number of IPv4 UDP queries received");
bd852e59
BH
314 S.declare("udp6-answers","Number of IPv6 answers sent out over UDP");
315 S.declare("udp6-queries","Number of IPv6 UDP queries received");
d3363b40 316 S.declare("overload-drops","Queries dropped because backends overloaded");
bd852e59 317
bb6e54fe 318 S.declare("rd-queries", "Number of recursion desired questions");
319 S.declare("recursion-unanswered", "Number of packets unanswered by configured recursor");
619e8acc
BH
320 S.declare("recursing-answers","Number of recursive answers sent out");
321 S.declare("recursing-questions","Number of questions sent to recursor");
322 S.declare("corrupt-packets","Number of corrupt packets received");
c681ff64 323 S.declare("signatures", "Number of DNSSEC signatures made");
619e8acc
BH
324 S.declare("tcp-queries","Number of TCP queries received");
325 S.declare("tcp-answers","Number of answers sent out over TCP");
b552d7b1 326 S.declare("tcp-answers-bytes","Total size of answers sent out over TCP");
50dbdbeb
PL
327 S.declare("tcp4-answers-bytes","Total size of answers sent out over TCPv4");
328 S.declare("tcp6-answers-bytes","Total size of answers sent out over TCPv6");
329
5fd567ec 330 S.declare("tcp4-queries","Number of IPv4 TCP queries received");
331 S.declare("tcp4-answers","Number of IPv4 answers sent out over TCP");
332
333 S.declare("tcp6-queries","Number of IPv6 TCP queries received");
334 S.declare("tcp6-answers","Number of IPv6 answers sent out over TCP");
d322f931
PD
335
336 S.declare("open-tcp-connections","Number of currently open TCP connections", getTCPConnectionCount);;
619e8acc 337
1a46890f 338 S.declare("qsize-q","Number of questions waiting for database attention", getQCount);
619e8acc 339
71f758e0
KM
340 S.declare("dnsupdate-queries", "DNS update packets received.");
341 S.declare("dnsupdate-answers", "DNS update packets successfully answered.");
342 S.declare("dnsupdate-refused", "DNS update packets that are refused.");
343 S.declare("dnsupdate-changes", "DNS update changes to records in total.");
619e8acc 344
93aecccc
RK
345 S.declare("incoming-notifications", "NOTIFY packets received.");
346
e903706d 347 S.declare("uptime", "Uptime of process in seconds", uptimeOfProcess);
af0c10e7 348 S.declare("real-memory-usage", "Actual unique use of memory in bytes (approx)", getRealMemoryUsage);
330dcb5c 349 S.declare("special-memory-usage", "Actual unique use of memory in bytes (approx)", getSpecialMemoryUsage);
24538841 350 S.declare("fd-usage", "Number of open filedescriptors", getOpenFileDescriptors);
f45a622c 351#ifdef __linux__
352 S.declare("udp-recvbuf-errors", "UDP 'recvbuf' errors", udpErrorStats);
353 S.declare("udp-sndbuf-errors", "UDP 'sndbuf' errors", udpErrorStats);
354 S.declare("udp-noport-errors", "UDP 'noport' errors", udpErrorStats);
355 S.declare("udp-in-errors", "UDP 'in' errors", udpErrorStats);
356#endif
357
e903706d 358 S.declare("sys-msec", "Number of msec spent in system time", getSysUserTimeMsec);
359 S.declare("user-msec", "Number of msec spent in user time", getSysUserTimeMsec);
149a72d8
RG
360
361#ifdef __linux__
c46df0ca
RG
362 S.declare("cpu-iowait", "Time spent waiting for I/O to complete by the whole system, in units of USER_HZ", getCPUIOWait);
363 S.declare("cpu-steal", "Stolen time, which is the time spent by the whole system in other operating systems when running in a virtualized environment, in units of USER_HZ", getCPUSteal);
149a72d8
RG
364#endif
365
e903706d 366 S.declare("meta-cache-size", "Number of entries in the metadata cache", DNSSECKeeper::dbdnssecCacheSizes);
367 S.declare("key-cache-size", "Number of entries in the key cache", DNSSECKeeper::dbdnssecCacheSizes);
368 S.declare("signature-cache-size", "Number of entries in the signature cache", signatureCacheSize);
369
619e8acc 370 S.declare("servfail-packets","Number of times a server-failed packet was sent out");
1a46890f 371 S.declare("latency","Average number of microseconds needed to answer a question", getLatency);
619e8acc 372 S.declare("timedout-packets","Number of packets which weren't answered within timeout set");
199631c6 373 S.declare("security-status", "Security status based on regular polling");
eb029b8e
PL
374 S.declareDNSNameQTypeRing("queries","UDP Queries Received");
375 S.declareDNSNameQTypeRing("nxdomain-queries","Queries for non-existent records within existent domains");
376 S.declareDNSNameQTypeRing("noerror-queries","Queries for existing records, but for type we don't have");
377 S.declareDNSNameQTypeRing("servfail-queries","Queries that could not be answered due to backend errors");
378 S.declareDNSNameQTypeRing("unauth-queries","Queries for domains that we are not authoritative for");
619e8acc 379 S.declareRing("logmessages","Log Messages");
4eb26e0f 380 S.declareComboRing("remotes","Remote server IP addresses");
381 S.declareComboRing("remotes-unauth","Remote hosts querying domains for which we are not auth");
382 S.declareComboRing("remotes-corrupt","Remote hosts sending corrupt packets");
619e8acc
BH
383}
384
619e8acc
BH
385int isGuarded(char **argv)
386{
387 char *p=strstr(argv[0],"-instance");
388
389 return !!p;
390}
391
c2826d2e 392static void sendout(std::unique_ptr<DNSPacket>& a)
619e8acc 393{
491d03d7 394 if(!a)
619e8acc
BH
395 return;
396
c2826d2e 397 N->send(*a);
bd852e59 398
491d03d7 399 int diff=a->d_dt.udiff();
a2746484 400 avg_latency=(int)(0.999*avg_latency+0.001*diff);
619e8acc
BH
401}
402
abc1d928 403//! The qthread receives questions over the internet via the Nameserver class, and hands them to the Distributor for further processing
c2826d2e 404static void qthread(unsigned int num)
26d75dc2 405try
619e8acc 406{
519f5484 407 setThreadName("pdns/receiver");
09b12b5d 408
c2826d2e
RG
409 g_distributors[num] = DNSDistributor::Create(::arg().asNum("distributor-threads", 1));
410 DNSDistributor* distributor = g_distributors[num]; // the big dispatcher!
27c0050c
RG
411 DNSPacket question(true);
412 DNSPacket cached(false);
619e8acc 413
1566533a 414 AtomicCounter &numreceived=*S.getPointer("udp-queries");
415 AtomicCounter &numreceiveddo=*S.getPointer("udp-do-queries");
bd852e59 416
1566533a 417 AtomicCounter &numreceived4=*S.getPointer("udp4-queries");
bd852e59 418
1566533a 419 AtomicCounter &numreceived6=*S.getPointer("udp6-queries");
d3363b40 420 AtomicCounter &overloadDrops=*S.getPointer("overload-drops");
90b07284 421
619e8acc 422 int diff;
21a303f3 423 bool logDNSQueries = ::arg().mustDo("log-dns-queries");
12f224ab 424 shared_ptr<UDPNameserver> NS;
2c001eb6
RG
425 std::string buffer;
426 buffer.resize(DNSPacket::s_udpTruncationThreshold);
4ee30c66
MZ
427
428 // If we have SO_REUSEPORT then create a new port for all receiver threads
429 // other than the first one.
c2826d2e 430 if(N->canReusePort() ) {
12f224ab
RG
431 NS = g_udpReceivers[num];
432 if (NS == nullptr) {
ed3afdfc
PD
433 NS = N;
434 }
12f224ab
RG
435 } else {
436 NS = N;
3a56adcc 437 }
4ee30c66 438
619e8acc 439 for(;;) {
c2826d2e 440 if(!NS->receive(question, buffer)) { // receive a packet inline
fe172793 441 continue; // packet was broken, try again
442 }
443
296ff2ed 444 numreceived++;
8a63d3ce 445
c2826d2e 446 if(question.d_remote.getSocklen()==sizeof(sockaddr_in))
bd852e59
BH
447 numreceived4++;
448 else
449 numreceived6++;
619e8acc 450
c2826d2e 451 if(question.d_dnssecOk)
9951e2d0
KM
452 numreceiveddo++;
453
c2826d2e 454 if(question.d.qr)
6a90bacf
BH
455 continue;
456
c2826d2e
RG
457 S.ringAccount("queries", question.qdomain, question.qtype);
458 S.ringAccount("remotes", question.d_remote);
fe498ace
BH
459 if(logDNSQueries) {
460 string remote;
c2826d2e
RG
461 if(question.hasEDNSSubnet())
462 remote = question.getRemote().toString() + "<-" + question.getRealRemote().toString();
fe498ace 463 else
c2826d2e
RG
464 remote = question.getRemote().toString();
465 g_log << Logger::Notice<<"Remote "<< remote <<" wants '" << question.qdomain<<"|"<<question.qtype.getName() <<
466 "', do = " <<question.d_dnssecOk <<", bufsize = "<< question.getMaxReplyLen();
467 if(question.d_ednsRawPacketSizeLimit > 0 && question.getMaxReplyLen() != (unsigned int)question.d_ednsRawPacketSizeLimit)
468 g_log<<" ("<<question.d_ednsRawPacketSizeLimit<<")";
fe498ace 469 }
abc8f3f9 470
c2826d2e
RG
471 if(PC.enabled() && (question.d.opcode != Opcode::Notify && question.d.opcode != Opcode::Update) && question.couldBeCached()) {
472 bool haveSomething=PC.get(question, cached); // does the PacketCache recognize this question?
75fde355
KM
473 if (haveSomething) {
474 if(logDNSQueries)
1b16851b 475 g_log<<": packetcache HIT"<<endl;
c2826d2e
RG
476 cached.setRemote(&question.d_remote); // inlined
477 cached.setSocket(question.getSocket()); // inlined
478 cached.d_anyLocal = question.d_anyLocal;
479 cached.setMaxReplyLen(question.getMaxReplyLen());
480 cached.d.rd=question.d.rd; // copy in recursion desired bit
481 cached.d.id=question.d.id;
75fde355 482 cached.commitD(); // commit d to the packet inlined
c2826d2e
RG
483 NS->send(cached); // answer it then inlined
484 diff=question.d_dt.udiff();
da286f66 485 avg_latency=(int)(0.999*avg_latency+0.001*diff); // 'EWMA'
75fde355
KM
486 continue;
487 }
619e8acc 488 }
bf269e28 489
078f4c97 490 if(distributor->isOverloaded()) {
bbe4b041 491 if(logDNSQueries)
1b16851b 492 g_log<<": Dropped query, backends are overloaded"<<endl;
d3363b40 493 overloadDrops++;
e7e691cc
BH
494 continue;
495 }
bbe4b041
OM
496
497 if (logDNSQueries) {
498 if (PC.enabled()) {
1b16851b 499 g_log<<": packetcache MISS"<<endl;
bbe4b041 500 } else {
1b16851b 501 g_log<<endl;
bbe4b041
OM
502 }
503 }
e7e691cc 504
491d03d7 505 try {
c2826d2e 506 distributor->question(question, &sendout); // otherwise, give to the distributor
491d03d7 507 }
508 catch(DistributorFatal& df) { // when this happens, we have leaked loads of memory. Bailing out time.
509 _exit(1);
510 }
619e8acc 511 }
619e8acc 512}
26d75dc2 513catch(PDNSException& pe)
514{
e6a9dde5 515 g_log<<Logger::Error<<"Fatal error in question thread: "<<pe.reason<<endl;
26d75dc2 516 _exit(1);
517}
619e8acc 518
9092419e 519static void dummyThread()
2250bafa 520{
2250bafa 521}
522
523static void triggerLoadOfLibraries()
524{
9092419e
RG
525 std::thread dummy(dummyThread);
526 dummy.join();
2250bafa 527}
528
619e8acc
BH
529void mainthread()
530{
b51ef4f9 531 Utility::srandom();
619e8acc 532
76ba685e
PL
533 gid_t newgid = 0;
534 if(!::arg()["setgid"].empty())
2211dac9 535 newgid = strToGID(::arg()["setgid"]);
76ba685e
PL
536 uid_t newuid = 0;
537 if(!::arg()["setuid"].empty())
2211dac9 538 newuid = strToUID(::arg()["setuid"]);
af7d3ea6 539
357f6a75 540 g_anyToTcp = ::arg().mustDo("any-to-tcp");
fc41a1a6 541 g_8bitDNS = ::arg().mustDo("8bit-dns");
8900e2e3 542#ifdef HAVE_LUA_RECORDS
27a630b4 543 g_doLuaRecord = ::arg().mustDo("enable-lua-records");
32829819 544 g_LuaRecordSharedState = (::arg()["enable-lua-records"] == "shared");
27a630b4 545 g_luaRecordExecLimit = ::arg().asNum("lua-records-exec-limit");
a6897a16
CHB
546 g_luaHealthChecksInterval = ::arg().asNum("lua-health-checks-interval");
547 g_luaHealthChecksExpireDelay = ::arg().asNum("lua-health-checks-expire-delay");
8900e2e3 548#endif
8dee0750 549
1cd66b8e 550 DNSPacket::s_udpTruncationThreshold = std::max(512, ::arg().asNum("udp-truncation-threshold"));
af7d3ea6 551 DNSPacket::s_doEDNSSubnetProcessing = ::arg().mustDo("edns-subnet-processing");
199631c6 552
bf269e28
RG
553 PC.setTTL(::arg().asNum("cache-ttl"));
554 PC.setMaxEntries(::arg().asNum("max-packet-cache-entries"));
555 QC.setMaxEntries(::arg().asNum("max-cache-entries"));
307994e7 556 DNSSECKeeper::setMaxEntries(::arg().asNum("max-cache-entries"));
bf269e28 557
1b16851b
OM
558 if (!PC.enabled() && ::arg().mustDo("log-dns-queries")) {
559 g_log<<Logger::Warning<<"Packet cache disabled, logging queries without HIT/MISS"<<endl;
560 }
561
150e318e 562 stubParseResolveConf();
199631c6 563
f0f3f0b0 564 if(!::arg()["chroot"].empty()) {
75336810
PL
565#ifdef HAVE_SYSTEMD
566 char *ns;
567 ns = getenv("NOTIFY_SOCKET");
568 if (ns != nullptr) {
e6a9dde5 569 g_log<<Logger::Error<<"Unable to chroot when running from systemd. Please disable chroot= or set the 'Type' for this service to 'simple'"<<endl;
75336810
PL
570 exit(1);
571 }
572#endif
2250bafa 573 triggerLoadOfLibraries();
dea466f3 574 if(::arg().mustDo("master") || ::arg().mustDo("slave"))
4957a608 575 gethostbyname("a.root-servers.net"); // this forces all lookup libraries to be loaded
f1d6a7ce 576 Utility::dropGroupPrivs(newuid, newgid);
dea466f3 577 if(chroot(::arg()["chroot"].c_str())<0 || chdir("/")<0) {
a702a96c 578 g_log<<Logger::Error<<"Unable to chroot to '"+::arg()["chroot"]+"': "<<stringerror()<<", exiting"<<endl;
619e8acc
BH
579 exit(1);
580 }
581 else
e6a9dde5 582 g_log<<Logger::Error<<"Chrooted to '"<<::arg()["chroot"]<<"'"<<endl;
f1d6a7ce
KM
583 } else {
584 Utility::dropGroupPrivs(newuid, newgid);
585 }
357f6a75 586
dea47634 587 AuthWebServer webserver;
f1d6a7ce 588 Utility::dropUserPrivs(newuid);
619e8acc 589
8eccac19 590 if(::arg().mustDo("resolver")){
c2826d2e 591 DP=std::unique_ptr<DNSProxy>(new DNSProxy(::arg()["resolver"]));
619e8acc
BH
592 DP->go();
593 }
e6402e23
PL
594
595 try {
596 doSecPoll(true);
597 }
598 catch(...) {}
599
efc10591
PL
600 {
601 // Some sanity checking on default key settings
602 bool hadKeyError = false;
603 int kskAlgo{0}, zskAlgo{0};
604 for (const string& algotype : {"ksk", "zsk"}) {
605 int algo, size;
606 if (::arg()["default-"+algotype+"-algorithm"].empty())
607 continue;
608 algo = DNSSECKeeper::shorthand2algorithm(::arg()["default-"+algotype+"-algorithm"]);
609 size = ::arg().asNum("default-"+algotype+"-size");
610 if (algo == -1) {
611 g_log<<Logger::Error<<"Error: default-"<<algotype<<"-algorithm set to unknown algorithm: "<<::arg()["default-"+algotype+"-algorithm"]<<endl;
612 hadKeyError = true;
613 }
614 else if (algo <= 10 && size == 0) {
615 g_log<<Logger::Error<<"Error: default-"<<algotype<<"-algorithm is set to an algorithm ("<<::arg()["default-"+algotype+"-algorithm"]<<") that requires a non-zero default-"<<algotype<<"-size!"<<endl;
616 hadKeyError = true;
617 }
618 if (algotype == "ksk") {
619 kskAlgo = algo;
620 } else {
621 zskAlgo = algo;
622 }
8b8e8670 623 }
efc10591
PL
624 if (hadKeyError) {
625 exit(1);
626 }
627 if (kskAlgo == 0 && zskAlgo != 0) {
628 g_log<<Logger::Error<<"Error: default-zsk-algorithm is set, but default-ksk-algorithm is not set."<<endl;
629 exit(1);
630 }
631 if (zskAlgo != 0 && zskAlgo != kskAlgo) {
632 g_log<<Logger::Error<<"Error: default-zsk-algorithm ("<<::arg()["default-zsk-algorithm"]<<"), when set, can not be different from default-ksk-algorithm ("<<::arg()["default-ksk-algorithm"]<<")."<<endl;
633 exit(1);
8b8e8670 634 }
82ee5aa5
PL
635 }
636
20829585 637 pdns::parseQueryLocalAddress(::arg()["query-local-address"]);
9cee91cb
PL
638 if (!::arg()["query-local-address6"].empty()) {
639 g_log<<Logger::Warning<<"query-local-address6 is deprecated and will be removed in a future version. Please use query-local-address for IPv6 addresses as well"<<endl;
640 pdns::parseQueryLocalAddress(::arg()["query-local-address6"]);
641 }
20829585 642
619e8acc
BH
643 // NOW SAFE TO CREATE THREADS!
644 dl->go();
645
536ab56f 646 if(::arg().mustDo("webserver") || ::arg().mustDo("api"))
dea47634
CH
647 webserver.go();
648
dad0736b 649 if(::arg().mustDo("slave") || ::arg().mustDo("master") || !::arg()["forward-notify"].empty())
619e8acc
BH
650 Communicator.go();
651
8c98b341 652 TN->go(); // tcp nameserver launch
952d3fcb 653
ff99a74b 654 unsigned int max_rthreads= ::arg().asNum("receiver-threads", 1);
2bf07cf4 655 g_distributors.resize(max_rthreads);
c2826d2e
RG
656 for(unsigned int n=0; n < max_rthreads; ++n) {
657 std::thread t(qthread, n);
658 t.detach();
659 }
619e8acc 660
c2826d2e 661 std::thread carbonThread(carbonDumpThread); // runs even w/o carbon, might change @ runtime
ba98c6d7 662
6988eae9
PL
663#ifdef HAVE_SYSTEMD
664 /* If we are here, notify systemd that we are ay-ok! This might have some
665 * timing issues with the backend-threads. e.g. if the initial MySQL connection
666 * is slow and times out (leading to process termination through the backend)
667 * We probably have told systemd already that we have started correctly.
668 */
669 sd_notify(0, "READY=1");
670#endif
671
199631c6 672 for(;;) {
673 sleep(1800);
ea272da2 674 try {
675 doSecPoll(false);
676 }
677 catch(...){}
199631c6 678 }
619e8acc 679
e6a9dde5 680 g_log<<Logger::Error<<"Mainthread exiting - should never happen"<<endl;
619e8acc 681}