2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
25 #include "common_startup.hh"
27 #include "secpoll-auth.hh"
29 #include <sys/resource.h>
30 #include "dynhandler.hh"
31 #include "dnsseckeeper.hh"
32 #include "threadname.hh"
34 #include "query-local-address.hh"
39 #include <systemd/sd-daemon.h>
44 #ifdef HAVE_LUA_RECORDS
46 int g_luaRecordExecLimit
;
47 time_t g_luaHealthChecksInterval
{5};
48 time_t g_luaHealthChecksExpireDelay
{3600};
50 typedef Distributor
<DNSPacket
,DNSPacket
,PacketHandler
> DNSDistributor
;
53 StatBag S
; //!< Statistics are gathered across PDNS via the StatBag class S
54 AuthPacketCache PC
; //!< This is the main PacketCache, shared across all threads
56 std::unique_ptr
<DNSProxy
> DP
{nullptr};
57 std::unique_ptr
<DynListener
> dl
{nullptr};
58 CommunicatorClass Communicator
;
59 shared_ptr
<UDPNameserver
> N
;
61 unique_ptr
<TCPNameserver
> TN
;
62 static vector
<DNSDistributor
*> g_distributors
;
63 vector
<std::shared_ptr
<UDPNameserver
> > g_udpReceivers
;
70 void declareArguments()
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")="";
74 ::arg().set("socket-dir",string("Where the controlsocket will live, ")+LOCALSTATEDIR
+"/pdns when unset and not chrooted"
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
;
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";
89 ::arg().set("local-port","The port on which we listen")="53";
90 ::arg().setSwitch("dnsupdate","Enable/Disable DNS update (RFC2136) support. Default is no.")="no";
91 ::arg().setSwitch("write-pid","Write a PID file")="yes";
92 ::arg().set("allow-dnsupdate-from","A global setting to allow DNS updates from these IP ranges.")="127.0.0.0/8,::1";
93 ::arg().setSwitch("send-signed-notify","Send TSIG secured NOTIFY if TSIG key is configured for a domain")="yes";
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";
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";
97 ::arg().setSwitch("log-dns-details","If PDNS should log DNS non-erroneous details")="no";
98 ::arg().setSwitch("log-dns-queries","If PDNS should log all incoming DNS queries")="no";
99 ::arg().set("local-address","Local IP addresses to which we bind")="0.0.0.0, ::";
100 ::arg().set("local-ipv6","DEPRECATED, will be removed, move your IPs to local-address")="";
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";
102 ::arg().setSwitch("non-local-bind", "Enable binding to non-local addresses by using FREEBIND / BINDANY socket options")="no";
103 ::arg().setSwitch("reuseport","Enable higher performance on compliant kernels by using SO_REUSEPORT allowing each receiver thread to open its own socket")="no";
104 ::arg().set("query-local-address","Source IP addresses for sending queries")="0.0.0.0 ::";
105 ::arg().set("query-local-address6","DEPRECATED: Use query-local-address. Source IPv6 address for sending queries")="";
106 ::arg().set("overload-queue-length","Maximum queuelength moving to packetcache only")="0";
107 ::arg().set("max-queue-length","Maximum queuelength before considering situation lost")="5000";
109 ::arg().set("retrieval-threads", "Number of AXFR-retrieval threads for slave operation")="2";
110 ::arg().setSwitch("api", "Enable/disable the REST API (including HTTP listener)")="no";
111 ::arg().set("api-key", "Static pre-shared authentication key for access to the REST API")="";
112 ::arg().setSwitch("default-api-rectify","Default API-RECTIFY value for zones")="yes";
113 ::arg().setSwitch("dname-processing", "If we should support DNAME records")="no";
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");
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!
123 ::arg().set("loglevel","Amount of logging. Higher is more. Do not set below 3")="4";
124 ::arg().set("disable-syslog","Disable logging to syslog, useful when running inside a supervisor that logs stdout")="no";
125 ::arg().set("log-timestamp","Print timestamps in log lines")="yes";
126 ::arg().set("default-soa-name","name to insert in the SOA record if none set in the backend")="a.misconfigured.powerdns.server";
127 ::arg().set("default-soa-mail","mail address to insert in the SOA record if none set in the backend")="";
128 ::arg().set("distributor-threads","Default number of Distributor (backend) threads to start")="3";
129 ::arg().set("signing-threads","Default number of signer threads to start")="3";
130 ::arg().set("receiver-threads","Default number of receiver threads to start")="1";
131 ::arg().set("queue-limit","Maximum number of milliseconds to queue a query")="1500";
132 ::arg().set("resolver","Use this resolver for ALIAS and the internal stub resolver")="no";
133 ::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate")="1232";
135 ::arg().set("config-name","Name of this virtual configuration - will rename the binary image")="";
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";
140 ::arg().set("allow-axfr-ips","Allow zonetransfers only to these subnets")="127.0.0.0/8,::1";
141 ::arg().set("only-notify", "Only send AXFR NOTIFY to these IP addresses or netmasks")="0.0.0.0/0,::/0";
142 ::arg().set("also-notify", "When notifying a domain, also notify these nameservers")="";
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";
144 ::arg().set("slave-cycle-interval","Schedule slave freshness checks once every .. seconds")="60";
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";
151 ::arg().setSwitch("slave","Act as a slave")="no";
152 ::arg().setSwitch("master","Act as a master")="no";
153 ::arg().setSwitch("superslave", "Act as a superslave")="no";
154 ::arg().setSwitch("disable-axfr-rectify","Disable the rectify step during an outgoing AXFR. Only required for regression testing.")="no";
155 ::arg().setSwitch("guardian","Run within a guardian process")="no";
156 ::arg().setSwitch("prevent-self-notification","Don't send notifications to what we think is ourself")="yes";
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";
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";
164 ::arg().set("webserver-password","Password required for accessing the webserver")="";
165 ::arg().set("webserver-allow-from","Webserver/API access is only allowed from these subnets")="127.0.0.1,::1";
166 ::arg().set("webserver-loglevel", "Amount of logging in the webserver (none, normal, detailed)") = "normal";
167 ::arg().set("webserver-max-bodysize","Webserver/API maximum request/response body size in megabytes")="2";
169 ::arg().setSwitch("do-ipv6-additional-processing", "Do AAAA additional processing")="yes";
170 ::arg().setSwitch("query-logging","Hint backends that queries should be logged")="no";
172 ::arg().set("carbon-namespace", "If set overwrites the first part of the carbon string")="pdns";
173 ::arg().set("carbon-ourname", "If set, overrides our reported hostname for carbon stats")="";
174 ::arg().set("carbon-instance", "If set overwrites the the instance name default")="auth";
175 ::arg().set("carbon-server", "If set, send metrics in carbon (graphite) format to this server IP address")="";
176 ::arg().set("carbon-interval", "Number of seconds between carbon (graphite) updates")="30";
178 ::arg().set("cache-ttl","Seconds to store packets in the PacketCache")="20";
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";
181 ::arg().set("soa-minimum-ttl","Default SOA minimum ttl")="3600";
182 ::arg().set("server-id", "Returned when queried for 'id.server' TXT or NSID, defaults to hostname - disabled or custom")="";
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";
186 ::arg().set("default-soa-edit","Default SOA-EDIT value")="";
187 ::arg().set("default-soa-edit-signed","Default SOA-EDIT value for signed zones")="";
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";
191 ::arg().set("trusted-notification-proxy", "IP address of incoming notification proxy")="";
192 ::arg().set("slave-renotify", "If we should send out notifications for slaved updates")="no";
193 ::arg().set("forward-notify", "IP addresses to forward received notifications to regardless of master or slave settings")="";
195 ::arg().set("default-ttl","Seconds a result is valid if not set otherwise")="3600";
196 ::arg().set("max-tcp-connections","Maximum number of TCP connections")="20";
197 ::arg().set("max-tcp-connections-per-client","Maximum number of simultaneous TCP connections per client")="0";
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";
202 ::arg().setSwitch("no-shuffle","Set this to prevent random shuffling of answers - for regression testing")="off";
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")="";
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";
209 ::arg().set("max-signature-cache-entries", "Maximum number of signatures cache entries")="";
210 ::arg().set("max-ent-entries", "Maximum number of empty non-terminals in a zone")="100000";
211 ::arg().set("entropy-source", "If set, read entropy from this file")="/dev/urandom";
213 ::arg().set("lua-prequery-script", "Lua script with prequery handler (DO NOT USE)")="";
214 ::arg().set("lua-dnsupdate-policy-script", "Lua script with DNS update policy handler")="";
216 ::arg().setSwitch("traceback-handler","Enable the traceback handler (Linux only)")="yes";
217 ::arg().setSwitch("direct-dnskey","Fetch DNSKEY, CDS and CDNSKEY RRs from backend during DNSKEY or CDS/CDNSKEY synthesis")="no";
218 ::arg().set("default-ksk-algorithm","Default KSK algorithm")="ecdsa256";
219 ::arg().set("default-ksk-size","Default KSK size (0 means default)")="0";
220 ::arg().set("default-zsk-algorithm","Default ZSK algorithm")="";
221 ::arg().set("default-zsk-size","Default ZSK size (0 means default)")="0";
222 ::arg().set("max-nsec3-iterations","Limit the number of NSEC3 hash iterations")="500"; // RFC5155 10.3
223 ::arg().set("default-publish-cdnskey","Default value for PUBLISH-CDNSKEY")="";
224 ::arg().set("default-publish-cds","Default value for PUBLISH-CDS")="";
226 ::arg().set("include-dir","Include *.conf files from this directory");
227 ::arg().set("security-poll-suffix","Domain name from which to query security update notifications")="secpoll.powerdns.com.";
229 ::arg().setSwitch("expand-alias", "Expand ALIAS records")="no";
230 ::arg().setSwitch("outgoing-axfr-expand-alias", "Expand ALIAS records during outgoing AXFR")="no";
231 ::arg().setSwitch("8bit-dns", "Allow 8bit dns queries")="no";
232 #ifdef HAVE_LUA_RECORDS
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";
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";
236 ::arg().set("lua-health-checks-interval", "LUA records health checks monitoring interval in seconds")="5";
238 ::arg().setSwitch("axfr-lower-serial", "Also AXFR a zone from a master with a lower serial")="no";
240 ::arg().set("lua-axfr-script", "Script to be used to edit incoming AXFRs")="";
241 ::arg().set("xfr-max-received-mbytes", "Maximum number of megabytes received from an incoming XFR")="100";
242 ::arg().set("axfr-fetch-timeout", "Maximum time in seconds for inbound AXFR to start or be idle after starting")="10";
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";
246 ::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file")="0";
248 ::arg().set("rng", "Specify the random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.")="auto";
249 ::arg().setDefaults();
252 static time_t s_start
=time(0);
253 static uint64_t uptimeOfProcess(const std::string
& str
)
255 return time(0) - s_start
;
258 static uint64_t getSysUserTimeMsec(const std::string
& str
)
261 getrusage(RUSAGE_SELF
, &ru
);
263 if(str
=="sys-msec") {
264 return (ru
.ru_stime
.tv_sec
*1000ULL + ru
.ru_stime
.tv_usec
/1000);
267 return (ru
.ru_utime
.tv_sec
*1000ULL + ru
.ru_utime
.tv_usec
/1000);
271 static uint64_t getTCPConnectionCount(const std::string
& str
)
273 return TN
->numTCPConnections();
276 static uint64_t getQCount(const std::string
& str
)
280 for(const auto& d
: g_distributors
) {
283 totcount
+= d
->getQueueSize(); // this does locking and other things, so don't get smart
287 catch(std::exception
& e
)
289 g_log
<<Logger::Error
<<"Had error retrieving queue sizes: "<<e
.what()<<endl
;
292 catch(PDNSException
& e
)
294 g_log
<<Logger::Error
<<"Had error retrieving queue sizes: "<<e
.reason
<<endl
;
298 static uint64_t getLatency(const std::string
& str
)
303 void declareStats(void)
305 S
.declare("udp-queries","Number of UDP queries received");
306 S
.declare("udp-do-queries","Number of UDP queries received with DO bit");
307 S
.declare("udp-answers","Number of answers sent out over UDP");
308 S
.declare("udp-answers-bytes","Total size of answers sent out over UDP");
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");
312 S
.declare("udp4-answers","Number of IPv4 answers sent out over UDP");
313 S
.declare("udp4-queries","Number of IPv4 UDP queries received");
314 S
.declare("udp6-answers","Number of IPv6 answers sent out over UDP");
315 S
.declare("udp6-queries","Number of IPv6 UDP queries received");
316 S
.declare("overload-drops","Queries dropped because backends overloaded");
318 S
.declare("rd-queries", "Number of recursion desired questions");
319 S
.declare("recursion-unanswered", "Number of packets unanswered by configured recursor");
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");
323 S
.declare("signatures", "Number of DNSSEC signatures made");
324 S
.declare("tcp-queries","Number of TCP queries received");
325 S
.declare("tcp-answers","Number of answers sent out over TCP");
326 S
.declare("tcp-answers-bytes","Total size of answers sent out over TCP");
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");
330 S
.declare("tcp4-queries","Number of IPv4 TCP queries received");
331 S
.declare("tcp4-answers","Number of IPv4 answers sent out over TCP");
333 S
.declare("tcp6-queries","Number of IPv6 TCP queries received");
334 S
.declare("tcp6-answers","Number of IPv6 answers sent out over TCP");
336 S
.declare("open-tcp-connections","Number of currently open TCP connections", getTCPConnectionCount
);;
338 S
.declare("qsize-q","Number of questions waiting for database attention", getQCount
);
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.");
345 S
.declare("incoming-notifications", "NOTIFY packets received.");
347 S
.declare("uptime", "Uptime of process in seconds", uptimeOfProcess
);
348 S
.declare("real-memory-usage", "Actual unique use of memory in bytes (approx)", getRealMemoryUsage
);
349 S
.declare("special-memory-usage", "Actual unique use of memory in bytes (approx)", getSpecialMemoryUsage
);
350 S
.declare("fd-usage", "Number of open filedescriptors", getOpenFileDescriptors
);
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
);
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
);
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
);
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
);
370 S
.declare("servfail-packets","Number of times a server-failed packet was sent out");
371 S
.declare("latency","Average number of microseconds needed to answer a question", getLatency
);
372 S
.declare("timedout-packets","Number of packets which weren't answered within timeout set");
373 S
.declare("security-status", "Security status based on regular polling");
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");
379 S
.declareRing("logmessages","Log Messages");
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");
385 int isGuarded(char **argv
)
387 char *p
=strstr(argv
[0],"-instance");
392 static void sendout(std::unique_ptr
<DNSPacket
>& a
)
399 int diff
=a
->d_dt
.udiff();
400 avg_latency
=(int)(0.999*avg_latency
+0.001*diff
);
403 //! The qthread receives questions over the internet via the Nameserver class, and hands them to the Distributor for further processing
404 static void qthread(unsigned int num
)
407 setThreadName("pdns/receiver");
409 g_distributors
[num
] = DNSDistributor::Create(::arg().asNum("distributor-threads", 1));
410 DNSDistributor
* distributor
= g_distributors
[num
]; // the big dispatcher!
411 DNSPacket
question(true);
412 DNSPacket
cached(false);
414 AtomicCounter
&numreceived
=*S
.getPointer("udp-queries");
415 AtomicCounter
&numreceiveddo
=*S
.getPointer("udp-do-queries");
417 AtomicCounter
&numreceived4
=*S
.getPointer("udp4-queries");
419 AtomicCounter
&numreceived6
=*S
.getPointer("udp6-queries");
420 AtomicCounter
&overloadDrops
=*S
.getPointer("overload-drops");
423 bool logDNSQueries
= ::arg().mustDo("log-dns-queries");
424 shared_ptr
<UDPNameserver
> NS
;
426 buffer
.resize(DNSPacket::s_udpTruncationThreshold
);
428 // If we have SO_REUSEPORT then create a new port for all receiver threads
429 // other than the first one.
430 if(N
->canReusePort() ) {
431 NS
= g_udpReceivers
[num
];
440 if(!NS
->receive(question
, buffer
)) { // receive a packet inline
441 continue; // packet was broken, try again
446 if(question
.d_remote
.getSocklen()==sizeof(sockaddr_in
))
451 if(question
.d_dnssecOk
)
457 S
.ringAccount("queries", question
.qdomain
, question
.qtype
);
458 S
.ringAccount("remotes", question
.d_remote
);
461 if(question
.hasEDNSSubnet())
462 remote
= question
.getRemote().toString() + "<-" + question
.getRealRemote().toString();
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
<<")";
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?
475 g_log
<<": packetcache HIT"<<endl
;
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
;
482 cached
.commitD(); // commit d to the packet inlined
483 NS
->send(cached
); // answer it then inlined
484 diff
=question
.d_dt
.udiff();
485 avg_latency
=(int)(0.999*avg_latency
+0.001*diff
); // 'EWMA'
490 if(distributor
->isOverloaded()) {
492 g_log
<<": Dropped query, backends are overloaded"<<endl
;
499 g_log
<<": packetcache MISS"<<endl
;
506 distributor
->question(question
, &sendout
); // otherwise, give to the distributor
508 catch(DistributorFatal
& df
) { // when this happens, we have leaked loads of memory. Bailing out time.
513 catch(PDNSException
& pe
)
515 g_log
<<Logger::Error
<<"Fatal error in question thread: "<<pe
.reason
<<endl
;
519 static void dummyThread()
523 static void triggerLoadOfLibraries()
525 std::thread
dummy(dummyThread
);
534 if(!::arg()["setgid"].empty())
535 newgid
= strToGID(::arg()["setgid"]);
537 if(!::arg()["setuid"].empty())
538 newuid
= strToUID(::arg()["setuid"]);
540 g_anyToTcp
= ::arg().mustDo("any-to-tcp");
541 g_8bitDNS
= ::arg().mustDo("8bit-dns");
542 #ifdef HAVE_LUA_RECORDS
543 g_doLuaRecord
= ::arg().mustDo("enable-lua-records");
544 g_LuaRecordSharedState
= (::arg()["enable-lua-records"] == "shared");
545 g_luaRecordExecLimit
= ::arg().asNum("lua-records-exec-limit");
546 g_luaHealthChecksInterval
= ::arg().asNum("lua-health-checks-interval");
547 g_luaHealthChecksExpireDelay
= ::arg().asNum("lua-health-checks-expire-delay");
550 DNSPacket::s_udpTruncationThreshold
= std::max(512, ::arg().asNum("udp-truncation-threshold"));
551 DNSPacket::s_doEDNSSubnetProcessing
= ::arg().mustDo("edns-subnet-processing");
553 PC
.setTTL(::arg().asNum("cache-ttl"));
554 PC
.setMaxEntries(::arg().asNum("max-packet-cache-entries"));
555 QC
.setMaxEntries(::arg().asNum("max-cache-entries"));
556 DNSSECKeeper::setMaxEntries(::arg().asNum("max-cache-entries"));
558 if (!PC
.enabled() && ::arg().mustDo("log-dns-queries")) {
559 g_log
<<Logger::Warning
<<"Packet cache disabled, logging queries without HIT/MISS"<<endl
;
562 stubParseResolveConf();
564 if(!::arg()["chroot"].empty()) {
567 ns
= getenv("NOTIFY_SOCKET");
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
;
573 triggerLoadOfLibraries();
574 if(::arg().mustDo("master") || ::arg().mustDo("slave"))
575 gethostbyname("a.root-servers.net"); // this forces all lookup libraries to be loaded
576 Utility::dropGroupPrivs(newuid
, newgid
);
577 if(chroot(::arg()["chroot"].c_str())<0 || chdir("/")<0) {
578 g_log
<<Logger::Error
<<"Unable to chroot to '"+::arg()["chroot"]+"': "<<stringerror()<<", exiting"<<endl
;
582 g_log
<<Logger::Error
<<"Chrooted to '"<<::arg()["chroot"]<<"'"<<endl
;
584 Utility::dropGroupPrivs(newuid
, newgid
);
587 AuthWebServer webserver
;
588 Utility::dropUserPrivs(newuid
);
590 if(::arg().mustDo("resolver")){
591 DP
=std::unique_ptr
<DNSProxy
>(new DNSProxy(::arg()["resolver"]));
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"}) {
606 if (::arg()["default-"+algotype
+"-algorithm"].empty())
608 algo
= DNSSECKeeper::shorthand2algorithm(::arg()["default-"+algotype
+"-algorithm"]);
609 size
= ::arg().asNum("default-"+algotype
+"-size");
611 g_log
<<Logger::Error
<<"Error: default-"<<algotype
<<"-algorithm set to unknown algorithm: "<<::arg()["default-"+algotype
+"-algorithm"]<<endl
;
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
;
618 if (algotype
== "ksk") {
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
;
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
;
637 pdns::parseQueryLocalAddress(::arg()["query-local-address"]);
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"]);
643 // NOW SAFE TO CREATE THREADS!
646 if(::arg().mustDo("webserver") || ::arg().mustDo("api"))
649 if(::arg().mustDo("slave") || ::arg().mustDo("master") || !::arg()["forward-notify"].empty())
652 TN
->go(); // tcp nameserver launch
654 unsigned int max_rthreads
= ::arg().asNum("receiver-threads", 1);
655 g_distributors
.resize(max_rthreads
);
656 for(unsigned int n
=0; n
< max_rthreads
; ++n
) {
657 std::thread
t(qthread
, n
);
661 std::thread
carbonThread(carbonDumpThread
); // runs even w/o carbon, might change @ runtime
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.
669 sd_notify(0, "READY=1");
680 g_log
<<Logger::Error
<<"Mainthread exiting - should never happen"<<endl
;