From 8d022964fc2261e9feb527e2dfb4114f0df3f0f9 Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Tue, 4 Mar 2003 18:33:39 +0000 Subject: [PATCH] working up to 2.9.7 git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@156 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- ChangeLog | 4 ++ modules/ldapbackend/ldapbackend.cc | 51 ++++++++++++----- modules/ldapbackend/ldapbackend.hh | 4 ++ pdns/Makefile.am | 2 +- pdns/backends/bind/Makefile.am | 2 +- pdns/backends/bind/zoneparser.hh | 2 +- pdns/backends/bind/zoneparser2.cc | 30 +++++----- pdns/common_startup.cc | 8 +-- pdns/docs/pdns.sgml | 91 ++++++++++++++++++------------ pdns/dynmessenger.cc | 9 ++- pdns/pdns_recursor.cc | 3 + pdns/receiver.cc | 6 +- pdns/tcpreceiver.cc | 2 + 13 files changed, 139 insertions(+), 75 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5c3ce7405..d6779142d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ Changes since 2.9.6: - zone2sql no longer silently tries to read directories - improved error reporting if unable to figure out IP addresses for slaves + - removed vestigal receiver-threads setting + - ldapbackend needs to include utility.hh (Remco Post) + - pdns_control could sometimes leave files behind in /tmp (dG) + - ldapbackend updates Changes since 2.9.5: - implemented isMaster in bindbackend (we now react to notifies) diff --git a/modules/ldapbackend/ldapbackend.cc b/modules/ldapbackend/ldapbackend.cc index ce166f018..3f05326b3 100644 --- a/modules/ldapbackend/ldapbackend.cc +++ b/modules/ldapbackend/ldapbackend.cc @@ -1,12 +1,20 @@ #include "ldapbackend.hh" + #include #include #include +static int Toupper(int c) +{ + return toupper(c); +} + + LdapBackend::LdapBackend( const string &suffix ) { m_msgid = 0; m_qname = ""; + m_revlookup = 0; setArgPrefix( "ldap" + suffix ); L << Logger::Notice << backendname << " Server = " << getArg( "host" ) << ":" << getArg( "port" ) << endl; @@ -35,20 +43,35 @@ bool LdapBackend::list( int domain_id ) void LdapBackend::lookup( const QType &qtype, const string &qname, DNSPacket *dnspkt, int zoneid ) { - string filter, attr; + int len = 0; + vector parts; + string filter, attr, ipaddr; char** attributes = attrany; - char* attronly[] = { NULL, NULL }; + char* attronly[] = { "associatedDomain", NULL, NULL }; m_qtype = qtype; - m_qname = m_pldap->escape( qname ); - filter = "(associatedDomain=" + m_qname + ")"; + m_qname = qname; + len = qname.length(); - if( qtype.getCode() != 255 ) // qtype != ANY + if( len > 20 && qname.substr( len - 13, 13 ) == ".in-addr.arpa" ) + { + m_revlookup = 1; + stringtok( parts, qname.substr( 0, len - 13 ), "." ); + filter = "(aRecord=" + parts[3] + "." + parts[2] + "." + parts[1] + "." + parts[0] + ")"; + attributes = attronly; + } + else + { + m_revlookup = 0; + filter = "(associatedDomain=" + m_pldap->escape( m_qname ) + ")"; + } + + if( qtype.getCode() != QType::ANY ) { attr = qtype.getName() + "Record"; filter = "(&" + filter + "(" + attr + "=*))"; - attronly[0] = (char*) attr.c_str(); + attronly[1] = (char*) attr.c_str(); attributes = attronly; } @@ -57,10 +80,6 @@ void LdapBackend::lookup( const QType &qtype, const string &qname, DNSPacket *dn L << Logger::Info << backendname << " Search = basedn: " << getArg( "basedn" ) << ", filter: " << filter << ", qtype: " << qtype.getName() << endl; } -static int Toupper(int c) -{ - return toupper(c); -} bool LdapBackend::get( DNSResourceRecord &rr ) { @@ -75,13 +94,19 @@ bool LdapBackend::get( DNSResourceRecord &rr ) { while( !m_result.empty() ) { + if( m_revlookup == 1 && m_result.find( "associatedDomain" ) != m_result.end() ) + { + m_result["PTRRecord"] = m_result["associatedDomain"]; + } + m_result.erase( "associatedDomain" ); + attribute = m_result.begin(); attrname = attribute->first; qstr = attrname.substr( 0, attrname.length() - 6 ); // extract qtype string from ldap attribute name transform( qstr.begin(), qstr.end(), qstr.begin(), &Toupper ); qt = QType( const_cast(qstr.c_str()) ); - while( !attribute->second.empty() && ( m_qtype == "ANY" || qt.getCode() == m_qtype.getCode() ) ) + while( !attribute->second.empty() && ( m_qtype.getCode() == QType::ANY || m_qtype.getCode() == qt.getCode() ) ) { content = attribute->second.back(); attribute->second.pop_back(); @@ -90,9 +115,9 @@ bool LdapBackend::get( DNSResourceRecord &rr ) rr.qname = m_qname; rr.priority = 0; - if( qt.getCode() == 15 ) // MX Record, e.g. 10 smtp.example.com + if( qt.getCode() == QType::MX ) // MX Record, e.g. 10 smtp.example.com { - stringtok( parts, content ); + stringtok( parts, content, " " ); rr.priority = (u_int16_t) strtol( parts[0].c_str(), NULL, 10 ); content = parts[1]; } diff --git a/modules/ldapbackend/ldapbackend.hh b/modules/ldapbackend/ldapbackend.hh index 6b7955413..d34d3190d 100644 --- a/modules/ldapbackend/ldapbackend.hh +++ b/modules/ldapbackend/ldapbackend.hh @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ using namespace std; static string backendname="[LdapBackend]"; static char* attrany[] = { + "associatedDomain", "ARecord", "NSRecord", "CNAMERecord", @@ -45,6 +47,8 @@ class LdapBackend : public DNSBackend private: int m_msgid; + int m_revlookup; + QType m_qtype; string m_qname; PowerLDAP* m_pldap; diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 7cf10f9f6..73e6129a5 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -31,7 +31,7 @@ dynlistener.cc dynlistener.hh dynhandler.cc dynhandler.hh \ resolver.hh resolver.cc communicator.cc communicator.hh dnsproxy.cc \ dnsproxy.hh randombackend.cc unix_utility.cc common_startup.cc \ utility.hh iputils.hh common_startup.hh \ -backends/bind/bindbackend.cc backends/bind/zoneparser2.cc \ +backends/bind/bindbackend2.cc backends/bind/zoneparser2.cc \ backends/bind/bindparser.cc backends/bind/bindlexer.c \ backends/bind/huffman.cc backends/gsql/gsqlbackend.cc \ backends/gsql/gsqlbackend.hh backends/gsql/ssql.hh \ diff --git a/pdns/backends/bind/Makefile.am b/pdns/backends/bind/Makefile.am index 4aac0074e..6eb394e3a 100644 --- a/pdns/backends/bind/Makefile.am +++ b/pdns/backends/bind/Makefile.am @@ -1,7 +1,7 @@ INCLUDES=-I../.. noinst_LTLIBRARIES = libbindbackend.la -libbindbackend_la_SOURCES=bindbackend.cc bindbackend.hh bindparser.yy \ +libbindbackend_la_SOURCES=bindbackend2.cc bindbackend2.hh bindparser.yy \ bindlexer.l zoneparser2.cc ../../misc.cc huffman.cc huffman.hh zoneparser.hh \ bindparser.hh ../../unix_utility.cc diff --git a/pdns/backends/bind/zoneparser.hh b/pdns/backends/bind/zoneparser.hh index 1edeb4cd4..37f41e6bf 100644 --- a/pdns/backends/bind/zoneparser.hh +++ b/pdns/backends/bind/zoneparser.hh @@ -45,7 +45,7 @@ class ZoneParser void setCallback(callback_t *callback); callback_t *d_callback; bool parseLine(const vector&words, vector &); - bool eatLine(string line, vector&); + bool eatLine(const string& line, vector&); void setDirectory(const string &dir); static string canonic(const string& dom); diff --git a/pdns/backends/bind/zoneparser2.cc b/pdns/backends/bind/zoneparser2.cc index 6a714a1f6..8c56b0c8c 100644 --- a/pdns/backends/bind/zoneparser2.cc +++ b/pdns/backends/bind/zoneparser2.cc @@ -65,14 +65,18 @@ void ZoneParser::parse(const string &fname, const string &origin, unsigned int d stackfds; fds.push(zonein); + while(!fds.empty()) { - while(fgets(cline,sizeof(cline)-1,fds.top())) { + while(fgets_unlocked(cline,sizeof(cline)-1,fds.top())) { line=cline; chomp(line," \x1a\r\n"); cutOff(line,";"); d_lineno++; - if(!line.find("$INCLUDE ") || !line.find("$include ")) { + if(line.empty()) + continue; + + if(line[0]=='$' && (!line.find("$INCLUDE ") || !line.find("$include "))) { vector parts; stringtok(parts,line," \t\n"); if(parts.size()!=2) @@ -121,14 +125,18 @@ void ZoneParser::parse(const string &fname, const string &origin, vector vector rec; stackfds; fds.push(zonein); + while(!fds.empty()) { - while(fgets(cline,sizeof(cline)-1,fds.top())) { + while(fgets_unlocked(cline,sizeof(cline)-1,fds.top())) { line=cline; chomp(line," \x1a\r\n"); cutOff(line,";"); d_lineno++; - if(!line.find("$INCLUDE ") || !line.find("$include ")) { + if(line.empty()) + continue; + + if(line[0]=='$' && (!line.find("$INCLUDE ") || !line.find("$include "))) { vector parts; stringtok(parts,line," \t\r\n"); if(parts.size()!=2) @@ -154,8 +162,6 @@ void ZoneParser::parse(const string &fname, const string &origin, vector fclose(fds.top()); fds.pop(); } - - } @@ -171,7 +177,6 @@ void ZoneParser::fillRec(const string &qname, const string &qtype, const string rec.ttl=ttl; rec.prio=prio; recs.push_back(rec); - } @@ -180,19 +185,18 @@ void ZoneParser::cutOff(string &line, const string &delim) unsigned int pos=line.find_first_of(delim); if(pos==string::npos) return; - line=line.substr(0,pos); + line.resize(pos); } -bool ZoneParser::eatLine(string line, vector &rec) +bool ZoneParser::eatLine(const string& line, vector &rec) { - rec.clear(); static string tline; static string lastfirstword; unsigned int pos=string::npos; if(tline.empty()) { - pos=line.find("("); + pos=line.find_first_of("("); if(pos!=string::npos) { // this is a line that continues tline=line.substr(0,pos); return false; @@ -239,7 +243,7 @@ ZoneParser::~ZoneParser() void ZoneParser::setCallback(callback_t *callback) { - d_callback=callback; + d_callback=callback; } bool ZoneParser::isNumber(const string &s) @@ -270,7 +274,7 @@ bool ZoneParser::isType(const string &s) bool ZoneParser::isClass(const string &s) { - return (s=="IN" || s=="CH" || s=="HS" || s=="in" || s=="ch" || s=="hs"); + return (s.size()==2 && (s=="IN" || s=="CH" || s=="HS" || s=="in" || s=="ch" || s=="hs")); } unsigned int ZoneParser::zoneNumber(const string &str) diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc index ac6dbd806..4e37b6e38 100644 --- a/pdns/common_startup.cc +++ b/pdns/common_startup.cc @@ -90,8 +90,6 @@ void declareArguments() arg().set("webserver-port","Port of webserver to listen on")="8081"; arg().set("webserver-password","Password required for accessing the webserver")=""; - arg().set("receiver-threads","Number of receiver threads to launch")="1"; - arg().setSwitch("out-of-zone-additional-processing","Do out of zone additional processing")="no"; arg().setSwitch("query-logging","Hint backends that queries should be logged")="no"; @@ -268,10 +266,8 @@ void mainthread() TN->go(); // tcp nameserver launch // fork(); (this worked :-)) - for(int n=0;n(D)); // receives packets - } + DNSDistributor *D= new DNSDistributor(arg().asNum("distributor-threads")); // the big dispatcher! + pthread_create(&qtid,0,qthread,static_cast(D)); // receives packets void *p; pthread_join(qtid, &p); diff --git a/pdns/docs/pdns.sgml b/pdns/docs/pdns.sgml index 66dc1e2d7..0655fdeae 100644 --- a/pdns/docs/pdns.sgml +++ b/pdns/docs/pdns.sgml @@ -11,7 +11,7 @@ - v2.1 $Date: 2003/02/15 11:30:17 $ + v2.1 $Date: 2003/03/04 18:33:39 $ @@ -3308,15 +3308,16 @@ name IN A 1.2.3.4 Configure database connectivity - The default PDNS distribution comes with a simple MySQL backend built in, which we will now use for - demonstrating database connectivity. This backend is called 'mysql', and needs to be configured + This chapter shows you how to configure the Generic MySQL backend, which we like a lot. But feel free to use any of the myriad + other backends. + This backend is called 'gmysql', and needs to be configured in pdns.conf. Add the following lines, adjusted for your local setup: - launch=mysql - mysql-host=127.0.0.1 - mysql-user=root - mysql-dbname=pdnstest + launch=gmysql + gmysql-host=127.0.0.1 + gmysql-user=root + gmysql-dbname=pdnstest Remove any earlier launch statements. Also remove the bind-example-zones @@ -3331,8 +3332,8 @@ name IN A 1.2.3.4 - This section describes the deprecated MySQL backend, which should no longer be used! Use the Generic MySQL backend! See - . + Be very very sure that you configure the *g*mysql backend and not the mysql backend. See + . If you use the 'mysql' backend things will only appear to work. @@ -3343,9 +3344,9 @@ name IN A 1.2.3.4 (...) 15:31:30 PowerDNS 1.99.0 (Mar 12 2002, 15:00:28) starting up 15:31:30 About to create 3 backend threads - 15:31:30 [MySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest' - 15:31:30 [MySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest' - 15:31:30 [MySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest' + 15:31:30 [gMySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest' + 15:31:30 [gMySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest' + 15:31:30 [gMySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest' This is as to be expected - we did not yet add anything to MySQL for PDNS to read from. At this point you may also see @@ -3359,24 +3360,44 @@ name IN A 1.2.3.4 Connect to MySQL as a user with sufficient privileges and issue the following commands: - # mysql - mysql> CREATE DATABASE pdnstest; - mysql> use pdnstest; +create table domains ( + id INT auto_increment, + name VARCHAR(255) NOT NULL, + master VARCHAR(20) DEFAULT NULL, + last_check INT DEFAULT NULL, + type VARCHAR(6) NOT NULL, + notified_serial INT DEFAULT NULL, + account VARCHAR(40) DEFAULT NULL, + primary key (id) +)type=InnoDB; - mysql> CREATE TABLE records ( - id int(11) NOT NULL auto_increment, - domain_id int(11) NOT NULL, - name varchar(255) NOT NULL, - type varchar(6) NOT NULL, - content varchar(255) default NULL, - ttl int(11) NOT NULL, - prio int(11) default NULL, - change_date int(11) default NULL, - PRIMARY KEY (id), - KEY name_index(name), - KEY nametype_index(name,type), - KEY domainid_index(domain_id) - ); +CREATE UNIQUE INDEX name_index ON domains(name); + +CREATE TABLE records ( + id INT auto_increment, + domain_id INT DEFAULT NULL, + name VARCHAR(255) DEFAULT NULL, + type VARCHAR(6) DEFAULT NULL, + content VARCHAR(255) DEFAULT NULL, + ttl INT DEFAULT NULL, + prio INT DEFAULT NULL, + change_date INT DEFAULT NULL, + primary key(id) +)type=InnoDB; + +CREATE INDEX rec_name_index ON records(name); +CREATE INDEX nametype_index ON records(name,type); +CREATE INDEX domain_id ON records(domain_id); + +create table supermasters ( + ip VARCHAR(25) NOT NULL, + nameserver VARCHAR(255) NOT NULL, + account VARCHAR(40) DEFAULT NULL +); + +GRANT SELECT ON supermasters TO pdns; +GRANT ALL ON domains TO pdns; +GRANT ALL ON records TO pdns; Now we have a database and an empty table. PDNS should now be able to launch in monitor mode and display no errors: @@ -3386,9 +3407,9 @@ name IN A 1.2.3.4 (...) 15:31:30 PowerDNS 1.99.0 (Mar 12 2002, 15:00:28) starting up 15:31:30 About to create 3 backend threads - 15:39:55 [MySQLbackend] MySQL connection succeeded - 15:39:55 [MySQLbackend] MySQL connection succeeded - 15:39:55 [MySQLbackend] MySQL connection succeeded + 15:39:55 [gMySQLbackend] MySQL connection succeeded + 15:39:55 [gMySQLbackend] MySQL connection succeeded + 15:39:55 [gMySQLbackend] MySQL connection succeeded A sample query sent to the database should now return quickly without data: @@ -3405,7 +3426,7 @@ name IN A 1.2.3.4 Now we need to add some records to our database: # mysql pdnstest - mysql> + mysql> INSERT INTO domains (name, type) values ('test.com', 'NATIVE'); INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'test.com','localhost ahu@ds9a.nl 1','SOA',86400,NULL); INSERT INTO records (domain_id, name, content, type,ttl,prio) @@ -3473,11 +3494,11 @@ name IN A 1.2.3.4 Your MySQL installation is probably defaulting to another location for its socket. Can be resolved by figuring out this location (often /var/run/mysqld.sock), and specifying it - in the configuration file with the mysql-socket parameter. + in the configuration file with the gmysql-socket parameter. Another solution is to not connect to the socket, but to 127.0.0.1, which can be achieved by specifying - mysql-host=127.0.0.1. + gmysql-host=127.0.0.1. diff --git a/pdns/dynmessenger.cc b/pdns/dynmessenger.cc index 343f1d62e..dce2f25b5 100644 --- a/pdns/dynmessenger.cc +++ b/pdns/dynmessenger.cc @@ -45,10 +45,13 @@ DynMessenger::DynMessenger(const string &localdir, const string &fname) unlink(d_local.sun_path); - if(bind(d_s, (sockaddr*)&d_local,sizeof(d_local))<0) + if(bind(d_s, (sockaddr*)&d_local,sizeof(d_local))<0) { + unlink(d_local.sun_path); throw AhuException("Unable to bind to local temporary file: "+string(strerror(errno))); + } if(chmod(d_local.sun_path,0666)<0) { // make sure that pdns can reply! + unlink(d_local.sun_path); perror("fchmod"); exit(1); } @@ -57,8 +60,10 @@ DynMessenger::DynMessenger(const string &localdir, const string &fname) d_remote.sun_family=AF_UNIX; strcpy(d_remote.sun_path,fname.c_str()); - if(connect(d_s,(sockaddr*)&d_remote,sizeof(d_remote))<0) + if(connect(d_s,(sockaddr*)&d_remote,sizeof(d_remote))<0) { + unlink(d_local.sun_path); throw AhuException("Unable to connect to remote '"+fname+"': "+string(strerror(errno))); + } } diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 2ee5ca8bf..10e7ce85a 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -391,6 +391,9 @@ int main(int argc, char **argv) FD_ZERO( &readfds ); FD_SET( d_clientsock, &readfds ); FD_SET( d_serversock, &readfds ); + + + /* this should listen on a TCP port as well for new connections, */ int selret = select( max(d_clientsock,d_serversock) + 1, &readfds, NULL, NULL, &tv ); if(selret<=0) if (selret == -1 && errno!=EINTR) diff --git a/pdns/receiver.cc b/pdns/receiver.cc index 6f6d45e25..a132fff75 100644 --- a/pdns/receiver.cc +++ b/pdns/receiver.cc @@ -1,6 +1,6 @@ /* PowerDNS Versatile Database Driven Nameserver - Copyright (C) 2002 PowerDNS.COM BV + Copyright (C) 2003 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 as published by @@ -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: receiver.cc,v 1.6 2003/01/02 15:43:00 ahu Exp $ +// $Id: receiver.cc,v 1.7 2003/03/04 18:33:39 ahu Exp $ #include #include #include @@ -540,7 +540,7 @@ int main(int argc, char **argv) declareStats(); DLOG(L<d.rd && arg().mustDo("recursor")) { // now what // this is a pretty rare event all in all, so we can afford to be slow + + // this code SHOULD attempt to answer from the local cache first! S.inc("recursing-questions"); Resolver res; unsigned int len; -- 2.40.0