]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
more pdns recursor stats
authorBert Hubert <bert.hubert@netherlabs.nl>
Thu, 23 Jan 2003 15:34:53 +0000 (15:34 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Thu, 23 Jan 2003 15:34:53 +0000 (15:34 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@140 d19b8d6e-7fed-0310-83ef-9ca221ded41b

ChangeLog
configure.in
pdns/backends/gsql/gsqlbackend.cc
pdns/dnspacket.cc
pdns/docs/pdns.sgml
pdns/packethandler.cc
pdns/pdns_recursor.cc
pdns/syncres.hh

index e5c2537f00cbe519419800147b3f384bda3db613..f662b7989e49317c8756dbb2cec54473bd94c073 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,7 @@ Changes since 2.9.4:
        - UltraSparc alignment issues Chris Andrews
        - compression (Mark Bergsma)
        - SRV records (Ueli Heuer)
+       - updated J root-server IP address in the recursor
        
 Changes since 2.9.3a:
 feat   - make *all* sql in gsqlbackends available for configuration (Martin Klebermass/bert hubert)
index fd7692066162f123f6d2001f5cb09672746792be..4e21df632a3a5ee2fbc80d6ad847dee396bb4546 100644 (file)
@@ -1,6 +1,6 @@
 dnl intro
 AC_INIT(pdns/receiver.cc)
-AM_INIT_AUTOMAKE(pdns, 2.9.4)
+AM_INIT_AUTOMAKE(pdns, 2.9.5)
 AC_CANONICAL_HOST
 AM_CONFIG_HEADER(config.h)
 AC_C_BIGENDIAN 
index e8f3f4abd44277818724ae6218f3a3f97e9ccee6..9e9fd06ec5e04e0b0293ed2057c73cbd41a793fb 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: gsqlbackend.cc,v 1.5 2003/01/02 20:15:26 ahu Exp $ 
+// $Id: gsqlbackend.cc,v 1.6 2003/01/23 15:34:53 ahu Exp $ 
 #include <string>
 #include <map>
 
@@ -370,6 +370,7 @@ bool GSQLBackend::get(DNSResourceRecord &r)
     else
       r.qname=row[5];
     r.qtype=row[3];
+    r.last_modified=0;
     
     r.domain_id=atoi(row[4].c_str());
     return true;
index 9394d4f2b1e4562129414a91aa1b1ede69e3f6bf..59228c07f42c6bbea69612c4b7613ee50bef8027 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-// $Id: dnspacket.cc,v 1.15 2003/01/21 15:04:02 ahu Exp $
+// $Id: dnspacket.cc,v 1.16 2003/01/23 15:34:53 ahu Exp $
 #include "utility.hh"
 #include <cstdio>
 
@@ -304,16 +304,7 @@ void DNSPacket::addMXRecord(const string &domain, const string &mx, int priority
   toqname(domain,&piece1);
 
   char piece2[12];
-
-  piece2[0]=0;
-
-  piece2[1]=15; // MX
-  piece2[2]=0;
-  piece2[3]=1; // IN
-
-  putLong(piece2+4,ttl);
-  piece2[8]=0;
-  piece2[9]=0;  // need to fill this in
+  makeHeader(piece2,QType::MX,ttl);
 
   // start of payload for which we need to specify the length in 8 & 9
 
@@ -526,15 +517,7 @@ void DNSPacket::addSOARecord(const string &domain, const string & content, u_int
   toqname(domain, &piece1);
 
   char p[10];
-  
-  p[0]=0;
-  p[1]=6; // SOA
-  p[2]=0;
-  p[3]=1; // IN
-  
-  putLong(p+4,ttl);
-  p[8]=0;
-  p[9]=0;  // need to fill this in (length)
+  makeHeader(p,QType::SOA,ttl);
   
   string piece3;  
   toqname(soadata.nameserver,&piece3, false);
@@ -615,16 +598,7 @@ void DNSPacket::addRPRecord(const string &domain, const string &content, u_int32
 
  toqname(domain.c_str(),&piece1);
  char p[10];
- p[0]=0;
- p[1]=17; // RP
- p[2]=0;
- p[3]=1; // IN
- putLong(p+4,ttl);
-
- p[8]=0;
- p[9]=0;  // need to fill this in
+ makeHeader(p,17,ttl);
  
  // content contains: mailbox-name more-info-domain (Separated by a space)
  unsigned int pos;
@@ -835,9 +809,6 @@ void DNSPacket::addHINFORecord(string domain, string content, u_int32_t ttl)
   char p[10];
   makeHeader(p,QType::HINFO,ttl);
   
-  p[8]=0;
-  p[9]=0; // need to fill this in
-  
   unsigned int offset=content.find(" ");
   string cpu, host;
   if(offset==string::npos) {
@@ -879,15 +850,7 @@ void DNSPacket::addNSRecord(string domain, string server, u_int32_t ttl, DNSReso
   toqname(domain, &piece1);
 
   char p[10];
-
-  p[0]=0;
-  p[1]=2; // NS
-  p[2]=0;
-  p[3]=1; // IN
-  putLong(p+4,ttl);
-
-  p[8]=0;
-  p[9]=0;  // need to fill this in
+  makeHeader(p,QType::NS,ttl);
 
   string piece3;
   string::size_type pos=server.find('@'); // chop off @
index 41ceab5489f7b7752f52bf1b156bd4e4d772044e..827be45d7505e4feeb7dc9e2b8d48a5b93da6bfe 100644 (file)
@@ -11,7 +11,7 @@
       </affiliation>
     </author>
     
-    <PubDate>v2.1 $Date: 2003/01/21 15:04:02 $</PubDate>
+    <PubDate>v2.1 $Date: 2003/01/23 15:34:53 $</PubDate>
     
     <Abstract>
        <para>  
          for example. Cooperation between the both halves of PDNS is also almost seamless. As a result, 'non-lazy recursion' has been dropped. See
          <xref linkend="recursion"> for more details.
        </para>
+       <para>
+         Furthermore, the recursor only works on Linux and Solaris (probably, untested). FreeBSD does not support the required functions.
+         If you know any important FreeBSD people, plea with them to support set/get/swapcontext!
+       </para>
        <para>
          The 'Contributor of the Month' award goes to Mark Bergsma who has responded to our plea for help with the label compressor and contributed
          a wonderfully simple and right fix that allows PDNS to compress just as well as Other namerervers out there. An honorary mention goes to
                Yet more UltraSPARC alignment issues fixed (Chris Andrews).
              </para>
            </listitem>
+           <listitem>
+             <para>
+               Dropped non-lazy recursion, nobody was using it.
+             </para>
+           </listitem>
            <listitem>
              <para>
                Label compression was improved so we can now fit all . records in 436 bytes, this used to be 460! (Code &amp; formal 
                SRV support (incoming and outgoing), submitted by Ueli Heuer.
              </para>
            </listitem>
+           <listitem>
+             <para>
+               Generic backends do not support SOA serial autocalculation, it appears. Could lead to random SOA serials in case 
+               of a serial of 0 in the database. Fixed so that 0 stays zero in that case. Don't set the SOA serial to 0 when using 
+               Generic MySQL or Generic PostgreSQL!
+             </para>
+           </listitem>
          </itemizedlist>
        </para>
       </sect2>
@@ -3238,11 +3254,11 @@ name         IN            A        1.2.3.4
 
          mysql> CREATE TABLE records (
          id int(11) NOT NULL auto_increment,
-         domain_id int(11) default NULL,
-         name varchar(255) default NULL,
-         type varchar(6) default NULL,
+         domain_id int(11) NOT NULL,
+         name varchar(255) NOT NULL,
+         type varchar(6) NOT NULL,
          content varchar(255) default NULL,
-         ttl int(11) default NULL,
+         ttl int(11) NOT NULL,
          prio int(11) default NULL,
          change_date int(11) default NULL,
          PRIMARY KEY (id),
@@ -4012,118 +4028,121 @@ local0.err                        /var/log/pdns.err
        not proceed from the authoritative database.
       </para>
     </sect1>
-    <sect1 id="built-in-recursor"><title>PowerDNS resolver/recursing nameserver</title>
+  </chapter>
+  <chapter id="built-in-recursor"><title>PowerDNS resolver/recursing nameserver</title>
+    <para>
+      As of 2.9.4, a small recursor comes with PowerDNS. The algorithm is influenced by the works of Dan J. Bernstein although
+      all mistakes are ours. Here are the current faults, so nobody can accuse us of false advertising:
+      <itemizedlist>
+       <listitem><para>
+           Only ignores stale cache entries, does not actually clean them up. May replace them with newer data, however.
+         </para></listitem>
+       <listitem><para>
+           Only compiles on Linux and possibly Solaris. FreeBSD 4.x decided not to support the 
+           POSIX get/set/swapcontext functions. Bug your favorite FreeBSD kernel or libc maintainer for a fix,
+           or ask him to port MTasker (see below) to your operating system.
+         </para></listitem>
+       <listitem<para>
+           It does not do TCP yet, and may have big problems with truncated packets.
+         </para></listitem>
+      </itemizedlist>
+    </para>
+    <para>
+      To compile, add <command>--enable-recursor</command> to configure and the file <filename>pdns_recursor</filename> will be 
+      compiled. To run on a different port, use <command>./syncres --local-port=53</command>.
+      To bind to another address, use the <command>local-address</command> setting.
+    </para>
+    <para>
+      <note>
+       <para>
+         PowerDNS author bert hubert has the pdns recursor in production and browsing with it works for him. Furthermore, the LARTC
+         mailinglist (2000 subscribers) is using the pdns recursing nameserver. 
+       </para>
+      </note>
+    </para>
+    <para>
+      Good points:
+      <itemizedlist>
+       <listitem><para>
+           Uses MTasker (<ulink url="http://ds9a.nl/mtasker">homepage</ulink>)
+         </para></listitem>
+       <listitem><para>
+           Can handle thousands of concurrent questions
+         </para></listitem>
+       <listitem><para>
+           Code is written linearly, sequentially, which means that there are no problems with 'query restart' or anything.
+         </para></listitem>
+       <listitem><para>
+           Relies heavily on Standard C++ Library infrastructure, which makes for little code (406 core lines).
+         </para></listitem>
+       <listitem><para>
+           Is very verbose in showing how recursion actually works.
+         </para></listitem>
+       <listitem><para>
+           The algorithm is simple and quite nifty.
+         </para></listitem>
+      </itemizedlist>
+    </para>
+    <sect1><title>pdns_recursor settings</title>
       <para>
-       As of 2.9.4, a small recursor comes with PowerDNS. The algorithm is influenced by the works of Dan J. Bernstein although
-       all mistakes are ours. Here are the current faults, so nobody can accuse us of false advertising:
-       <itemizedlist>
-         <listitem><para>
-             Only ignores stale cache entries, does not actually clean them up. May replace them with newer data, however.
-           </para></listitem>
-         <listitem><para>
-             Only compiles on Linux and possibly Solaris. FreeBSD 4.x decided not to support the 
-             POSIX get/set/swapcontext functions. Bug your favorite FreeBSD kernel or libc maintainer for a fix,
-             or ask him to port MTasker (see below) to your operating system.
-           </para></listitem>
-         <listitem<para>
-             It does not do TCP yet, and may have big problems with truncated packets.
-           </para></listitem>
-       </itemizedlist>
+       At startup, the recursing nameserver reads the file <filename>recursor.conf</filename> from the configuration directory,
+       often <filename>/etc/powerdns</filename> or <filename>/usr/local/etc</filename>.
       </para>
       <para>
-       To compile, add <command>--enable-recursor</command> to configure and the file <filename>pdns_recursor</filename> will be 
-       compiled. To run on a different port, use <command>./syncres --local-port=53</command>.
-       To bind to another address, use the <command>local-address</command> setting.
-      </para>
+       The following settings can be configured:
+       <variablelist>
+         <varlistentry>
+           <term>aaaa-additional-processing</term>
+           <listitem>
+             <para>
+               If turned on, the recursor will attempt to add AAAA IPv6 records to questions for MX records and NS records.
+               Can be quite slow as absence of these records in earlier answers does not guarantee their non-existance. Can double
+               the amount of queries needed. Off by default.
+             </para>
+           </listitem>
+         </varlistentry>
+         <varlistentry>
+           <term>daemon</term>
+           <listitem>
+             <para>
+               Operate in the background, which is the default.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry>
+           <term>local-address</term>
+           <listitem>
+             <para>
+               Local IP address (singular) to bind to. Defaults to all addresses.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry>
+           <term>local-port</term>
+           <listitem>
+             <para>
+               Local port (singular) to bind to. Defaults to 53.
+             </para>
+           </listitem>
+         </varlistentry>
+         <varlistentry>
+           <term>trace</term>
+           <listitem>
+             <para>
+               If turned on, output impressive heaps of logging. May destroy performance under load.
+             </para>
+           </listitem>
+         </varlistentry>
+       </variablelist>
       <para>
-       <note>
-         <para>
-           PowerDNS author bert hubert has the pdns recursor in production and browsing with it works for him. Furthermore, the LARTC
-           mailinglist (2000 subscribers) is using the pdns recursing nameserver. 
-         </para>
-       </note>
-      </para>
+    </sect1>
+    <sect1><title>Statistics</title>
       <para>
-       Good points:
-       <itemizedlist>
-         <listitem><para>
-             Uses MTasker (<ulink url="http://ds9a.nl/mtasker">homepage</ulink>)
-           </para></listitem>
-         <listitem><para>
-             Can handle thousands of concurrent questions
-           </para></listitem>
-         <listitem><para>
-             Code is written linearly, sequentially, which means that there are no problems with 'query restart' or anything.
-           </para></listitem>
-         <listitem><para>
-             Relies heavily on Standard C++ Library infrastructure, which makes for little code (406 core lines).
-           </para></listitem>
-         <listitem><para>
-             Is very verbose in showing how recursion actually works.
-           </para></listitem>
-         <listitem><para>
-             The algorithm is simple and quite nifty.
-           </para></listitem>
-       </itemizedlist>
+       Every half our or so, the recursor outputs a line with statistics. More infrastructure is planned so as to allow
+       for Cricket or MRTG graphs.
       </para>
-      <sect2><title>pdns_recursor settings</title>
-       <para>
-         <variablelist>
-           <varlistentry>
-             <term>aaaa-additional-processing</term>
-             <listitem>
-               <para>
-                 If turned on, the recursor will attempt to add AAAA IPv6 records to questions for MX records and NS records.
-                 Can be quite slow as absence of these records in earlier answers does not guarantee their non-existance. Can double
-                 the amount of queries needed.
-               </para>
-             </listitem>
-           </varlistentry>
-           <varlistentry>
-             <term>daemon</term>
-             <listitem>
-               <para>
-                 Operate in the background.
-               </para>
-             </listitem>
-           </varlistentry>
-
-           <varlistentry>
-             <term>local-address</term>
-             <listitem>
-               <para>
-                 Local IP address (singular) to bind to.
-               </para>
-             </listitem>
-           </varlistentry>
-
-           <varlistentry>
-             <term>local-port</term>
-             <listitem>
-               <para>
-                 Local port (singular) to bind to. Defaults to 5300!
-               </para>
-             </listitem>
-           </varlistentry>
-           <varlistentry>
-             <term>local-port</term>
-             <listitem>
-               <para>
-                 Local port (singular) to bind to. Defaults to 5300!
-               </para>
-             </listitem>
-           </varlistentry>
-           <varlistentry>
-             <term>trace</term>
-             <listitem>
-               <para>
-                 If turned on, output impressive heaps of logging. May destroy performance under load.
-               </para>
-             </listitem>
-           </varlistentry>
-         </variablelist>
-       <para>
-      </sect2>
     </sect1>
   </chapter>
   <chapter id="replication"><title>Master/Slave operation &amp; replication</title>
@@ -4978,6 +4997,30 @@ local0.err                        /var/log/pdns.err
              </para>
            </listitem>
          </varlistentry>
+         <varlistentry>
+           <term>Q: Can I use a MySQL database with the Windows version of PowerDNS?</term>
+           <listitem>
+             <para>
+               A: You can. MySQL support is supplied through the ODBC backend, which is compiled into the main binary.
+               So if you want to use MySQL you can change the pdns.conf file, which is located in the PowerDNS for Windows directory, to use the 
+               correct ODBC data sources.
+
+               If you don't know how to use ODBC with MySQL:
+               <itemizedlist>
+                 <listitem><para>
+                     Download MyODBC from <ulink url="http://www.mysql.com/">http://www.mysql.com/</ulink>
+                   </para></listitem>
+                 <listitem><para>
+                     Install the MySQL ODBC driver.
+                   </para></listitem>
+               </itemizedlist>
+               Then you can follow the instructions located in <xref linkend="windows">.
+               But instead of selecting the Microsoft Access Driver you select the MySQL ODBC Driver and configure it to use your MySQL database.
+    
+               <note><para>For other databases for which an ODBC driver is available, the procedure is the same as this example.</para></note>
+             </para>
+           </listitem>
+         </varlistentry>
        </variablelist>
       </para>
     <sect1 id="pdns-devel-faq"><title>Backend developer HOWTO</title>
@@ -5540,11 +5583,11 @@ while(&lt;&gt;)
         <screen>
           CREATE TABLE records (
          id int(11) NOT NULL auto_increment,
-         domain_id int(11) default NULL,
-         name varchar(255) default NULL,
-         type varchar(6) default NULL,
-         content varchar(255) default NULL,
-         ttl int(11) default NULL,
+         domain_id int(11) NOT NULL,
+         name varchar(255) NOT NULL,
+         type varchar(6) NOT NULL,
+         content varchar(255) NOT NULL,
+         ttl int(11) NOT NULL,
          prio int(11) default NULL,
          change_date int(11) default NULL,
          PRIMARY KEY (id),
@@ -5764,7 +5807,7 @@ while(&lt;&gt;)
              <row><entry>Master</entry><entry>Yes</entry></row>
              <row><entry>Slave</entry><entry>Yes</entry></row>
              <row><entry>Superslave</entry><entry>Yes</entry></row>
-             <row><entry>Autoserial</entry><entry>Yes</entry></row>
+             <row><entry>Autoserial</entry><entry>NO</entry></row>
              <row><entry>Case</entry><entry>All lower</entry></row>
              <row><entry>Module name &lt; 2.9.3</entry><entry>pgmysql</entry></row>
              <row><entry>Module name &gt; 2.9.2</entry><entry>gmysql and gpgsql</entry></row>
index f34ffbcbfa6b22c264da58e3c25f99abd8c4d14f..0da42f29b1daf16012e7e627d1fbba2813b4830b 100644 (file)
@@ -33,7 +33,6 @@
 #include "resolver.hh"
 #include "communicator.hh"
 #include "dnsproxy.hh"
-#include "recbcomm.hh"
 
 extern StatBag S;
 extern PacketCache PC;  
@@ -149,7 +148,7 @@ int PacketHandler::doDNSCheckRequest(DNSPacket *p, DNSPacket *r, string &target)
   DNSResourceRecord rr;
 
   if (p->qclass == 3 && p->qtype.getName() == "HINFO") {
-    rr.content = "PowerDNS $Id: packethandler.cc,v 1.7 2003/01/21 10:42:34 ahu Exp $";
+    rr.content = "PowerDNS $Id: packethandler.cc,v 1.8 2003/01/23 15:34:53 ahu Exp $";
     rr.ttl = 5;
     rr.qname=target;
     rr.qtype=13; // hinfo
@@ -165,7 +164,7 @@ int PacketHandler::doVersionRequest(DNSPacket *p, DNSPacket *r, string &target)
 {
   DNSResourceRecord rr;
   if(p->qtype.getCode()==QType::TXT && target=="version.bind") {// TXT
-    rr.content="Served by POWERDNS "VERSION" $Id: packethandler.cc,v 1.7 2003/01/21 10:42:34 ahu Exp $";
+    rr.content="Served by POWERDNS "VERSION" $Id: packethandler.cc,v 1.8 2003/01/23 15:34:53 ahu Exp $";
     rr.ttl=5;
     rr.qname=target;
     rr.qtype=QType::TXT; // TXT
index d6369781947a787f5d789d7651a7f4f995f25cc4..5402a6001c0cac9ef4038e7ad9b376541070a894 100644 (file)
@@ -23,6 +23,7 @@
 #include <set>
 #include <netdb.h>
 #include <stdio.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include "mtasker.hh"
@@ -49,18 +50,6 @@ ArgvMap &arg()
 int d_clientsock;
 int d_serversock;
 
-
-/*
-Jan 20 00:21:40 [48570] new question arrived for 'idealx.com|MX' from 127.0.0.1
-Jan 20 00:21:40 [48571] new question arrived for 'idealx.com|MX' from 127.0.0.1
-Jan 20 00:21:40 [48572] new question arrived for 'idealx.com|MX' from 127.0.0.1
-Jan 20 00:21:40 [48573] new question arrived for 'idealx.com|MX' from 127.0.0.1
-Jan 20 00:21:44 [48573] sent answer to question for 'idealx.com|MX' to 127.0.0.1, 0 answers, 0 additional, sent 2 packets, rcode=2
-Jan 20 00:21:44 [48573] sent answer to question for 'idealx.com|MX' to 127.0.0.1, 0 answers, 0 additional, sent 2 packets, rcode=2
-Jan 20 00:21:44 [48573] sent answer to question for 'idealx.com|MX' to 127.0.0.1, 0 answers, 0 additional, sent 2 packets, rcode=2
-Jan 20 00:21:44 [48573] sent answer to question for 'idealx.com|MX' to 127.0.0.1, 0 answers, 0 additional, sent 2 packets, rcode=2
-*/
-
 struct PacketID
 {
   u_int16_t id;
@@ -83,7 +72,7 @@ bool operator<(const PacketID& a, const PacketID& b)
   return false;
 }
 
-MTasker<PacketID,string> MT(200000);
+MTasker<PacketID,string> MT(100000); // could probably be way lower
 
 /* these two functions are used by LWRes */
 int asendto(const char *data, int len, int flags, struct sockaddr *toaddr, int addrlen, int id) 
@@ -108,7 +97,6 @@ int arecvfrom(char *data, int len, int flags, struct sockaddr *toaddr, socklen_t
   return 1;
 }
 
-
 typedef map<string,set<DNSResourceRecord> > cache_t;
 cache_t cache;
 int cacheHits, cacheMisses;
@@ -118,10 +106,10 @@ int getCache(const string &qname, const QType& qt, set<DNSResourceRecord>* res)
   if(j!=cache.end() && j->first==toLower(qname)+"|"+qt.getName() && j->second.begin()->ttl>(unsigned int)time(0)) {
     if(res)
       *res=j->second;
-    cacheHits++;
+
     return (unsigned int)j->second.begin()->ttl-time(0);
   }
-  cacheMisses++;
+
   return -1;
 }
 
@@ -138,7 +126,7 @@ void init(void)
 
   // prime root cache
   static char*ips[]={"198.41.0.4", "128.9.0.107", "192.33.4.12", "128.8.10.90", "192.203.230.10", "192.5.5.241", "192.112.36.4", "128.63.2.53", 
-                    "192.36.148.17","198.41.0.10", "193.0.14.129", "198.32.64.12", "202.12.27.33"};
+                    "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"};
   DNSResourceRecord arr, nsrr;
   arr.qtype=QType::A;
   arr.ttl=time(0)+3600000;
@@ -164,6 +152,7 @@ void init(void)
 void startDoResolve(void *p)
 {
   try {
+    bool quiet=arg().mustDo("quiet");
     DNSPacket P=*(DNSPacket *)p;
 
     delete (DNSPacket *)p;
@@ -174,7 +163,9 @@ void startDoResolve(void *p)
     R->setRA(true);
 
     SyncRes sr;
-    L<<Logger::Error<<"["<<MT.getTid()<<"] question for '"<<P.qdomain<<"|"<<P.qtype.getName()<<"' from "<<P.getRemote()<<endl;
+    if(!quiet)
+      L<<Logger::Error<<"["<<MT.getTid()<<"] question for '"<<P.qdomain<<"|"<<P.qtype.getName()<<"' from "<<P.getRemote()<<endl;
+
     sr.setId(MT.getTid());
     if(!P.d.rd)
       sr.setCacheOnly();
@@ -190,8 +181,12 @@ void startDoResolve(void *p)
 
     const char *buffer=R->getData();
     sendto(d_serversock,buffer,R->len,0,(struct sockaddr *)(R->remote),R->d_socklen);
-    L<<Logger::Error<<"["<<MT.getTid()<<"] answer to "<<(P.d.rd?"":"non-rd ")<<"question '"<<P.qdomain<<"|"<<P.qtype.getName();
-    L<<"': "<<ntohs(R->d.ancount)<<" answers, "<<ntohs(R->d.arcount)<<" additional, took "<<sr.d_outqueries<<" packets, rcode="<<res<<endl;
+    if(!quiet) {
+      L<<Logger::Error<<"["<<MT.getTid()<<"] answer to "<<(P.d.rd?"":"non-rd ")<<"question '"<<P.qdomain<<"|"<<P.qtype.getName();
+      L<<"': "<<ntohs(R->d.ancount)<<" answers, "<<ntohs(R->d.arcount)<<" additional, took "<<sr.d_outqueries<<" packets, rcode="<<res<<endl;
+    }
+    
+    sr.d_outqueries ? cacheMisses++ : cacheHits++;
 
     delete R;
   }
@@ -272,17 +267,28 @@ void daemonize(void)
 
 }
 int counter, qcounter;
+bool statsWanted;
+
+void usr1Handler(int)
+{
+  statsWanted=true;
+}
+void doStats(void)
+{
+  if(qcounter) {
+    L<<Logger::Error<<"stats: "<<qcounter<<" questions, "<<cache.size()<<" cache entries, "<<SyncRes::s_negcache.size()<<" negative entries, "
+     <<(int)((cacheHits*100.0)/(cacheHits+cacheMisses))<<"% cache hits";
+    L<<Logger::Error<<", outpacket/query ratio "<<(int)(SyncRes::s_outqueries*100.0/SyncRes::s_queries)<<"%"<<endl;
+  }
+  statsWanted=false;
+}
 
 void houseKeeping(void *)
 {
   static time_t last_stat, last_rootupdate;
 
-  if(time(0)-last_stat>1800) {
-    if(qcounter) {
-      L<<Logger::Error<<"stats: "<<qcounter<<" questions, "<<cache.size()<<" cache entries, "
-       <<(int)((cacheHits*100.0)/(cacheHits+cacheMisses))<<"% cache hits";
-      L<<Logger::Error<<", outpacket/query ratio "<<(int)(SyncRes::s_outqueries*100.0/SyncRes::s_queries)<<"%"<<endl;
-    }
+  if(time(0)-last_stat>1800) { 
+    doStats();
     last_stat=time(0);
   }
   if(time(0)-last_rootupdate>7200) {
@@ -307,13 +313,24 @@ int main(int argc, char **argv)
     arg().set("soa-minimum-ttl","Don't change")="0";
     arg().set("soa-serial-offset","Don't change")="0";
     arg().set("aaaa-additional-processing","turn on to do AAAA additional processing (slow)")="off";
-    arg().set("local-port","port to listen on")="5300";
+    arg().set("local-port","port to listen on")="53";
     arg().set("local-address","port to listen on")="0.0.0.0";
     arg().set("trace","if we should output heaps of logging")="off";
-    arg().set("daemon","Operate as a daemon")="no";
+    arg().set("daemon","Operate as a daemon")="yes";
+    arg().set("quiet","Suppress logging of questions and answers")="off";
+    arg().set("config-dir","Location of configuration directory (recursor.conf)")=SYSCONFDIR;
     arg().setCmd("help","Provide a helpful message");
+    L.toConsole(Logger::Warning);
+    arg().laxParse(argc,argv); // do a lax parse
+
+    string configname=arg()["config-dir"]+"/recursor.conf";
+    cleanSlashes(configname);
+
+    if(!arg().file(configname.c_str())) 
+      L<<Logger::Warning<<"Unable to parse configuration file '"<<configname<<"'"<<endl;
+
+    arg().parse(argc,argv);
 
-    arg().parse(argc, argv);
 
     if(arg().mustDo("help")) {
       cerr<<"syntax:"<<endl<<endl;
@@ -321,9 +338,7 @@ int main(int argc, char **argv)
       exit(99);
     }
 
-
     L.setName("pdns_recursor");
-    L.toConsole(Logger::Warning);
 
     if(arg().mustDo("trace"))
       SyncRes::setLog(true);
@@ -342,11 +357,15 @@ int main(int argc, char **argv)
       L.toConsole(Logger::Critical);
       daemonize();
     }
+    signal(SIGUSR1,usr1Handler);
+
     for(;;) {
       while(MT.schedule()); // housekeeping, let threads do their thing
       
-      if(!((counter++)%1000)) 
+      if(!((counter++)%100)) 
        MT.makeThread(houseKeeping,0);
+      if(statsWanted)
+       doStats();
 
       socklen_t addrlen=sizeof(fromaddr);
       int d_len;
@@ -361,10 +380,12 @@ int main(int argc, char **argv)
       FD_SET( d_clientsock, &readfds );
       FD_SET( d_serversock, &readfds );
       int selret = select( max(d_clientsock,d_serversock) + 1, &readfds, NULL, NULL, &tv );
-      if (selret == -1) 
+      if(selret<=0) 
+       if (selret == -1 && errno!=EINTR) 
          throw AhuException("Select returned: "+stringerror());
-      if(!selret) // nothing happened
-       continue;
+       else
+         continue;
+
       
       if(FD_ISSET(d_clientsock,&readfds)) { // do we have a question response?
        d_len=recvfrom(d_clientsock, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen);    
index 401d24f72366df5ad2804adf0b05d0540cf06b36..db2f1fd7e01cf0b062ae7c1467898e0ad983f548 100644 (file)
@@ -38,7 +38,7 @@ public:
   static unsigned int s_queries;
   static unsigned int s_outqueries;
   unsigned int d_outqueries;
-  
+  static map<string,string> s_negcache;    
 private:
   struct GetBestNSAnswer;
   int doResolveAt(set<string> nameservers, string auth, const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret,
@@ -54,14 +54,14 @@ private:
   vector<string> shuffle(set<string> &nameservers);
   bool moreSpecificThan(const string& a, const string &b);
   string getA(const string &qname, int depth, set<GetBestNSAnswer>& beenthere);
-  
+
 private:
   string d_prefix;
   static bool s_log;
   bool d_cacheonly;
   bool d_nocache;
   LWRes d_lwr;
-  static map<string,string> s_negcache;
+
   struct GetBestNSAnswer
   {
     string qname;