]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/receiver.cc
remove fancy-record options
[thirdparty/pdns.git] / pdns / receiver.cc
CommitLineData
12c86877
BH
1/*
2 PowerDNS Versatile Database Driven Nameserver
ce19a815 3 Copyright (C) 2002 - 2013 PowerDNS.COM BV
12c86877
BH
4
5 This program is free software; you can redistribute it and/or modify
22dc646a
BH
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
ea44d9d3 8
f782fe38
MH
9 Additionally, the license of this program contains a special
10 exception which allows to distribute the program in binary form when
11 it is linked against OpenSSL.
12c86877
BH
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
06bd9ccf 20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12c86877 21*/
e8d78143 22#include "packetcache.hh"
da44c9ea 23
12c86877
BH
24#include <cstdio>
25#include <signal.h>
26#include <cstring>
27#include <cstdlib>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32#include <iostream>
33#include <string>
34#include <sys/stat.h>
35#include <unistd.h>
36#include <sys/time.h>
37#include <sys/types.h>
38#include <sys/wait.h>
39#include <errno.h>
40#include <pthread.h>
41#include <unistd.h>
42#include <sys/mman.h>
43#include <fcntl.h>
44#include <fstream>
040712e0 45#include <boost/algorithm/string.hpp>
12c86877
BH
46
47#include "config.h"
48#include "dns.hh"
49#include "dnsbackend.hh"
50#include "ueberbackend.hh"
51#include "dnspacket.hh"
52#include "nameserver.hh"
53#include "distributor.hh"
54#include "logger.hh"
55#include "arguments.hh"
56#include "packethandler.hh"
57#include "statbag.hh"
58#include "tcpreceiver.hh"
12c86877
BH
59#include "misc.hh"
60#include "dynlistener.hh"
61#include "dynhandler.hh"
62#include "communicator.hh"
63#include "dnsproxy.hh"
731f58b8 64#include "utility.hh"
12c86877 65#include "common_startup.hh"
02116dff 66#include "dnsrecords.hh"
ba1a571d 67#include "version.hh"
12c86877
BH
68
69time_t s_starttime;
70
71string s_programname="pdns"; // used in packethandler.cc
72
c4ac5865 73const char *funnytext=
12c86877
BH
74"*****************************************************************************\n"\
75"Ok, you just ran pdns_server through 'strings' hoping to find funny messages.\n"\
76"Well, you found one. \n"\
77"Two ions are flying through their particle accelerator, says the one to the\n"
78"other 'I think I've lost an electron!' \n"\
79"So the other one says, 'Are you sure?'. 'YEAH! I'M POSITIVE!'\n"\
80" the pdns crew - pdns@powerdns.com\n"
81"*****************************************************************************\n";
82
83
84// start (sys)logging
85
86/** \var Logger L
87\brief All logging is done via L, a Logger instance
88*/
89
90
91/**
92\file receiver.cc
93\brief The main loop of powerdns
94
95This file is where it all happens - main is here, as are the two pivotal threads qthread() and athread()
96*/
97
98void daemonize(void)
99{
100 if(fork())
101 exit(0); // bye bye
102
103 setsid();
104
dd8b6bd1 105 int i=open("/dev/null",O_RDWR); /* open stdin */
11a2091b
BH
106 if(i < 0)
107 L<<Logger::Critical<<"Unable to open /dev/null: "<<stringerror()<<endl;
108 else {
109 dup2(i,0); /* stdin */
110 dup2(i,1); /* stderr */
111 dup2(i,2); /* stderr */
112 close(i);
113 }
12c86877
BH
114}
115
12c86877 116static int cpid;
12c86877
BH
117static void takedown(int i)
118{
119 if(cpid) {
120 L<<Logger::Error<<"Guardian is killed, taking down children with us"<<endl;
5c663d99
IM
121 } else {
122 L<<Logger::Error<<"PDNS instance is going down, taking children with us"<<endl;
12c86877 123 }
5c663d99
IM
124 kill(-getpgid(cpid),SIGKILL);
125 exit(0);
12c86877
BH
126}
127
128static void writePid(void)
129{
e8d78143 130 string fname=::arg()["socket-dir"]+"/"+s_programname+".pid";
12c86877
BH
131 ofstream of(fname.c_str());
132 if(of)
133 of<<getpid()<<endl;
134 else
135 L<<Logger::Error<<"Requested to write pid for "<<getpid()<<" to "<<fname<<" failed: "<<strerror(errno)<<endl;
136}
137
aced0e6c
BH
138int g_fd1[2], g_fd2[2];
139FILE *g_fp;
140pthread_mutex_t g_guardian_lock = PTHREAD_MUTEX_INITIALIZER;
12c86877 141
64bcb6be
RA
142// The next two methods are not in dynhandler.cc because they use a few items declared in this file.
143static string DLCycleHandler(const vector<string>&parts, pid_t ppid)
144{
ee443da2 145 kill(-getpgid(cpid), SIGKILL);
64bcb6be
RA
146 sleep(1);
147 return "ok";
148}
149
12c86877
BH
150static string DLRestHandler(const vector<string>&parts, pid_t ppid)
151{
152 string line;
153
154 for(vector<string>::const_iterator i=parts.begin();i!=parts.end();++i) {
155 if(i!=parts.begin())
156 line.append(1,' ');
157 line.append(*i);
158 }
159 line.append(1,'\n');
160
aced0e6c
BH
161 Lock l(&g_guardian_lock);
162
163 try {
164 writen2(g_fd1[1],line.c_str(),line.size()+1);
165 }
3f81d239 166 catch(PDNSException &ae) {
aced0e6c
BH
167 return "Error communicating with instance: "+ae.reason;
168 }
12c86877 169 char mesg[512];
20ca8e7d 170 string response;
aced0e6c 171 while(fgets(mesg,sizeof(mesg),g_fp)) {
188b28bd 172 if(*mesg=='\0')
20ca8e7d
BH
173 break;
174 response+=mesg;
175 }
040712e0 176 boost::trim_right(response);
20ca8e7d 177 return response;
12c86877
BH
178}
179
64bcb6be 180
12c86877
BH
181
182static int guardian(int argc, char **argv)
183{
184 if(isGuarded(argv))
185 return 0;
186
187 int infd=0, outfd=1;
188
189 DynListener dlg(s_programname);
3c90953e
PD
190 dlg.registerFunc("QUIT",&DLQuitHandler, "quit daemon");
191 dlg.registerFunc("CYCLE",&DLCycleHandler, "restart instance");
192 dlg.registerFunc("PING",&DLPingHandler, "ping guardian");
193 dlg.registerFunc("STATUS",&DLStatusHandler, "get instance status from guardian");
12c86877
BH
194 dlg.registerRestFunc(&DLRestHandler);
195 dlg.go();
196 string progname=argv[0];
197
198 bool first=true;
12c86877 199
aced0e6c
BH
200 pthread_mutex_lock(&g_guardian_lock);
201
12c86877
BH
202 for(;;) {
203 int pid;
204 setStatus("Launching child");
aced0e6c
BH
205
206 if(pipe(g_fd1)<0 || pipe(g_fd2)<0) {
12c86877
BH
207 L<<Logger::Critical<<"Unable to open pipe for coprocess: "<<strerror(errno)<<endl;
208 exit(1);
209 }
210
aced0e6c
BH
211 if(!(g_fp=fdopen(g_fd2[0],"r"))) {
212 L<<Logger::Critical<<"Unable to associate a file pointer with pipe: "<<stringerror()<<endl;
213 exit(1);
214 }
215 setbuf(g_fp,0); // no buffering please, confuses select
216
12c86877 217 if(!(pid=fork())) { // child
12c86877
BH
218 signal(SIGHUP, SIG_DFL);
219 signal(SIGUSR1, SIG_DFL);
220 signal(SIGUSR2, SIG_DFL);
221
ee443da2
IM
222 // Set different pgrp for this child,
223 // so we could kill all of it's children
224 // with one kill call
225 setpgid(getpid(), 0);
226
12c86877
BH
227 char **const newargv=new char*[argc+2];
228 int n;
229
e8d78143 230 if(::arg()["config-name"]!="") {
4957a608
BH
231 progname+="-"+::arg()["config-name"];
232 L<<Logger::Error<<"Virtual configuration name: "<<::arg()["config-name"]<<endl;
12c86877
BH
233 }
234
235 newargv[0]=strdup(const_cast<char *>((progname+"-instance").c_str()));
236 for(n=1;n<argc;n++) {
4957a608 237 newargv[n]=argv[n];
12c86877
BH
238 }
239 newargv[n]=0;
240
241 L<<Logger::Error<<"Guardian is launching an instance"<<endl;
aced0e6c
BH
242 close(g_fd1[1]);
243 fclose(g_fp); // this closes g_fd2[0] for us
12c86877 244
aced0e6c 245 if(g_fd1[0]!= infd) {
4957a608
BH
246 dup2(g_fd1[0], infd);
247 close(g_fd1[0]);
12c86877
BH
248 }
249
aced0e6c 250 if(g_fd2[1]!= outfd) {
4957a608
BH
251 dup2(g_fd2[1], outfd);
252 close(g_fd2[1]);
12c86877 253 }
c1663439 254 if(execvp(argv[0], newargv)<0) {
4957a608
BH
255 L<<Logger::Error<<"Unable to execvp '"<<argv[0]<<"': "<<strerror(errno)<<endl;
256 char **p=newargv;
257 while(*p)
258 L<<Logger::Error<<*p++<<endl;
12c86877 259
4957a608 260 exit(1);
12c86877 261 }
c1663439 262 L<<Logger::Error<<"execvp returned!!"<<endl;
12c86877
BH
263 // never reached
264 }
265 else if(pid>0) { // parent
aced0e6c
BH
266 close(g_fd1[0]);
267 close(g_fd2[1]);
12c86877
BH
268
269 if(first) {
4957a608 270 first=false;
4957a608
BH
271 signal(SIGHUP, SIG_IGN);
272 signal(SIGUSR1, SIG_IGN);
273 signal(SIGUSR2, SIG_IGN);
12c86877 274
4957a608 275 writePid();
12c86877 276 }
aced0e6c 277 pthread_mutex_unlock(&g_guardian_lock);
12c86877
BH
278 int status;
279 cpid=pid;
280 for(;;) {
4957a608
BH
281 int ret=waitpid(pid,&status,WNOHANG);
282
283 if(ret<0) {
284 L<<Logger::Error<<"In guardian loop, waitpid returned error: "<<strerror(errno)<<endl;
285 L<<Logger::Error<<"Dying"<<endl;
286 exit(1);
287 }
288 else if(ret) // something exited
289 break;
290 else { // child is alive
291 // execute some kind of ping here
292 if(DLQuitPlease())
293 takedown(1); // needs a parameter..
294 setStatus("Child running on pid "+itoa(pid));
295 sleep(1);
296 }
12c86877 297 }
aced0e6c
BH
298
299 pthread_mutex_lock(&g_guardian_lock);
300 close(g_fd1[1]);
301 fclose(g_fp);
302 g_fp=0;
12c86877
BH
303
304 if(WIFEXITED(status)) {
4957a608
BH
305 int ret=WEXITSTATUS(status);
306
307 if(ret==99) {
308 L<<Logger::Error<<"Child requested a stop, exiting"<<endl;
309 exit(1);
310 }
311 setStatus("Child died with code "+itoa(ret));
312 L<<Logger::Error<<"Our pdns instance exited with code "<<ret<<endl;
313 L<<Logger::Error<<"Respawning"<<endl;
314
6f8e772b 315 goto respawn;
12c86877
BH
316 }
317 if(WIFSIGNALED(status)) {
4957a608
BH
318 int sig=WTERMSIG(status);
319 setStatus("Child died because of signal "+itoa(sig));
320 L<<Logger::Error<<"Our pdns instance ("<<pid<<") exited after signal "<<sig<<endl;
12c86877 321#ifdef WCOREDUMP
4957a608
BH
322 if(WCOREDUMP(status))
323 L<<Logger::Error<<"Dumped core"<<endl;
12c86877
BH
324#endif
325
4957a608 326 L<<Logger::Error<<"Respawning"<<endl;
6f8e772b 327 goto respawn;
12c86877
BH
328 }
329 L<<Logger::Error<<"No clue what happened! Respawning"<<endl;
6f8e772b
IM
330respawn:
331 if (cpid) {
332 L<<Logger::Error<<"Cleaning up any remaining children with PGRP "<<cpid<<endl;
333 kill(-cpid, SIGKILL);
334 }
335 sleep(1);
12c86877
BH
336 }
337 else {
338 L<<Logger::Error<<"Unable to fork: "<<strerror(errno)<<endl;
339 exit(1);
340 }
341 }
342}
343
344static void UNIX_declareArguments()
345{
65efcdbc 346 ::arg().set("config-dir","Location of configuration directory (pdns.conf)")=SYSCONFDIR;
e8d78143
BH
347 ::arg().set("config-name","Name of this virtual configuration - will rename the binary image")="";
348 ::arg().set("socket-dir","Where the controlsocket will live")=LOCALSTATEDIR;
0949b8ae 349 ::arg().set("module-dir","Default directory for modules")=PKGLIBDIR;
e8d78143
BH
350 ::arg().set("chroot","If set, chroot to this directory for more security")="";
351 ::arg().set("logging-facility","Log under a specific facility")="";
352 ::arg().set("daemon","Operate as a daemon")="no";
12c86877
BH
353}
354
355static void loadModules()
356{
e8d78143 357 if(!::arg()["load-modules"].empty()) {
12c86877
BH
358 vector<string>modules;
359
e8d78143 360 stringtok(modules,::arg()["load-modules"],",");
12c86877
BH
361
362 for(vector<string>::const_iterator i=modules.begin();i!=modules.end();++i) {
363 bool res;
364 const string &module=*i;
365
366 if(module.find(".")==string::npos)
4957a608 367 res=UeberBackend::loadmodule(::arg()["module-dir"]+"/lib"+module+"backend.so");
12c86877 368 else if(module[0]=='/' || (module[0]=='.' && module[1]=='/') || (module[0]=='.' && module[1]=='.')) // absolute or current path
4957a608 369 res=UeberBackend::loadmodule(module);
12c86877 370 else
4957a608 371 res=UeberBackend::loadmodule(::arg()["module-dir"]+"/"+module);
12c86877
BH
372
373 if(res==false) {
4957a608
BH
374 L<<Logger::Error<<"receiver unable to load module "<<module<<endl;
375 exit(1);
12c86877
BH
376 }
377 }
378 }
379}
380
12c86877
BH
381#ifdef __linux__
382#include <execinfo.h>
383static void tbhandler(int num)
384{
385 L<<Logger::Critical<<"Got a signal "<<num<<", attempting to print trace: "<<endl;
386 void *array[20]; //only care about last 17 functions (3 taken with tracing support)
387 size_t size;
388 char **strings;
389 size_t i;
390
391 size = backtrace (array, 20);
392 strings = backtrace_symbols (array, size); //Need -rdynamic gcc (linker) flag for this to work
393
394 for (i = 0; i < size; i++) //skip useless functions
395 L<<Logger::Error<<strings[i]<<endl;
396
397
398 signal(SIGABRT, SIG_DFL);
399 abort();//hopefully will give core
400
401}
402#endif
403
404//! The main function of pdns, the pdns process
405int main(int argc, char **argv)
ba1a571d 406{
3e135495 407 versionSetProduct(ProductAuthoritative);
02116dff
BH
408 reportAllTypes(); // init MOADNSParser
409
1a3bbc1b
IM
410 // Even if PDNS is not deamonized it must be
411 // the leader of the process group
412 setpgid(getpid(), 0);
413
5c663d99
IM
414 // Initialize child PID var. It will remain 0 for pdns instance.
415 // It will have child value in the PDNS guardian instance.
416 // cpid is needed to properly terminate PDNS process in
417 // takedown function, and in Guardian's Cycle handler.
418 cpid=0;
419
420 signal(SIGINT, takedown);
421 signal(SIGTERM, takedown);
422
12c86877
BH
423 s_programname="pdns";
424 s_starttime=time(0);
425
426#ifdef __linux__
427 signal(SIGSEGV,tbhandler);
428 signal(SIGFPE,tbhandler);
429 signal(SIGABRT,tbhandler);
430 signal(SIGILL,tbhandler);
431#endif
432
35b9a6ff
PD
433#if __GNUC__ >= 3
434 std::ios_base::sync_with_stdio(false);
435#endif
12c86877
BH
436
437 L.toConsole(Logger::Warning);
438 try {
439 declareArguments();
440 UNIX_declareArguments();
c4db07b7 441
e8d78143 442 ::arg().laxParse(argc,argv); // do a lax parse
12c86877 443
c4db07b7 444 if(::arg().mustDo("version")) {
ba1a571d 445 showProductVersion();
3613a51c 446 showBuildConfiguration();
c4db07b7
PD
447 exit(99);
448 }
449
e8d78143
BH
450 if(::arg()["config-name"]!="")
451 s_programname+="-"+::arg()["config-name"];
12c86877
BH
452
453 (void)theL(s_programname);
454
e8d78143 455 string configname=::arg()["config-dir"]+"/"+s_programname+".conf";
12c86877
BH
456 cleanSlashes(configname);
457
e8d78143
BH
458 if(!::arg().mustDo("config") && !::arg().mustDo("no-config")) // "config" == print a configuration file
459 ::arg().laxFile(configname.c_str());
12c86877 460
e8d78143
BH
461 ::arg().laxParse(argc,argv); // reparse so the commandline still wins
462 if(!::arg()["logging-facility"].empty()) {
f8499e52
BH
463 int val=logFacilityToLOG(::arg().asNum("logging-facility") );
464 if(val >= 0)
465 theL().setFacility(val);
6e2514e4 466 else
4957a608 467 L<<Logger::Error<<"Unknown logging facility "<<::arg().asNum("logging-facility") <<endl;
12c86877
BH
468 }
469
e8d78143
BH
470 L.setLoglevel((Logger::Urgency)(::arg().asNum("loglevel")));
471 L.toConsole((Logger::Urgency)(::arg().asNum("loglevel")));
12c86877 472
e8d78143
BH
473 if(::arg().mustDo("help") || ::arg().mustDo("config")) {
474 ::arg().set("daemon")="no";
475 ::arg().set("guardian")="no";
12c86877
BH
476 }
477
e8d78143
BH
478 if(::arg().mustDo("guardian") && !isGuarded(argv)) {
479 if(::arg().mustDo("daemon")) {
4957a608
BH
480 L.toConsole(Logger::Critical);
481 daemonize();
12c86877
BH
482 }
483 guardian(argc, argv);
484 // never get here, guardian will reinvoke process
485 cerr<<"Um, we did get here!"<<endl;
486 }
45fdd612 487
12c86877
BH
488
489 // we really need to do work - either standalone or as an instance
5488e86b
PD
490
491#ifdef __linux__
492 if(!::arg().mustDo("traceback-handler")) {
493 L<<Logger::Warning<<"Disabling traceback handler"<<endl;
494 signal(SIGSEGV,SIG_DFL);
495 signal(SIGFPE,SIG_DFL);
496 signal(SIGABRT,SIG_DFL);
497 signal(SIGILL,SIG_DFL);
498 }
499#endif
500
a28a204a
BH
501 seedRandom(::arg()["entropy-source"]);
502
12c86877 503 loadModules();
e8d78143 504 BackendMakers().launch(::arg()["launch"]); // vrooooom!
f4137d84 505
e8d78143 506 if(!::arg().getCommands().empty()) {
49daa3cd
BH
507 cerr<<"Fatal: non-option on the command line, perhaps a '--setting=123' statement missed the '='?"<<endl;
508 exit(99);
509 }
f4137d84 510
e8d78143 511 if(::arg().mustDo("help")) {
ff5ba4f9
WA
512 cout<<"syntax:"<<endl<<endl;
513 cout<<::arg().helpstring(::arg()["help"])<<endl;
514 exit(0);
12c86877
BH
515 }
516
e8d78143
BH
517 if(::arg().mustDo("config")) {
518 cout<<::arg().configstring()<<endl;
12c86877
BH
519 exit(99);
520 }
521
e8d78143 522 if(::arg().mustDo("list-modules")) {
12c86877
BH
523 vector<string>modules=BackendMakers().getModules();
524 cerr<<"Modules available:"<<endl;
525 for(vector<string>::const_iterator i=modules.begin();i!=modules.end();++i)
4957a608 526 cout<<*i<<endl;
12c86877
BH
527
528 exit(99);
529 }
da44c9ea 530
e8d78143 531 if(!::arg().asNum("local-port")) {
da44c9ea
BH
532 L<<Logger::Error<<"Unable to launch, binding to no port or port 0 makes no sense"<<endl;
533 exit(99); // this isn't going to fix itself either
534 }
12c86877
BH
535 if(!BackendMakers().numLauncheable()) {
536 L<<Logger::Error<<"Unable to launch, no backends configured for querying"<<endl;
da44c9ea 537 exit(99); // this isn't going to fix itself either
12c86877 538 }
e8d78143 539 if(::arg().mustDo("daemon")) {
12c86877
BH
540 L.toConsole(Logger::None);
541 if(!isGuarded(argv))
4957a608 542 daemonize();
12c86877
BH
543 }
544
545 if(isGuarded(argv)) {
546 L<<Logger::Warning<<"This is a guarded instance of pdns"<<endl;
547 dl=new DynListener; // listens on stdin
548 }
549 else {
550 L<<Logger::Warning<<"This is a standalone pdns"<<endl;
551
e8d78143 552 if(::arg().mustDo("control-console"))
4957a608 553 dl=new DynListener();
12c86877 554 else
4957a608 555 dl=new DynListener(s_programname);
12c86877
BH
556
557 writePid();
558 }
3c90953e
PD
559 DynListener::registerFunc("SHOW",&DLShowHandler, "show a specific statistic or * to get a list", "<statistic>");
560 DynListener::registerFunc("RPING",&DLPingHandler, "ping instance");
561 DynListener::registerFunc("QUIT",&DLRQuitHandler, "quit daemon");
562 DynListener::registerFunc("UPTIME",&DLUptimeHandler, "get instance uptime");
563 DynListener::registerFunc("NOTIFY-HOST",&DLNotifyHostHandler, "notify host for specific domain", "<domain> <host>");
564 DynListener::registerFunc("NOTIFY",&DLNotifyHandler, "queue a notification", "<domain>");
565 DynListener::registerFunc("RELOAD",&DLReloadHandler, "reload all zones");
566 DynListener::registerFunc("REDISCOVER",&DLRediscoverHandler, "discover any new zones");
567 DynListener::registerFunc("VERSION",&DLVersionHandler, "get instance version");
568 DynListener::registerFunc("PURGE",&DLPurgeHandler, "purge entries from packet cache", "[<record>]");
569 DynListener::registerFunc("CCOUNTS",&DLCCHandler, "get cache statistics");
ba7244a5 570 DynListener::registerFunc("QTYPES", &DLQTypesHandler, "get QType statistics");
93698ef3
PD
571 DynListener::registerFunc("RESPSIZES", &DLRSizesHandler, "get histogram of response sizes");
572 DynListener::registerFunc("REMOTES", &DLRemotesHandler, "get top remotes");
3c90953e
PD
573 DynListener::registerFunc("SET",&DLSettingsHandler, "set config variables", "<var> <value>");
574 DynListener::registerFunc("RETRIEVE",&DLNotifyRetrieveHandler, "retrieve slave domain", "<domain>");
64bcb6be 575 DynListener::registerFunc("CURRENT-CONFIG",&DLCurrentConfigHandler, "Retrieve the current configuration");
cd76677f 576 DynListener::registerFunc("LIST-ZONES",&DLListZones, "show list of zones", "[master|slave|native]");
040712e0
BH
577
578 if(!::arg()["tcp-control-address"].empty()) {
579 DynListener* dlTCP=new DynListener(ComboAddress(::arg()["tcp-control-address"], ::arg().asNum("tcp-control-port")));
580 dlTCP->go();
581 }
12c86877 582
12c86877 583 // reparse, with error checking
e8d78143
BH
584 if(!::arg().mustDo("no-config"))
585 ::arg().file(configname.c_str());
586 ::arg().parse(argc,argv);
5bc3abe7
PD
587
588 if(::arg()["server-id"].empty()) {
589 char tmp[128];
590 gethostname(tmp, sizeof(tmp)-1);
591 ::arg().set("server-id")=tmp;
592 }
593
12c86877
BH
594 UeberBackend::go();
595 N=new UDPNameserver; // this fails when we are not root, throws exception
596
e8d78143 597 if(!::arg().mustDo("disable-tcp"))
12c86877
BH
598 TN=new TCPNameserver;
599 }
600 catch(const ArgException &A) {
601 L<<Logger::Error<<"Fatal error: "<<A.reason<<endl;
602 exit(1);
603 }
604
605 declareStats();
606 DLOG(L<<Logger::Warning<<"Verbose logging in effect"<<endl);
12c86877 607
ba1a571d 608 showProductVersion();
12c86877
BH
609
610 try {
12c86877
BH
611 mainthread();
612 }
3f81d239 613 catch(PDNSException &AE) {
e8d78143 614 if(!::arg().mustDo("daemon"))
12c86877
BH
615 cerr<<"Exiting because: "<<AE.reason<<endl;
616 L<<Logger::Error<<"Exiting because: "<<AE.reason<<endl;
617 }
adc10f99 618 catch(std::exception &e) {
e8d78143 619 if(!::arg().mustDo("daemon"))
12c86877
BH
620 cerr<<"Exiting because of STL error: "<<e.what()<<endl;
621 L<<Logger::Error<<"Exiting because of STL error: "<<e.what()<<endl;
622 }
623 catch(...) {
624 cerr<<"Uncaught exception of unknown type - sorry"<<endl;
625 }
626
627 exit(1);
628
629}
630
631