]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth: merge "main" code into new auth-main.(cc|hh)
authorChris Hofstaedtler <chris.hofstaedtler@deduktiva.com>
Wed, 8 Dec 2021 19:46:39 +0000 (20:46 +0100)
committerChris Hofstaedtler <chris.hofstaedtler@deduktiva.com>
Tue, 2 Aug 2022 13:48:10 +0000 (15:48 +0200)
Merge common_startup.cc and receiver.cc into auth-main.cc, and
rename common_startup.hh into receiver.hh.
This is a very minimal merge with no cleanup. Its intention is to
make understanding the startup code path easier, by avoiding having
to look at two compilation units to determine the exact order.

14 files changed:
.not-formatted
configure.ac
pdns/Makefile.am
pdns/auth-carbon.cc
pdns/auth-main.cc [moved from pdns/common_startup.cc with 66% similarity]
pdns/auth-main.hh [moved from pdns/common_startup.hh with 100% similarity]
pdns/dynhandler.cc
pdns/lua-record.cc
pdns/nameserver.cc
pdns/packethandler.cc
pdns/receiver.cc [deleted file]
pdns/slavecommunicator.cc
pdns/tcpreceiver.cc
pdns/ws-auth.cc

index 22c9a461b422431f45af857231f50c10c5894ea6..1725c9bdaa2f2ee8f2a7e312b22c467e9bb7d789 100644 (file)
@@ -29,8 +29,6 @@
 ./pdns/cdb.hh
 ./pdns/comfun.cc
 ./pdns/comment.hh
-./pdns/common_startup.cc
-./pdns/common_startup.hh
 ./pdns/communicator.cc
 ./pdns/communicator.hh
 ./pdns/dbdnsseckeeper.cc
 ./pdns/query-local-address.hh
 ./pdns/rcpgenerator.cc
 ./pdns/rcpgenerator.hh
-./pdns/receiver.cc
 ./pdns/remote_logger.cc
 ./pdns/remote_logger.hh
 ./pdns/resolve-context.hh
index 2359358f07162b8d69bcdc319fa17bd8b2b6ff01..42c1bd21ea4d36bab959de10308c31244fe977ec 100644 (file)
@@ -4,7 +4,7 @@ AC_INIT([pdns], m4_esyscmd([builder-support/gen-version]))
 AC_CONFIG_AUX_DIR([build-aux])
 AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip tar-ustar -Wno-portability subdir-objects parallel-tests 1.11])
 AM_SILENT_RULES([yes])
-AC_CONFIG_SRCDIR([pdns/receiver.cc])
+AC_CONFIG_SRCDIR([pdns/auth-main.cc])
 AC_CONFIG_MACRO_DIR([m4])
 
 AC_USE_SYSTEM_EXTENSIONS
index 2a5ed8852114e245a64c5720127f2ad08190567d..ec93fadc6f3eea8bd49ee1b79a8cf416016c3183 100644 (file)
@@ -189,6 +189,7 @@ pdns_server_SOURCES = \
        auth-caches.cc auth-caches.hh \
        auth-carbon.cc \
        auth-catalogzone.cc auth-catalogzone.hh \
+       auth-main.cc auth-main.hh \
        auth-packetcache.cc auth-packetcache.hh \
        auth-querycache.cc auth-querycache.hh \
        auth-zonecache.cc auth-zonecache.hh \
@@ -204,7 +205,6 @@ pdns_server_SOURCES = \
        cachecleaner.hh \
        circular_buffer.hh \
        comment.hh \
-       common_startup.cc common_startup.hh \
        communicator.cc communicator.hh \
        credentials.cc credentials.hh \
        dbdnsseckeeper.cc \
@@ -252,7 +252,6 @@ pdns_server_SOURCES = \
        qtype.cc qtype.hh \
        query-local-address.hh query-local-address.cc \
        rcpgenerator.cc \
-       receiver.cc \
        resolver.cc resolver.hh \
        responsestats.cc responsestats.hh responsestats-auth.cc \
        rfc2136handler.cc \
index 41767bc7bfd4139f906c18efac5c81901f49a811..e46ff8d0ed92001f93cd9b09e750ae0446239675 100644 (file)
@@ -28,7 +28,7 @@
 #include "iputils.hh"
 #include "sstuff.hh"
 #include "arguments.hh"
-#include "common_startup.hh"
+#include "auth-main.hh"
 
 #include "namespaces.hh"
 
similarity index 66%
rename from pdns/common_startup.cc
rename to pdns/auth-main.cc
index 34a41320e7bc2105f4567623d534a6a971c22930..a76d2f60234ace5f7aa63ce594bf2ee8092b51c2 100644 (file)
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
-#include "common_startup.hh"
-#include "ws-auth.hh"
-#include "secpoll-auth.hh"
-#include <sys/time.h>
+#include <cstdio>
+#include <signal.h>
+#include <cstring>
+#include <cstdlib>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <iostream>
+#include <string>
+#include <sys/stat.h>
+#include <unistd.h>
 #include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <pthread.h>
+#include <thread>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <fstream>
+#include <boost/algorithm/string.hpp>
+#ifdef HAVE_LIBSODIUM
+#include <sodium.h>
+#endif
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
+#include "auth-main.hh"
+#include "secpoll-auth.hh"
 #include "dynhandler.hh"
 #include "dnsseckeeper.hh"
 #include "threadname.hh"
 #include "misc.hh"
 #include "query-local-address.hh"
 #include "trusted-notification-proxy.hh"
+#include "packetcache.hh"
 #include "packethandler.hh"
+#include "opensslsigners.hh"
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "ueberbackend.hh"
+#include "dnspacket.hh"
+#include "nameserver.hh"
+#include "distributor.hh"
+#include "logger.hh"
+#include "arguments.hh"
+#include "packethandler.hh"
+#include "statbag.hh"
+#include "tcpreceiver.hh"
+#include "misc.hh"
+#include "dynlistener.hh"
+#include "dynhandler.hh"
+#include "communicator.hh"
+#include "dnsproxy.hh"
+#include "utility.hh"
+#include "dnsrecords.hh"
+#include "version.hh"
+#include "ws-auth.hh"
 
-#include <thread>
+#ifdef HAVE_LUA_RECORDS
+#include "minicurl.hh"
+#endif /* HAVE_LUA_RECORDS */
 
-#ifdef HAVE_SYSTEMD
-#include <systemd/sd-daemon.h>
-#endif
+time_t s_starttime;
+
+string s_programname="pdns"; // used in packethandler.cc
+
+const char *funnytext=
+"*****************************************************************************\n"\
+"Ok, you just ran pdns_server through 'strings' hoping to find funny messages.\n"\
+"Well, you found one. \n"\
+"Two ions are flying through their particle accelerator, says the one to the\n"
+"other 'I think I've lost an electron!' \n"\
+"So the other one says, 'Are you sure?'. 'YEAH! I'M POSITIVE!'\n"\
+"                                            the pdns crew - pdns@powerdns.com\n"
+"*****************************************************************************\n";
 
 bool g_anyToTcp;
 bool g_8bitDNS;
@@ -67,6 +128,8 @@ vector<std::shared_ptr<UDPNameserver> > g_udpReceivers;
 NetmaskGroup g_proxyProtocolACL;
 size_t g_proxyProtocolMaximumSize;
 
+void mainthread();
+
 ArgvMap &arg()
 {
   return theArg;
@@ -816,3 +879,590 @@ void mainthread()
   
   g_log<<Logger::Error<<"Mainthread exiting - should never happen"<<endl;
 }
+
+static void daemonize()
+{
+  if(fork())
+    exit(0); // bye bye
+
+  setsid();
+
+  int i=open("/dev/null",O_RDWR); /* open stdin */
+  if(i < 0)
+    g_log<<Logger::Critical<<"Unable to open /dev/null: "<<stringerror()<<endl;
+  else {
+    dup2(i,0); /* stdin */
+    dup2(i,1); /* stderr */
+    dup2(i,2); /* stderr */
+    close(i);
+  }
+}
+
+static int cpid;
+static void takedown(int i)
+{
+  if(cpid) {
+    g_log<<Logger::Error<<"Guardian is killed, taking down children with us"<<endl;
+    kill(cpid,SIGKILL);
+    exit(0);
+  }
+}
+
+static void writePid()
+{
+  if(!::arg().mustDo("write-pid"))
+    return;
+
+  string fname=::arg()["socket-dir"];
+  if (::arg()["socket-dir"].empty()) {
+    if (::arg()["chroot"].empty())
+      fname = std::string(LOCALSTATEDIR) + "/pdns";
+    else
+      fname = ::arg()["chroot"] + "/";
+  } else if (!::arg()["socket-dir"].empty() && !::arg()["chroot"].empty()) {
+    fname = ::arg()["chroot"] + ::arg()["socket-dir"];
+  }
+
+  fname += + "/" + s_programname + ".pid";
+  ofstream of(fname.c_str());
+  if(of)
+    of<<getpid()<<endl;
+  else
+    g_log<<Logger::Error<<"Writing pid for "<<getpid()<<" to "<<fname<<" failed: "<<stringerror()<<endl;
+}
+
+static int g_fd1[2], g_fd2[2];
+static FILE *g_fp;
+static std::mutex g_guardian_lock;
+
+// The next two methods are not in dynhandler.cc because they use a few items declared in this file.
+static string DLCycleHandler(const vector<string>&parts, pid_t ppid)
+{
+  kill(cpid, SIGKILL); // why?
+  kill(cpid, SIGKILL); // why?
+  sleep(1);
+  return "ok";
+}
+
+static string DLRestHandler(const vector<string>&parts, pid_t ppid)
+{
+  string line;
+
+  for(vector<string>::const_iterator i=parts.begin();i!=parts.end();++i) {
+    if(i!=parts.begin())
+      line.append(1,' ');
+    line.append(*i);
+  }
+  line.append(1,'\n');
+
+  std::lock_guard<std::mutex> l(g_guardian_lock);
+
+  try {
+    writen2(g_fd1[1],line.c_str(),line.size()+1);
+  }
+  catch(PDNSException &ae) {
+    return "Error communicating with instance: "+ae.reason;
+  }
+  char mesg[512];
+  string response;
+  while(fgets(mesg,sizeof(mesg),g_fp)) {
+    if(*mesg=='\0')
+      break;
+    response+=mesg;
+  }
+  boost::trim_right(response);
+  return response;
+}
+
+static int guardian(int argc, char **argv)
+{
+  if(isGuarded(argv))
+    return 0;
+
+  int infd=0, outfd=1;
+
+  DynListener dlg(s_programname);
+  dlg.registerFunc("QUIT",&DLQuitHandler, "quit daemon");
+  dlg.registerFunc("CYCLE",&DLCycleHandler, "restart instance");
+  dlg.registerFunc("PING",&DLPingHandler, "ping guardian");
+  dlg.registerFunc("STATUS",&DLStatusHandler, "get instance status from guardian");
+  dlg.registerRestFunc(&DLRestHandler);
+  dlg.go();
+  string progname=argv[0];
+
+  bool first=true;
+  cpid=0;
+
+  g_guardian_lock.lock();
+
+  for(;;) {
+    int pid;
+    setStatus("Launching child");
+
+    if(pipe(g_fd1)<0 || pipe(g_fd2)<0) {
+      g_log<<Logger::Critical<<"Unable to open pipe for coprocess: "<<stringerror()<<endl;
+      exit(1);
+    }
+
+    if(!(g_fp=fdopen(g_fd2[0],"r"))) {
+      g_log<<Logger::Critical<<"Unable to associate a file pointer with pipe: "<<stringerror()<<endl;
+      exit(1);
+    }
+    setbuf(g_fp,nullptr); // no buffering please, confuses select
+
+    if(!(pid=fork())) { // child
+      signal(SIGTERM, SIG_DFL);
+
+      signal(SIGHUP, SIG_DFL);
+      signal(SIGUSR1, SIG_DFL);
+      signal(SIGUSR2, SIG_DFL);
+
+      char **const newargv=new char*[argc+2];
+      int n;
+
+      if(::arg()["config-name"]!="") {
+        progname+="-"+::arg()["config-name"];
+        g_log<<Logger::Error<<"Virtual configuration name: "<<::arg()["config-name"]<<endl;
+      }
+
+      newargv[0]=strdup(const_cast<char *>((progname+"-instance").c_str()));
+      for(n=1;n<argc;n++) {
+        newargv[n]=argv[n];
+      }
+      newargv[n]=nullptr;
+
+      g_log<<Logger::Error<<"Guardian is launching an instance"<<endl;
+      close(g_fd1[1]);
+      fclose(g_fp); // this closes g_fd2[0] for us
+
+      if(g_fd1[0]!= infd) {
+        dup2(g_fd1[0], infd);
+        close(g_fd1[0]);
+      }
+
+      if(g_fd2[1]!= outfd) {
+        dup2(g_fd2[1], outfd);
+        close(g_fd2[1]);
+      }
+      if(execvp(argv[0], newargv)<0) {
+        g_log<<Logger::Error<<"Unable to execvp '"<<argv[0]<<"': "<<stringerror()<<endl;
+        char **p=newargv;
+        while(*p)
+          g_log<<Logger::Error<<*p++<<endl;
+
+        exit(1);
+      }
+      g_log<<Logger::Error<<"execvp returned!!"<<endl;
+      // never reached
+    }
+    else if(pid>0) { // parent
+      close(g_fd1[0]);
+      close(g_fd2[1]);
+
+      if(first) {
+        first=false;
+        signal(SIGTERM, takedown);
+
+        signal(SIGHUP, SIG_IGN);
+        signal(SIGUSR1, SIG_IGN);
+        signal(SIGUSR2, SIG_IGN);
+
+        writePid();
+      }
+      g_guardian_lock.unlock();
+      int status;
+      cpid=pid;
+      for(;;) {
+        int ret=waitpid(pid,&status,WNOHANG);
+
+        if(ret<0) {
+          g_log<<Logger::Error<<"In guardian loop, waitpid returned error: "<<stringerror()<<endl;
+          g_log<<Logger::Error<<"Dying"<<endl;
+          exit(1);
+        }
+        else if(ret) // something exited
+          break;
+        else { // child is alive
+          // execute some kind of ping here
+          if(DLQuitPlease())
+            takedown(1); // needs a parameter..
+          setStatus("Child running on pid "+itoa(pid));
+          sleep(1);
+        }
+      }
+
+      g_guardian_lock.lock();
+      close(g_fd1[1]);
+      fclose(g_fp);
+      g_fp=nullptr;
+
+      if(WIFEXITED(status)) {
+        int ret=WEXITSTATUS(status);
+
+        if(ret==99) {
+          g_log<<Logger::Error<<"Child requested a stop, exiting"<<endl;
+          exit(1);
+        }
+        setStatus("Child died with code "+itoa(ret));
+        g_log<<Logger::Error<<"Our pdns instance exited with code "<<ret<<", respawning"<<endl;
+
+        sleep(1);
+        continue;
+      }
+      if(WIFSIGNALED(status)) {
+        int sig=WTERMSIG(status);
+        setStatus("Child died because of signal "+itoa(sig));
+        g_log<<Logger::Error<<"Our pdns instance ("<<pid<<") exited after signal "<<sig<<endl;
+#ifdef WCOREDUMP
+        if(WCOREDUMP(status))
+          g_log<<Logger::Error<<"Dumped core"<<endl;
+#endif
+
+        g_log<<Logger::Error<<"Respawning"<<endl;
+        sleep(1);
+        continue;
+      }
+      g_log<<Logger::Error<<"No clue what happened! Respawning"<<endl;
+    }
+    else {
+      g_log<<Logger::Error<<"Unable to fork: "<<stringerror()<<endl;
+      exit(1);
+    }
+  }
+}
+
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
+#include <execinfo.h>
+static void tbhandler(int num)
+{
+  g_log<<Logger::Critical<<"Got a signal "<<num<<", attempting to print trace: "<<endl;
+  void *array[20]; // only care about last 17 functions (3 taken with tracing support)
+  size_t size;
+  char **strings;
+  size_t i;
+
+  size = backtrace (array, 20);
+  strings = backtrace_symbols (array, size); // Need -rdynamic gcc (linker) flag for this to work
+
+  for (i = 0; i < size; i++) // skip useless functions
+    g_log<<Logger::Error<<strings[i]<<endl;
+
+  signal(SIGABRT, SIG_DFL);
+  abort(); // hopefully will give core
+}
+#endif
+
+//! The main function of pdns, the pdns process
+int main(int argc, char **argv)
+{
+  versionSetProduct(ProductAuthoritative);
+  reportAllTypes(); // init MOADNSParser
+
+  s_programname="pdns";
+  s_starttime=time(nullptr);
+
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
+  signal(SIGSEGV,tbhandler);
+  signal(SIGFPE,tbhandler);
+  signal(SIGABRT,tbhandler);
+  signal(SIGILL,tbhandler);
+#endif
+
+  std::ios_base::sync_with_stdio(false);
+
+  g_log.toConsole(Logger::Warning);
+  try {
+    declareArguments();
+
+    ::arg().laxParse(argc,argv); // do a lax parse
+
+    if(::arg().mustDo("version")) {
+      showProductVersion();
+      showBuildConfiguration();
+      exit(99);
+    }
+
+    if(::arg()["config-name"]!="")
+      s_programname+="-"+::arg()["config-name"];
+
+    g_log.setName(s_programname);
+
+    string configname=::arg()["config-dir"]+"/"+s_programname+".conf";
+    cleanSlashes(configname);
+
+    if(::arg()["config"] != "default" && !::arg().mustDo("no-config")) // "config" == print a configuration file
+      ::arg().laxFile(configname.c_str());
+
+    ::arg().laxParse(argc,argv); // reparse so the commandline still wins
+    if(!::arg()["logging-facility"].empty()) {
+      int val=logFacilityToLOG(::arg().asNum("logging-facility") );
+      if(val >= 0)
+        g_log.setFacility(val);
+      else
+        g_log<<Logger::Error<<"Unknown logging facility "<<::arg().asNum("logging-facility") <<endl;
+    }
+
+    if (::arg().mustDo("master")) ::arg().set("primary")="yes";
+    if (::arg().mustDo("slave")) ::arg().set("secondary")="yes";
+    if (::arg().mustDo("slave-renotify")) ::arg().set("secondary-do-renotify")="yes";
+    if (::arg().mustDo("superslave")) ::arg().set("autosecondary")="yes";
+    if (::arg().mustDo("allow-unsigned-supermaster")) ::arg().set("allow-unsigned-autoprimary")="yes";
+    if (!::arg().isEmpty("domain-metadata-cache-ttl"))
+      ::arg().set("zone-metadata-cache-ttl") = ::arg()["domain-metadata-cache-ttl"];
+
+    // this mirroring back is on purpose, so that config dumps reflect the actual setting on both names
+    if (::arg().mustDo("primary")) ::arg().set("master")="yes";
+    if (::arg().mustDo("secondary")) ::arg().set("slave")="yes";
+    if (::arg().mustDo("secondary-do-renotify")) ::arg().set("slave-renotify")="yes";
+    if (::arg().mustDo("autosecondary")) ::arg().set("superslave")="yes";
+    if (::arg().mustDo("allow-unsigned-autoprimary")) ::arg().set("allow-unsigned-supermaster")="yes";
+    ::arg().set("domain-metadata-cache-ttl") = ::arg()["zone-metadata-cache-ttl"];
+
+    g_log.setLoglevel((Logger::Urgency)(::arg().asNum("loglevel")));
+    g_log.disableSyslog(::arg().mustDo("disable-syslog"));
+    g_log.setTimestamps(::arg().mustDo("log-timestamp"));
+    g_log.toConsole((Logger::Urgency)(::arg().asNum("loglevel")));
+
+    if(::arg().mustDo("help") || ::arg().mustDo("config")) {
+      ::arg().set("daemon")="no";
+      ::arg().set("guardian")="no";
+    }
+
+    if(::arg().mustDo("guardian") && !isGuarded(argv)) {
+      if(::arg().mustDo("daemon")) {
+        g_log.toConsole(Logger::Critical);
+        daemonize();
+      }
+      guardian(argc, argv);
+      // never get here, guardian will reinvoke process
+      cerr<<"Um, we did get here!"<<endl;
+    }
+
+    // we really need to do work - either standalone or as an instance
+
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
+    if(!::arg().mustDo("traceback-handler")) {
+      g_log<<Logger::Warning<<"Disabling traceback handler"<<endl;
+      signal(SIGSEGV,SIG_DFL);
+      signal(SIGFPE,SIG_DFL);
+      signal(SIGABRT,SIG_DFL);
+      signal(SIGILL,SIG_DFL);
+    }
+#endif
+
+#ifdef HAVE_LIBSODIUM
+      if (sodium_init() == -1) {
+        cerr<<"Unable to initialize sodium crypto library"<<endl;
+        exit(99);
+      }
+#endif
+
+    openssl_thread_setup();
+    openssl_seed();
+    /* setup rng */
+    dns_random_init();
+
+#ifdef HAVE_LUA_RECORDS
+    MiniCurl::init();
+#endif /* HAVE_LUA_RECORDS */
+
+    if(!::arg()["load-modules"].empty()) {
+      vector<string> modules;
+
+      stringtok(modules,::arg()["load-modules"], ", ");
+      if (!UeberBackend::loadModules(modules, ::arg()["module-dir"])) {
+        exit(1);
+      }
+    }
+
+    BackendMakers().launch(::arg()["launch"]); // vrooooom!
+
+    if(!::arg().getCommands().empty()) {
+      cerr<<"Fatal: non-option";
+      if (::arg().getCommands().size() > 1) {
+        cerr<<"s";
+      }
+      cerr<<" (";
+      bool first = true;
+      for (const auto& c : ::arg().getCommands()) {
+        if (!first) {
+          cerr<<", ";
+        }
+        first = false;
+        cerr<<c;
+      }
+      cerr<<") on the command line, perhaps a '--setting=123' statement missed the '='?"<<endl;
+      exit(99);
+    }
+
+    if(::arg().mustDo("help")) {
+      cout<<"syntax:"<<endl<<endl;
+      cout<<::arg().helpstring(::arg()["help"])<<endl;
+      exit(0);
+    }
+
+    if(::arg().mustDo("config")) {
+      string config = ::arg()["config"];
+      if (config == "default") {
+        cout<<::arg().configstring(false, true);
+      } else if (config == "diff") {
+          cout<<::arg().configstring(true, false);
+      } else if (config == "check") {
+        try {
+          if(!::arg().mustDo("no-config"))
+            ::arg().file(configname.c_str());
+          ::arg().parse(argc,argv);
+          exit(0);
+        }
+        catch(const ArgException &A) {
+          cerr<<"Fatal error: "<<A.reason<<endl;
+          exit(1);
+        }
+      } else {
+        cout<<::arg().configstring(true, true);
+      }
+      exit(0);
+    }
+
+    if(::arg().mustDo("list-modules")) {
+      auto modules = BackendMakers().getModules();
+      cout<<"Modules available:"<<endl;
+      for(const auto& m : modules)
+        cout<< m <<endl;
+
+      _exit(99);
+    }
+
+    if(!::arg().asNum("local-port")) {
+      g_log<<Logger::Error<<"Unable to launch, binding to no port or port 0 makes no sense"<<endl;
+      exit(99); // this isn't going to fix itself either
+    }
+    if(!BackendMakers().numLauncheable()) {
+      g_log<<Logger::Error<<"Unable to launch, no backends configured for querying"<<endl;
+      exit(99); // this isn't going to fix itself either
+    }
+    if(::arg().mustDo("daemon")) {
+      g_log.toConsole(Logger::None);
+      if(!isGuarded(argv))
+        daemonize();
+    }
+
+    if(isGuarded(argv)) {
+      g_log<<Logger::Warning<<"This is a guarded instance of pdns"<<endl;
+      dl=make_unique<DynListener>(); // listens on stdin
+    }
+    else {
+      g_log<<Logger::Warning<<"This is a standalone pdns"<<endl; 
+
+      if(::arg().mustDo("control-console"))
+        dl=make_unique<DynListener>();
+      else
+        dl = std::make_unique<DynListener>(s_programname);
+
+      writePid();
+    }
+    DynListener::registerFunc("SHOW",&DLShowHandler, "show a specific statistic or * to get a list", "<statistic>");
+    DynListener::registerFunc("RPING",&DLPingHandler, "ping instance");
+    DynListener::registerFunc("QUIT",&DLRQuitHandler, "quit daemon");
+    DynListener::registerFunc("UPTIME",&DLUptimeHandler, "get instance uptime");
+    DynListener::registerFunc("NOTIFY-HOST", &DLNotifyHostHandler, "notify host for specific zone", "<zone> <host>");
+    DynListener::registerFunc("NOTIFY", &DLNotifyHandler, "queue a notification", "<zone>");
+    DynListener::registerFunc("RELOAD",&DLReloadHandler, "reload all zones");
+    DynListener::registerFunc("REDISCOVER",&DLRediscoverHandler, "discover any new zones");
+    DynListener::registerFunc("VERSION",&DLVersionHandler, "get instance version");
+    DynListener::registerFunc("PURGE",&DLPurgeHandler, "purge entries from packet cache", "[<record>]");
+    DynListener::registerFunc("CCOUNTS",&DLCCHandler, "get cache statistics");
+    DynListener::registerFunc("QTYPES", &DLQTypesHandler, "get QType statistics");
+    DynListener::registerFunc("RESPSIZES", &DLRSizesHandler, "get histogram of response sizes");
+    DynListener::registerFunc("REMOTES", &DLRemotesHandler, "get top remotes");
+    DynListener::registerFunc("SET",&DLSettingsHandler, "set config variables", "<var> <value>");
+    DynListener::registerFunc("RETRIEVE", &DLNotifyRetrieveHandler, "retrieve slave zone", "<zone> [<ip>]");
+    DynListener::registerFunc("CURRENT-CONFIG",&DLCurrentConfigHandler, "retrieve the current configuration", "[diff]");
+    DynListener::registerFunc("LIST-ZONES", &DLListZones, "show list of zones", "[primary|secondary|native]");
+    DynListener::registerFunc("TOKEN-LOGIN", &DLTokenLogin, "Login to a PKCS#11 token", "<module> <slot> <pin>");
+    DynListener::registerFunc("XFR-QUEUE", &DLSuckRequests, "Get all requests for XFR in queue");
+
+    if(!::arg()["tcp-control-address"].empty()) {
+      DynListener* dlTCP=new DynListener(ComboAddress(::arg()["tcp-control-address"], ::arg().asNum("tcp-control-port")));
+      dlTCP->go();
+    }
+
+    // reparse, with error checking
+    if(!::arg().mustDo("no-config"))
+      ::arg().file(configname.c_str());
+    ::arg().parse(argc,argv);
+
+    if(::arg()["server-id"].empty()) {
+      char tmp[128];
+      if(gethostname(tmp, sizeof(tmp)-1) == 0) {
+        ::arg().set("server-id")=tmp;
+      } else {
+        g_log<<Logger::Warning<<"Unable to get the hostname, NSID and id.server values will be empty: "<<stringerror()<<endl;
+      }
+    }
+
+    UeberBackend::go();
+
+    g_zoneCache.setRefreshInterval(::arg().asNum("zone-cache-refresh-interval"));
+    {
+      UeberBackend B;
+      B.updateZoneCache();
+    }
+
+    N=std::make_shared<UDPNameserver>(); // this fails when we are not root, throws exception
+    g_udpReceivers.push_back(N);
+
+    size_t rthreads = ::arg().asNum("receiver-threads", 1);
+    if (rthreads > 1 && N->canReusePort()) {
+      g_udpReceivers.resize(rthreads);
+
+      for (size_t idx = 1; idx < rthreads; idx++) {
+        try {
+          g_udpReceivers[idx] = std::make_shared<UDPNameserver>(true);
+        }
+        catch(const PDNSException& e) {
+          g_log<<Logger::Error<<"Unable to reuse port, falling back to original bind"<<endl;
+          break;
+        }
+      }
+    }
+
+    TN = make_unique<TCPNameserver>();
+  }
+  catch(const ArgException &A) {
+    g_log<<Logger::Error<<"Fatal error: "<<A.reason<<endl;
+    exit(1);
+  }
+
+  try {
+    declareStats();
+  }
+  catch(PDNSException &PE) {
+    g_log<<Logger::Error<<"Exiting because: "<<PE.reason<<endl;
+    exit(1);
+  }
+  S.blacklist("special-memory-usage");
+
+  DLOG(g_log<<Logger::Warning<<"Verbose logging in effect"<<endl);
+
+  showProductVersion();
+
+  try {
+    mainthread();
+  }
+  catch(PDNSException &e) {
+    if(!::arg().mustDo("daemon"))
+      cerr<<"Exiting because: "<<e.reason<<endl;
+    g_log<<Logger::Error<<"Exiting because: "<<e.reason<<endl;
+  }
+  catch(std::exception &e) {
+    if(!::arg().mustDo("daemon"))
+      cerr<<"Exiting because of STL error: "<<e.what()<<endl;
+    g_log<<Logger::Error<<"Exiting because of STL error: "<<e.what()<<endl;
+  }
+  catch(...) {
+    cerr<<"Uncaught exception of unknown type - sorry"<<endl;
+  }
+
+  exit(1);
+}
similarity index 100%
rename from pdns/common_startup.hh
rename to pdns/auth-main.hh
index 82125a84d393b555e536d873aec59d3ee50fc980..9a27e3302854cf5c3d749e039c7112086b859ba4 100644 (file)
@@ -38,7 +38,7 @@
 #include "nameserver.hh"
 #include "responsestats.hh"
 #include "ueberbackend.hh"
-#include "common_startup.hh"
+#include "auth-main.hh"
 
 extern ResponseStats g_rs;
 
index ebbda122379ba6762eb6e501eae20e7a008be8a9..16ad0b9e701d23df599d0c099b58c3290df13b87 100644 (file)
@@ -13,7 +13,7 @@
 #include "ueberbackend.hh"
 #include "dnsrecords.hh"
 #include "dns_random.hh"
-#include "common_startup.hh"
+#include "auth-main.hh"
 #include "../modules/geoipbackend/geoipinterface.hh" // only for the enum
 
 /* to do:
index 183033dd6e495574a4a197c0f3f72c1a927bc66c..db66bc9e62164dbffa087766f39dc0352fe0d839 100644 (file)
@@ -32,7 +32,7 @@
 #include <sys/types.h>
 #include "responsestats.hh"
 
-#include "common_startup.hh"
+#include "auth-main.hh"
 #include "dns.hh"
 #include "dnsbackend.hh"
 #include "dnspacket.hh"
@@ -83,7 +83,7 @@ extern StatBag S;
     These statistics are made available via the UeberBackend on the same socket that is used for dynamic module commands.
 
     \section Main Main 
-    The main() of PowerDNS can be found in receiver.cc - start reading there for further insights into the operation of the nameserver
+    The main() of PowerDNS can be found in auth-main.cc - start reading there for further insights into the operation of the nameserver
 */
 
 vector<ComboAddress> g_localaddresses; // not static, our unit tests need to poke this
index f34d83b8e91b84f497153dbccd59fbb7f6aebd80..ac7f62a6ee7f45bc5027cac034840cb09b26c1de 100644 (file)
@@ -44,7 +44,7 @@
 #include "communicator.hh"
 #include "dnsproxy.hh"
 #include "version.hh"
-#include "common_startup.hh"
+#include "auth-main.hh"
 #include "trusted-notification-proxy.hh"
 
 #if 0
diff --git a/pdns/receiver.cc b/pdns/receiver.cc
deleted file mode 100644 (file)
index e5e6785..0000000
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * This file is part of PowerDNS or dnsdist.
- * Copyright -- PowerDNS.COM B.V. and its contributors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * In addition, for the avoidance of any doubt, permission is granted to
- * link this program with OpenSSL and to (re)distribute the binaries
- * produced as the result of such linking.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "packetcache.hh"
-
-#include <cstdio>
-#include <signal.h>
-#include <cstring>
-#include <cstdlib>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <iostream>
-#include <string>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <fstream>
-#include <boost/algorithm/string.hpp>
-#ifdef HAVE_LIBSODIUM
-#include <sodium.h>
-#endif
-#include "opensslsigners.hh"
-
-#include "dns.hh"
-#include "dnsbackend.hh"
-#include "ueberbackend.hh"
-#include "dnspacket.hh"
-#include "nameserver.hh"
-#include "distributor.hh"
-#include "logger.hh"
-#include "arguments.hh"
-#include "packethandler.hh"
-#include "statbag.hh"
-#include "tcpreceiver.hh"
-#include "misc.hh"
-#include "dynlistener.hh"
-#include "dynhandler.hh"
-#include "communicator.hh"
-#include "dnsproxy.hh"
-#include "utility.hh"
-#include "common_startup.hh"
-#include "dnsrecords.hh"
-#include "version.hh"
-
-#ifdef HAVE_LUA_RECORDS
-#include "minicurl.hh"
-#endif /* HAVE_LUA_RECORDS */
-
-time_t s_starttime;
-
-string s_programname="pdns"; // used in packethandler.cc
-
-const char *funnytext=
-"*****************************************************************************\n"\
-"Ok, you just ran pdns_server through 'strings' hoping to find funny messages.\n"\
-"Well, you found one. \n"\
-"Two ions are flying through their particle accelerator, says the one to the\n"
-"other 'I think I've lost an electron!' \n"\
-"So the other one says, 'Are you sure?'. 'YEAH! I'M POSITIVE!'\n"\
-"                                            the pdns crew - pdns@powerdns.com\n"
-"*****************************************************************************\n";
-
-
-// start (sys)logging
-
-
-/**
-\file receiver.cc
-\brief The main loop of powerdns 
-
-This file is where it all happens - main is here, as are the two pivotal threads qthread() and athread()
-*/
-
-static void daemonize()
-{
-  if(fork())
-    exit(0); // bye bye
-  
-  setsid(); 
-
-  int i=open("/dev/null",O_RDWR); /* open stdin */
-  if(i < 0) 
-    g_log<<Logger::Critical<<"Unable to open /dev/null: "<<stringerror()<<endl;
-  else {
-    dup2(i,0); /* stdin */
-    dup2(i,1); /* stderr */
-    dup2(i,2); /* stderr */
-    close(i);
-  }
-}
-
-static int cpid;
-static void takedown(int i)
-{
-  if(cpid) {
-    g_log<<Logger::Error<<"Guardian is killed, taking down children with us"<<endl;
-    kill(cpid,SIGKILL);
-    exit(0);
-  }
-}
-
-static void writePid()
-{
-  if(!::arg().mustDo("write-pid"))
-    return;
-
-  string fname=::arg()["socket-dir"];
-  if (::arg()["socket-dir"].empty()) {
-    if (::arg()["chroot"].empty())
-      fname = std::string(LOCALSTATEDIR) + "/pdns";
-    else
-      fname = ::arg()["chroot"] + "/";
-  } else if (!::arg()["socket-dir"].empty() && !::arg()["chroot"].empty()) {
-    fname = ::arg()["chroot"] + ::arg()["socket-dir"];
-  }
-
-  fname += + "/" + s_programname + ".pid";
-  ofstream of(fname.c_str());
-  if(of)
-    of<<getpid()<<endl;
-  else
-    g_log<<Logger::Error<<"Writing pid for "<<getpid()<<" to "<<fname<<" failed: "<<stringerror()<<endl;
-}
-
-static int g_fd1[2], g_fd2[2];
-static FILE *g_fp;
-static std::mutex g_guardian_lock;
-
-// The next two methods are not in dynhandler.cc because they use a few items declared in this file.
-static string DLCycleHandler(const vector<string>&parts, pid_t ppid)
-{
-  kill(cpid, SIGKILL); // why?
-  kill(cpid, SIGKILL); // why?
-  sleep(1);
-  return "ok";
-}
-
-static string DLRestHandler(const vector<string>&parts, pid_t ppid)
-{
-  string line;
-  
-  for(vector<string>::const_iterator i=parts.begin();i!=parts.end();++i) {
-    if(i!=parts.begin())
-      line.append(1,' ');
-    line.append(*i);
-  }
-  line.append(1,'\n');
-  
-  std::lock_guard<std::mutex> l(g_guardian_lock);
-
-  try {
-    writen2(g_fd1[1],line.c_str(),line.size()+1);
-  }
-  catch(PDNSException &ae) {
-    return "Error communicating with instance: "+ae.reason;
-  }
-  char mesg[512];
-  string response;
-  while(fgets(mesg,sizeof(mesg),g_fp)) {
-    if(*mesg=='\0')
-      break;
-    response+=mesg;
-  }
-  boost::trim_right(response);
-  return response;
-}
-
-
-
-static int guardian(int argc, char **argv)
-{
-  if(isGuarded(argv))
-    return 0;
-
-  int infd=0, outfd=1;
-
-  DynListener dlg(s_programname);
-  dlg.registerFunc("QUIT",&DLQuitHandler, "quit daemon");
-  dlg.registerFunc("CYCLE",&DLCycleHandler, "restart instance");
-  dlg.registerFunc("PING",&DLPingHandler, "ping guardian");
-  dlg.registerFunc("STATUS",&DLStatusHandler, "get instance status from guardian");
-  dlg.registerRestFunc(&DLRestHandler);
-  dlg.go();
-  string progname=argv[0];
-
-  bool first=true;
-  cpid=0;
-
-  g_guardian_lock.lock();
-
-  for(;;) {
-    int pid;
-    setStatus("Launching child");
-    
-    if(pipe(g_fd1)<0 || pipe(g_fd2)<0) {
-      g_log<<Logger::Critical<<"Unable to open pipe for coprocess: "<<stringerror()<<endl;
-      exit(1);
-    }
-
-    if(!(g_fp=fdopen(g_fd2[0],"r"))) {
-      g_log<<Logger::Critical<<"Unable to associate a file pointer with pipe: "<<stringerror()<<endl;
-      exit(1);
-    }
-    setbuf(g_fp,nullptr); // no buffering please, confuses select
-
-    if(!(pid=fork())) { // child
-      signal(SIGTERM, SIG_DFL);
-
-      signal(SIGHUP, SIG_DFL);
-      signal(SIGUSR1, SIG_DFL);
-      signal(SIGUSR2, SIG_DFL);
-
-      char **const newargv=new char*[argc+2];
-      int n;
-
-      if(::arg()["config-name"]!="") {
-        progname+="-"+::arg()["config-name"];
-        g_log<<Logger::Error<<"Virtual configuration name: "<<::arg()["config-name"]<<endl;
-      }
-
-      newargv[0]=strdup(const_cast<char *>((progname+"-instance").c_str()));
-      for(n=1;n<argc;n++) {
-        newargv[n]=argv[n];
-      }
-      newargv[n]=nullptr;
-      
-      g_log<<Logger::Error<<"Guardian is launching an instance"<<endl;
-      close(g_fd1[1]);
-      fclose(g_fp); // this closes g_fd2[0] for us
-
-      if(g_fd1[0]!= infd) {
-        dup2(g_fd1[0], infd);
-        close(g_fd1[0]);
-      }
-
-      if(g_fd2[1]!= outfd) {
-        dup2(g_fd2[1], outfd);
-        close(g_fd2[1]);
-      }
-      if(execvp(argv[0], newargv)<0) {
-        g_log<<Logger::Error<<"Unable to execvp '"<<argv[0]<<"': "<<stringerror()<<endl;
-        char **p=newargv;
-        while(*p)
-          g_log<<Logger::Error<<*p++<<endl;
-
-        exit(1);
-      }
-      g_log<<Logger::Error<<"execvp returned!!"<<endl;
-      // never reached
-    }
-    else if(pid>0) { // parent
-      close(g_fd1[0]);
-      close(g_fd2[1]);
-
-      if(first) {
-        first=false;
-        signal(SIGTERM, takedown);
-
-        signal(SIGHUP, SIG_IGN);
-        signal(SIGUSR1, SIG_IGN);
-        signal(SIGUSR2, SIG_IGN);
-
-        writePid();
-      }
-      g_guardian_lock.unlock();
-      int status;
-      cpid=pid;
-      for(;;) {
-        int ret=waitpid(pid,&status,WNOHANG);
-
-        if(ret<0) {
-          g_log<<Logger::Error<<"In guardian loop, waitpid returned error: "<<stringerror()<<endl;
-          g_log<<Logger::Error<<"Dying"<<endl;
-          exit(1);
-        }
-        else if(ret) // something exited
-          break;
-        else { // child is alive
-          // execute some kind of ping here 
-          if(DLQuitPlease())
-            takedown(1); // needs a parameter..
-          setStatus("Child running on pid "+itoa(pid));
-          sleep(1);
-        }
-      }
-
-      g_guardian_lock.lock();
-      close(g_fd1[1]);
-      fclose(g_fp);
-      g_fp=nullptr;
-
-      if(WIFEXITED(status)) {
-        int ret=WEXITSTATUS(status);
-
-        if(ret==99) {
-          g_log<<Logger::Error<<"Child requested a stop, exiting"<<endl;
-          exit(1);
-        }
-        setStatus("Child died with code "+itoa(ret));
-        g_log<<Logger::Error<<"Our pdns instance exited with code "<<ret<<", respawning"<<endl;
-
-        sleep(1);
-        continue;
-      }
-      if(WIFSIGNALED(status)) {
-        int sig=WTERMSIG(status);
-        setStatus("Child died because of signal "+itoa(sig));
-        g_log<<Logger::Error<<"Our pdns instance ("<<pid<<") exited after signal "<<sig<<endl;
-#ifdef WCOREDUMP
-        if(WCOREDUMP(status)) 
-          g_log<<Logger::Error<<"Dumped core"<<endl;
-#endif
-
-        g_log<<Logger::Error<<"Respawning"<<endl;
-        sleep(1);
-        continue;
-      }
-      g_log<<Logger::Error<<"No clue what happened! Respawning"<<endl;
-    }
-    else {
-      g_log<<Logger::Error<<"Unable to fork: "<<stringerror()<<endl;
-      exit(1);
-    }
-  }
-}
-
-#if defined(__GLIBC__) && !defined(__UCLIBC__)
-#include <execinfo.h>
-static void tbhandler(int num)
-{
-  g_log<<Logger::Critical<<"Got a signal "<<num<<", attempting to print trace: "<<endl;
-  void *array[20]; //only care about last 17 functions (3 taken with tracing support)
-  size_t size;
-  char **strings;
-  size_t i;
-  
-  size = backtrace (array, 20);
-  strings = backtrace_symbols (array, size); //Need -rdynamic gcc (linker) flag for this to work
-  
-  for (i = 0; i < size; i++) //skip useless functions
-    g_log<<Logger::Error<<strings[i]<<endl;
-  
-  
-  signal(SIGABRT, SIG_DFL);
-  abort();//hopefully will give core
-
-}
-#endif
-
-//! The main function of pdns, the pdns process
-int main(int argc, char **argv)
-{
-  versionSetProduct(ProductAuthoritative);
-  reportAllTypes(); // init MOADNSParser
-
-  s_programname="pdns";
-  s_starttime=time(nullptr);
-
-#if defined(__GLIBC__) && !defined(__UCLIBC__)
-  signal(SIGSEGV,tbhandler);
-  signal(SIGFPE,tbhandler);
-  signal(SIGABRT,tbhandler);
-  signal(SIGILL,tbhandler);
-#endif
-
-  std::ios_base::sync_with_stdio(false);
-
-  g_log.toConsole(Logger::Warning);
-  try {
-    declareArguments();
-
-    ::arg().laxParse(argc,argv); // do a lax parse
-    
-    if(::arg().mustDo("version")) {
-      showProductVersion();
-      showBuildConfiguration();
-      exit(99);
-    }
-
-    if(::arg()["config-name"]!="") 
-      s_programname+="-"+::arg()["config-name"];
-    
-    g_log.setName(s_programname);
-    
-    string configname=::arg()["config-dir"]+"/"+s_programname+".conf";
-    cleanSlashes(configname);
-
-    if(::arg()["config"] != "default" && !::arg().mustDo("no-config")) // "config" == print a configuration file
-      ::arg().laxFile(configname.c_str());
-    
-    ::arg().laxParse(argc,argv); // reparse so the commandline still wins
-    if(!::arg()["logging-facility"].empty()) {
-      int val=logFacilityToLOG(::arg().asNum("logging-facility") );
-      if(val >= 0)
-        g_log.setFacility(val);
-      else
-        g_log<<Logger::Error<<"Unknown logging facility "<<::arg().asNum("logging-facility") <<endl;
-    }
-
-    if (::arg().mustDo("master")) ::arg().set("primary")="yes";
-    if (::arg().mustDo("slave")) ::arg().set("secondary")="yes";
-    if (::arg().mustDo("slave-renotify")) ::arg().set("secondary-do-renotify")="yes";
-    if (::arg().mustDo("superslave")) ::arg().set("autosecondary")="yes";
-    if (::arg().mustDo("allow-unsigned-supermaster")) ::arg().set("allow-unsigned-autoprimary")="yes";
-    if (!::arg().isEmpty("domain-metadata-cache-ttl"))
-      ::arg().set("zone-metadata-cache-ttl") = ::arg()["domain-metadata-cache-ttl"];
-
-    // this mirroring back is on purpose, so that config dumps reflect the actual setting on both names
-    if (::arg().mustDo("primary")) ::arg().set("master")="yes";
-    if (::arg().mustDo("secondary")) ::arg().set("slave")="yes";
-    if (::arg().mustDo("secondary-do-renotify")) ::arg().set("slave-renotify")="yes";
-    if (::arg().mustDo("autosecondary")) ::arg().set("superslave")="yes";
-    if (::arg().mustDo("allow-unsigned-autoprimary")) ::arg().set("allow-unsigned-supermaster")="yes";
-    ::arg().set("domain-metadata-cache-ttl") = ::arg()["zone-metadata-cache-ttl"];
-
-    g_log.setLoglevel((Logger::Urgency)(::arg().asNum("loglevel")));
-    g_log.disableSyslog(::arg().mustDo("disable-syslog"));
-    g_log.setTimestamps(::arg().mustDo("log-timestamp"));
-    g_log.toConsole((Logger::Urgency)(::arg().asNum("loglevel")));  
-
-    if(::arg().mustDo("help") || ::arg().mustDo("config")) {
-      ::arg().set("daemon")="no";
-      ::arg().set("guardian")="no";
-    }
-
-    if(::arg().mustDo("guardian") && !isGuarded(argv)) {
-      if(::arg().mustDo("daemon")) {
-        g_log.toConsole(Logger::Critical);
-        daemonize();
-      }
-      guardian(argc, argv);  
-      // never get here, guardian will reinvoke process
-      cerr<<"Um, we did get here!"<<endl;
-    }
-
-    
-    // we really need to do work - either standalone or as an instance
-
-#if defined(__GLIBC__) && !defined(__UCLIBC__)
-    if(!::arg().mustDo("traceback-handler")) {
-      g_log<<Logger::Warning<<"Disabling traceback handler"<<endl;
-      signal(SIGSEGV,SIG_DFL);
-      signal(SIGFPE,SIG_DFL);
-      signal(SIGABRT,SIG_DFL);
-      signal(SIGILL,SIG_DFL);
-    }
-#endif
-
-#ifdef HAVE_LIBSODIUM
-      if (sodium_init() == -1) {
-        cerr<<"Unable to initialize sodium crypto library"<<endl;
-        exit(99);
-      }
-#endif
-
-    openssl_thread_setup();
-    openssl_seed();
-    /* setup rng */
-    dns_random_init();
-
-#ifdef HAVE_LUA_RECORDS
-    MiniCurl::init();
-#endif /* HAVE_LUA_RECORDS */
-
-    if(!::arg()["load-modules"].empty()) {
-      vector<string> modules;
-
-      stringtok(modules,::arg()["load-modules"], ", ");
-      if (!UeberBackend::loadModules(modules, ::arg()["module-dir"])) {
-        exit(1);
-      }
-    }
-
-    BackendMakers().launch(::arg()["launch"]); // vrooooom!
-
-    if(!::arg().getCommands().empty()) {
-      cerr<<"Fatal: non-option";
-      if (::arg().getCommands().size() > 1) {
-        cerr<<"s";
-      }
-      cerr<<" (";
-      bool first = true;
-      for (const auto& c : ::arg().getCommands()) {
-        if (!first) {
-          cerr<<", ";
-        }
-        first = false;
-        cerr<<c;
-      }
-      cerr<<") on the command line, perhaps a '--setting=123' statement missed the '='?"<<endl;
-      exit(99);
-    }
-    
-    if(::arg().mustDo("help")) {
-      cout<<"syntax:"<<endl<<endl;
-      cout<<::arg().helpstring(::arg()["help"])<<endl;
-      exit(0);
-    }
-    
-    if(::arg().mustDo("config")) {
-      string config = ::arg()["config"];
-      if (config == "default") {
-        cout<<::arg().configstring(false, true);
-      } else if (config == "diff") {
-          cout<<::arg().configstring(true, false);
-      } else if (config == "check") {
-        try {
-          if(!::arg().mustDo("no-config"))
-            ::arg().file(configname.c_str());
-          ::arg().parse(argc,argv);
-          exit(0);
-        }
-        catch(const ArgException &A) {
-          cerr<<"Fatal error: "<<A.reason<<endl;
-          exit(1);
-        }
-      } else {
-        cout<<::arg().configstring(true, true);
-      }
-      exit(0);
-    }
-
-    if(::arg().mustDo("list-modules")) {
-      auto modules = BackendMakers().getModules();
-      cout<<"Modules available:"<<endl;
-      for(const auto& m : modules)
-        cout<< m <<endl;
-
-      _exit(99);
-    }
-
-    if(!::arg().asNum("local-port")) {
-      g_log<<Logger::Error<<"Unable to launch, binding to no port or port 0 makes no sense"<<endl;
-      exit(99); // this isn't going to fix itself either
-    }
-    if(!BackendMakers().numLauncheable()) {
-      g_log<<Logger::Error<<"Unable to launch, no backends configured for querying"<<endl;
-      exit(99); // this isn't going to fix itself either
-    }    
-    if(::arg().mustDo("daemon")) {
-      g_log.toConsole(Logger::None);
-      if(!isGuarded(argv))
-        daemonize();
-    }
-
-    if(isGuarded(argv)) {
-      g_log<<Logger::Warning<<"This is a guarded instance of pdns"<<endl;
-      dl=make_unique<DynListener>(); // listens on stdin 
-    }
-    else {
-      g_log<<Logger::Warning<<"This is a standalone pdns"<<endl; 
-      
-      if(::arg().mustDo("control-console"))
-        dl=make_unique<DynListener>();
-      else
-        dl = std::make_unique<DynListener>(s_programname);
-
-      writePid();
-    }
-    DynListener::registerFunc("SHOW",&DLShowHandler, "show a specific statistic or * to get a list", "<statistic>");
-    DynListener::registerFunc("RPING",&DLPingHandler, "ping instance");
-    DynListener::registerFunc("QUIT",&DLRQuitHandler, "quit daemon");
-    DynListener::registerFunc("UPTIME",&DLUptimeHandler, "get instance uptime");
-    DynListener::registerFunc("NOTIFY-HOST", &DLNotifyHostHandler, "notify host for specific zone", "<zone> <host>");
-    DynListener::registerFunc("NOTIFY", &DLNotifyHandler, "queue a notification", "<zone>");
-    DynListener::registerFunc("RELOAD",&DLReloadHandler, "reload all zones");
-    DynListener::registerFunc("REDISCOVER",&DLRediscoverHandler, "discover any new zones");
-    DynListener::registerFunc("VERSION",&DLVersionHandler, "get instance version");
-    DynListener::registerFunc("PURGE",&DLPurgeHandler, "purge entries from packet cache", "[<record>]");
-    DynListener::registerFunc("CCOUNTS",&DLCCHandler, "get cache statistics");
-    DynListener::registerFunc("QTYPES", &DLQTypesHandler, "get QType statistics");
-    DynListener::registerFunc("RESPSIZES", &DLRSizesHandler, "get histogram of response sizes");
-    DynListener::registerFunc("REMOTES", &DLRemotesHandler, "get top remotes");
-    DynListener::registerFunc("SET",&DLSettingsHandler, "set config variables", "<var> <value>");
-    DynListener::registerFunc("RETRIEVE", &DLNotifyRetrieveHandler, "retrieve slave zone", "<zone> [<ip>]");
-    DynListener::registerFunc("CURRENT-CONFIG",&DLCurrentConfigHandler, "retrieve the current configuration", "[diff]");
-    DynListener::registerFunc("LIST-ZONES", &DLListZones, "show list of zones", "[primary|secondary|native]");
-    DynListener::registerFunc("TOKEN-LOGIN", &DLTokenLogin, "Login to a PKCS#11 token", "<module> <slot> <pin>");
-    DynListener::registerFunc("XFR-QUEUE", &DLSuckRequests, "Get all requests for XFR in queue");
-
-    if(!::arg()["tcp-control-address"].empty()) {
-      DynListener* dlTCP=new DynListener(ComboAddress(::arg()["tcp-control-address"], ::arg().asNum("tcp-control-port")));
-      dlTCP->go();
-    }
-
-    // reparse, with error checking
-    if(!::arg().mustDo("no-config"))
-      ::arg().file(configname.c_str());
-    ::arg().parse(argc,argv);
-
-    if(::arg()["server-id"].empty()) {
-      char tmp[128];
-      if(gethostname(tmp, sizeof(tmp)-1) == 0) {
-        ::arg().set("server-id")=tmp;
-      } else {
-        g_log<<Logger::Warning<<"Unable to get the hostname, NSID and id.server values will be empty: "<<stringerror()<<endl;
-      }
-    }
-
-    UeberBackend::go();
-
-    g_zoneCache.setRefreshInterval(::arg().asNum("zone-cache-refresh-interval"));
-    {
-      UeberBackend B;
-      B.updateZoneCache();
-    }
-
-    N=std::make_shared<UDPNameserver>(); // this fails when we are not root, throws exception
-    g_udpReceivers.push_back(N);
-
-    size_t rthreads = ::arg().asNum("receiver-threads", 1);
-    if (rthreads > 1 && N->canReusePort()) {
-      g_udpReceivers.resize(rthreads);
-
-      for (size_t idx = 1; idx < rthreads; idx++) {
-        try {
-          g_udpReceivers[idx] = std::make_shared<UDPNameserver>(true);
-        }
-        catch(const PDNSException& e) {
-          g_log<<Logger::Error<<"Unable to reuse port, falling back to original bind"<<endl;
-          break;
-        }
-      }
-    }
-
-    TN = make_unique<TCPNameserver>();
-  }
-  catch(const ArgException &A) {
-    g_log<<Logger::Error<<"Fatal error: "<<A.reason<<endl;
-    exit(1);
-  }
-  
-  try {
-    declareStats();
-  }
-  catch(PDNSException &PE) {
-    g_log<<Logger::Error<<"Exiting because: "<<PE.reason<<endl;
-    exit(1);
-  }
-  S.blacklist("special-memory-usage");
-
-  DLOG(g_log<<Logger::Warning<<"Verbose logging in effect"<<endl);
-
-  showProductVersion();
-
-  try {
-    mainthread();
-  }
-  catch(PDNSException &AE) {
-    if(!::arg().mustDo("daemon"))
-      cerr<<"Exiting because: "<<AE.reason<<endl;
-    g_log<<Logger::Error<<"Exiting because: "<<AE.reason<<endl;
-  }      
-  catch(std::exception &e) {
-    if(!::arg().mustDo("daemon"))
-      cerr<<"Exiting because of STL error: "<<e.what()<<endl;
-    g_log<<Logger::Error<<"Exiting because of STL error: "<<e.what()<<endl;
-  }
-  catch(...) {
-    cerr<<"Uncaught exception of unknown type - sorry"<<endl;
-  }
-
-  exit(1);
-  
-}
-
-
index a8ba80a0d5cd4cf990acc35ff556bd6884f2f852..fcb47be130f54cdf9e5dfa082252f1251e81ef0c 100644 (file)
@@ -43,7 +43,7 @@
 #include "base64.hh"
 #include "inflighter.cc"
 #include "namespaces.hh"
-#include "common_startup.hh"
+#include "auth-main.hh"
 #include "query-local-address.hh"
 
 #include "ixfr.hh"
index 75ccde36f553db0848ccae8dbfbe6e79a85f99c3..baa06ea6384e7e8cb55908296abce431dbea32c3 100644 (file)
@@ -51,7 +51,7 @@
 #include "logger.hh"
 #include "arguments.hh"
 
-#include "common_startup.hh"
+#include "auth-main.hh"
 #include "packethandler.hh"
 #include "statbag.hh"
 #include "communicator.hh"
index 09888351620bc6b830b44374bad6a39cb88c5f43..9aca8ca2fb7016990699307750e2ba26b1317227 100644 (file)
@@ -42,7 +42,7 @@
 #include "dnsseckeeper.hh"
 #include <iomanip>
 #include "zoneparser-tng.hh"
-#include "common_startup.hh"
+#include "auth-main.hh"
 #include "auth-caches.hh"
 #include "auth-zonecache.hh"
 #include "threadname.hh"