]> granicus.if.org Git - pdns/commitdiff
trim some build dependencies, make rec_control/pdns_recursor grok /var/run as place...
authorBert Hubert <bert.hubert@netherlabs.nl>
Sun, 26 Mar 2006 22:16:00 +0000 (22:16 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sun, 26 Mar 2006 22:16:00 +0000 (22:16 +0000)
add tcp-questions in all the right places, add callback so 'rec_control quit' gets a response before the program quits

git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@631 d19b8d6e-7fed-0310-83ef-9ca221ded41b

12 files changed:
pdns/Makefile.am
pdns/dynloader.cc
pdns/lwres.cc
pdns/pdns_recursor.cc
pdns/rec_channel.cc
pdns/rec_channel.hh
pdns/rec_channel_rec.cc
pdns/rec_control.cc
pdns/syncres.hh
pdns/tools/rrd/create
pdns/tools/rrd/makegraphs
pdns/tools/rrd/update

index 68189fa67821da7fb5c2aca2d82029defd1b50a0..3c573a040ef3faf96588fc764e5f8be059fa9b06 100644 (file)
@@ -89,11 +89,11 @@ dnsscope_LDFLAGS= @DYNLINKFLAGS@ @THREADFLAGS@
 
 # INCLUDES=-I/usr/include/mysql
 
-rec_control_SOURCES=rec_channel.cc rec_channel.hh rec_control.cc
+rec_control_SOURCES=rec_channel.cc rec_channel.hh rec_control.cc arguments.cc arguments.hh
 
 pdns_recursor_SOURCES=syncres.cc resolver.hh misc.cc unix_utility.cc qtype.cc \
-logger.cc statbag.cc dnspacket.cc arguments.cc  lwres.cc pdns_recursor.cc lwres.hh \
-mtasker.hh sillyrecords.cc syncres.hh recursor_cache.cc recursor_cache.hh dnsparser.cc \
+logger.cc statbag.cc arguments.cc  lwres.cc pdns_recursor.cc lwres.hh \
+mtasker.hh syncres.hh recursor_cache.cc recursor_cache.hh dnsparser.cc \
 dnswriter.cc dnswriter.hh dnsrecords.cc dnsrecords.hh rcpgenerator.cc rcpgenerator.hh \
 base64.cc base64.hh zoneparser-tng.cc zoneparser-tng.hh rec_channel.cc rec_channel.hh \
 rec_channel_rec.cc
index d976f504d32e981786b642291cbfdfda544b2acf..1012114c7bc93ee1cf86afab905aaccfabf106a1 100644 (file)
@@ -67,7 +67,6 @@ int main(int argc, char **argv)
     exit(99);
   }
 
-
   if(arg()["config-name"]!="") 
     s_programname+="-"+arg()["config-name"];
 
@@ -81,7 +80,6 @@ int main(int argc, char **argv)
   else
     localdir=dirname(strdup(socketname.c_str()));
 
-
   const vector<string>&commands=arg().getCommands();
 
   if(commands.empty()) {
index 1dab630ec738d94fa2104a3e76d4ea1547fe45db..99753dc807e329a4b29893ca3bdc3c4ab7e0707d 100644 (file)
 #include <cstring>
 #include <string>
 #include <vector>
-#include "dnspacket.hh"
 #include "dns.hh"
 #include "qtype.hh"
-#include "tcpreceiver.hh"
 #include "ahuexception.hh"
 #include "statbag.hh"
 #include "arguments.hh"
index 49794b3899f51473566c36d470ef764a9c0a9107..a2a75ed98dde9b89d866427ff1bd44478f7966d6 100644 (file)
@@ -31,7 +31,6 @@
 #include <unistd.h>
 #include "mtasker.hh"
 #include <utility>
-#include "dnspacket.hh"
 #include "statbag.hh"
 #include "arguments.hh"
 #include "syncres.hh"
@@ -47,6 +46,7 @@
 #include "dnsrecords.hh"
 #include "zoneparser-tng.hh"
 #include "rec_channel.hh"
+#include "logger.hh"
 
 using namespace boost;
 
@@ -374,7 +374,7 @@ RecursorControlChannel s_rcc;
 
 void makeControlChannelSocket()
 {
-  s_rcc.listen("pdns_recursor.controlsocket");
+  s_rcc.listen(::arg()["socket-dir"]+"/pdns_recursor.controlsocket");
 }
 
 void makeClientSocket()
@@ -497,7 +497,7 @@ void daemonize(void)
 }
 #endif
 
-uint64_t counter, qcounter;
+uint64_t counter;
 bool statsWanted;
 
 
@@ -518,8 +518,8 @@ void usr2Handler(int)
 
 void doStats(void)
 {
-  if(qcounter) {
-    L<<Logger::Error<<"stats: "<<qcounter<<" questions, "<<RC.size()<<" cache entries, "<<SyncRes::s_negcache.size()<<" negative entries, "
+  if(g_stats.qcounter) {
+    L<<Logger::Error<<"stats: "<<g_stats.qcounter<<" questions, "<<RC.size()<<" cache entries, "<<SyncRes::s_negcache.size()<<" negative entries, "
      <<(int)((RC.cacheHits*100.0)/(RC.cacheHits+RC.cacheMisses))<<"% cache hits"<<endl;
     L<<Logger::Error<<"stats: throttle map: "<<SyncRes::s_throttle.size()<<", ns speeds: "
      <<SyncRes::s_nsSpeeds.size()<<endl; // ", bytes: "<<RC.bytes()<<endl;
@@ -833,7 +833,10 @@ int main(int argc, char **argv)
        string remote;
        string msg=s_rcc.recv(&remote);
        RecursorControlParser rcp;
-       s_rcc.send(rcp.getAnswer(msg), &remote);
+       RecursorControlParser::func_t* command;
+       string answer=rcp.getAnswer(msg, &command);
+       s_rcc.send(answer, &remote);
+       command();
       }
 
       if(FD_ISSET(d_clientsock,&readfds)) { // do we have a UDP question response?
@@ -876,7 +879,7 @@ int main(int argc, char **argv)
            if(dc->d_mdp.d_header.qr)
              L<<Logger::Error<<"Ignoring answer on server socket!"<<endl;
            else {
-             ++qcounter;
+             ++g_stats.qcounter;
              dc->setSocket(*i);
              dc->d_tcp=false;
              MT->makeThread(startDoResolve, (void*) dc, "udp");
@@ -1026,7 +1029,8 @@ int main(int argc, char **argv)
              if(dc->d_mdp.d_header.qr)
                L<<Logger::Error<<"Ignoring answer on server socket!"<<endl;
              else {
-               ++qcounter;
+               ++g_stats.qcounter;
+               ++g_stats.tcpqcounter;
                MT->makeThread(startDoResolve, dc, "tcp");
              }
            }
index a8f6fcc4dc0beae985582b191d85b2f47303f6d5..2fbc01e19a97163577114a12b93ed69776c9c135 100644 (file)
@@ -32,12 +32,12 @@ int RecursorControlChannel::listen(const string& fname)
   strcpy(local.sun_path, fname.c_str());
     
   if(bind(d_fd, (sockaddr*)&local,sizeof(local))<0) 
-    throw AhuException("Unable to bind to controlsocket: "+string(strerror(errno)));
+    throw AhuException("Unable to bind to controlsocket '"+fname+"': "+string(strerror(errno)));
 
   return d_fd;
 }
 
-void RecursorControlChannel::connect(const string& fname)
+void RecursorControlChannel::connect(const string& path, const string& fname)
 {
   struct sockaddr_un local, remote;
 
@@ -50,12 +50,15 @@ void RecursorControlChannel::connect(const string& fname)
   if(setsockopt(d_fd, SOL_SOCKET, SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0)
     throw AhuException(string("Setsockopt failed: ")+strerror(errno));
   
-  string localname="./blah";
+  string localname=path+"/lsockXXXXXX";
+  strcpy(local.sun_path, localname.c_str());
+
+  if(mkstemp(local.sun_path) < 0)
+    throw AhuException("Unable to generate local temporary file in directory '"+path+"': "+string(strerror(errno)));
 
   local.sun_family=AF_UNIX;
-  strcpy(local.sun_path,localname.c_str());
 
-  int err=unlink(localname.c_str());
+  int err=unlink(local.sun_path);
   if(err < 0 && errno!=ENOENT)
     throw AhuException("Unable to remove local controlsocket: "+string(strerror(errno)));
 
@@ -72,10 +75,10 @@ void RecursorControlChannel::connect(const string& fname)
   memset(&remote,0,sizeof(remote));
   
   remote.sun_family=AF_UNIX;
-  strcpy(remote.sun_path,fname.c_str());
+  strcpy(remote.sun_path,(path+"/"+fname).c_str());
   if(::connect(d_fd, (sockaddr*)&remote, sizeof(remote)) < 0) {
     unlink(local.sun_path);
-    throw AhuException("Unable to connect to remote '"+fname+"': "+string(strerror(errno)));
+    throw AhuException("Unable to connect to remote '"+path+fname+"': "+string(strerror(errno)));
   }
 }
 
index b95c2c97a02ac3483721983f0eebabcea6a82e52..9d14d84d5a9afc63e0d0daa7c9341c5f811bb047 100644 (file)
@@ -9,7 +9,7 @@ class RecursorControlChannel
 {
 public:
   int listen(const std::string& filename);
-  void connect(const std::string& filename);
+  void connect(const std::string& path, const std::string& filename);
 
   uint64_t getStat(const std::string& name);
 
@@ -23,7 +23,9 @@ class RecursorControlParser
 {
 public:
   RecursorControlParser();
-  std::string getAnswer(const std::string& question);
+  static void nop(void){}
+  typedef void func_t(void);
+  std::string getAnswer(const std::string& question, func_t** func);
 
 };
 
index e63cf9beba02322941c2be205bf0da91b4dbf0be..8c4106e7152a078e34c7f6d091c2d05da90fde40 100644 (file)
@@ -11,6 +11,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include "logger.hh"
 
 using namespace std;
 using namespace boost;
@@ -98,15 +99,15 @@ uint32_t getQueryRate()
   gettimeofday(&now, 0);
   optional<float> delay=g_stats.queryrate.get(now, 10);
   if(delay)
-    return 1000000/(*delay);
+    return (uint32_t)(1000000/(*delay));
   else
     return 0;
 }
 
 RecursorControlParser::RecursorControlParser()
 {
-  extern uint64_t qcounter;
-  addGetStat("questions", &qcounter);
+  addGetStat("questions", &g_stats.qcounter);
+  addGetStat("tcp-questions", &g_stats.tcpqcounter);
 
   addGetStat("cache-hits", &RC.cacheHits);
   addGetStat("cache-misses", &RC.cacheMisses);
@@ -124,7 +125,6 @@ RecursorControlParser::RecursorControlParser()
 
   addGetStat("qa-latency", &g_stats.avgLatencyUsec);
 
-  addGetStat("all-questions", &qcounter);
   addGetStat("negcache-entries", boost::bind(&SyncRes::negcache_t::size, ref(SyncRes::s_negcache)));
   addGetStat("throttle-entries", boost::bind(&SyncRes::throttle_t::size, ref(SyncRes::s_throttle)));
   addGetStat("nsspeeds-entries", boost::bind(&SyncRes::nsspeeds_t::size, ref(SyncRes::s_nsSpeeds)));
@@ -139,13 +139,20 @@ RecursorControlParser::RecursorControlParser()
   addGetStat("query-rate", getQueryRate);
 }
 
-string RecursorControlParser::getAnswer(const string& question)
+static void doExit()
 {
+  L<<Logger::Error<<"Exiting on user request"<<endl;
+  exit(1);
+}
+
+string RecursorControlParser::getAnswer(const string& question, RecursorControlParser::func_t** command)
+{
+  *command=nop;
   vector<string> words;
   stringtok(words, question);
 
   if(words.empty())
-    return "invalid command";
+    return "invalid command\n";
 
   string cmd=toLower(words[0]);
   vector<string>::const_iterator begin=words.begin()+1, end=words.end();
@@ -153,8 +160,10 @@ string RecursorControlParser::getAnswer(const string& question)
   if(cmd=="get") 
     return doGet(begin, end);
 
-  if(cmd=="quit") 
-    exit(1);
+  if(cmd=="quit") {
+    *command=&doExit;
+    return "bye\n";
+  }
 
   if(cmd=="dump-cache") 
     return doDumpCache(begin, end);
index 8e6af87c7d5cc32a1cb66d97cf4cd7cad3f4fd3b..6090225b28eb7be14e5c2cddcd7560fe46c19ec8 100644 (file)
@@ -1,27 +1,65 @@
+/*
+    PowerDNS Versatile Database Driven Nameserver
+    Copyright (C) 2006 PowerDNS.COM BV
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2 as 
+    published by the Free Software Foundation
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
 #include "rec_channel.hh"
 #include <iostream>
 #include "ahuexception.hh"
+#include "arguments.hh"
 
 using namespace std;
 
+ArgvMap &arg()
+{
+  static ArgvMap arg;
+  return arg;
+}
+
+static void initArguments(int argc, char** argv)
+{
+  arg().set("config-dir","Location of configuration directory (pdns.conf)")=SYSCONFDIR;
+  arg().set("socket-dir","Where the controlsocket will live")=LOCALSTATEDIR;
+  arg().setCmd("help","Provide this helpful message");
+
+  arg().laxParse(argc,argv);  
+  if(arg().mustDo("help")) {
+    cerr<<"syntax:"<<endl<<endl;
+    cerr<<arg().helpstring(arg()["help"])<<endl;
+    exit(99);
+  }
+
+}
+
 int main(int argc, char** argv)
 try
 {
+  initArguments(argc, argv);
+
   RecursorControlChannel rccS;
-  rccS.connect("pdns_recursor.controlsocket");
+  rccS.connect(arg()["socket-dir"], "pdns_recursor.controlsocket");
 
+  const vector<string>&commands=arg().getCommands();
   string command;
-  for(int i=1; i< argc; ++i) {
-    if(i>1)
+  for(int i=0; i< commands.size(); ++i) {
+    if(i>0)
       command+=" ";
-    command+=argv[i];
+    command+=commands[i];
   }
-
-
   rccS.send(command);
-
   string receive=rccS.recv();
-  
   cout<<receive;
 }
 catch(AhuException& ae)
index f11eafcaad4b502a0e9bd3a05a94e085f183f330..a702e898ba3e41b14d3b6960fd8f71668d000b25 100644 (file)
@@ -335,7 +335,6 @@ struct PacketID
 };
 
 extern MemRecursorCache RC;
-extern uint64_t qcounter;
 extern MTasker<PacketID,string>* MT;
 
 struct RecursorStats
@@ -346,6 +345,8 @@ struct RecursorStats
   PulseRate queryrate;
   uint64_t answers0_1, answers1_10, answers10_100, answers100_1000, answersSlow;
   uint64_t avgLatencyUsec;
+  uint64_t qcounter;
+  uint64_t tcpqcounter;
 };
 
 extern RecursorStats g_stats;
index 7bf289fcc7c19e7293dcd00786d6a3bd28071932..74deedcf41d7704d04630d2aa3442eff223c1c5a 100755 (executable)
@@ -1,5 +1,6 @@
 rrdtool create pdns_recursor.rrd -s 60 \
 DS:questions:COUNTER:600:0:100000 \
+DS:tcp-questions:COUNTER:600:0:100000 \
 DS:cache-entries:GAUGE:600:0:U \
 DS:throttle-entries:GAUGE:600:0:U \
 DS:concurrent-queries:GAUGE:600:0:50000 \
index a9e4c3e70b46ffb264bf2c6305c2ea4ace9cb210..d69705f9db3a4dcd34072aec2505fe0e8be09da3 100755 (executable)
@@ -17,6 +17,12 @@ function makeGraphs()
         STACK:nxdomainanswers#ffa500:"nxdomain answers/s"\
         STACK:servfailanswers#ff0000:"servfail answers/s"
 
+  rrdtool graph --start -$1 $WWWPREFIX/tcp-questions-$2.png -w $WSIZE -h $HSIZE -l 0\
+       -t "TCP question and answer counts per second" \
+       -v "packets" \
+       DEF:tcpquestions=pdns_recursor.rrd:tcp-questions:AVERAGE  \
+        LINE2:tcpquestions#0000ff:"questions/s"\
+
   rrdtool graph --start -$1 $WWWPREFIX/latencies-$2.png -w $WSIZE -h $HSIZE -l 0\
        -t "Questions answered within latency" \
        -v "questions" \
index caa905eaa36132c5b3a62d24bb27c1341df487a2..5c219920c8524fb03797193547a0955ead62c087 100755 (executable)
@@ -1,17 +1,16 @@
 #!/bin/bash
 TSTAMP=$(date +%s)
-cd ../..
 
-VARIABLES="questions cache-entries concurrent-queries\
+VARIABLES="questions tcp-questions cache-entries concurrent-queries\
           nxdomain-answers noerror-answers\
           servfail-answers tcp-outqueries\
           outgoing-timeouts nsspeeds-entries negcache-entries all-outqueries throttled-out\
           cache-hits cache-misses answers0-1 answers1-10 answers10-100 answers100-1000 answers-slow\
        qa-latency throttle-entries"
 
-UVARIABLES=$(echo $VARIABLES | tr '[a-z]' '[A-Z]' | tr - _     )
+UVARIABLES=$(echo $VARIABLES | tr '[a-z]' '[A-Z]' | tr - _ )
 
-./rec_control GET $VARIABLES |
+rec_control GET $VARIABLES |
 (
   for a in $UVARIABLES
   do