]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Norbert sends:
authorBert Hubert <bert.hubert@netherlabs.nl>
Sun, 9 Mar 2008 15:31:37 +0000 (15:31 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sun, 9 Mar 2008 15:31:37 +0000 (15:31 +0000)
Here's an update for the OpenDBX backend:
- Fix for SQLite2/3 locking problem on concurrent reads/writes
- Fixes compilation on Solaris (u_int vs. uint)
- Support for autoserial (needs triggers)

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

modules/opendbxbackend/odbxbackend.cc
modules/opendbxbackend/odbxbackend.hh
modules/opendbxbackend/odbxprivate.cc

index 10a0e475946f361a8fdf3bb8329dfcea559a1e99..1cfdfde447dd56a1fd0e741bec5baaaba93d58fd 100644 (file)
@@ -106,14 +106,29 @@ bool OdbxBackend::getDomainInfo( const string& domain, DomainInfo& di )
                        di.backend = this;
                        di.serial = 0;
 
-                       if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
+                       if( ( tmp = odbx_field_value( m_result, 6 ) ) != NULL )
                        {
-                               di.id = strtol( tmp, NULL, 10 );
+                               SOAData sd;
+
+                               sd.serial = 0;
+                               fillSOAData( string( tmp, odbx_field_length( m_result, 6 ) ), sd );
+
+                               if( sd.serial == 0 && ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
+                               {
+                                       sd.serial = strtol( tmp, NULL, 10 );
+                               }
+
+                               di.serial = sd.serial;
                        }
 
-                       if( ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
+                       if( ( tmp = odbx_field_value( m_result, 4 ) ) != NULL )
                        {
-                               di.zone = string( tmp, odbx_field_length( m_result, 1 ) );
+                               di.last_check = strtol( tmp, NULL, 10 );
+                       }
+
+                       if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
+                       {
+                               stringtok(di.masters, string( tmp, odbx_field_length( m_result, 3 ) ), ", \t");
                        }
 
                        if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
@@ -128,31 +143,80 @@ bool OdbxBackend::getDomainInfo( const string& domain, DomainInfo& di )
                                }
                        }
 
-                       if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
+                       if( ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
                        {
-                               string masters = string( tmp, odbx_field_length( m_result, 3 ) );
-                               stringtok(di.masters, masters, ", \t");
+                               di.zone = string( tmp, odbx_field_length( m_result, 1 ) );
                        }
 
-                       if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
+                       if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
                        {
-                               di.last_check = strtol( tmp, NULL, 10 );
+                               di.id = strtol( tmp, NULL, 10 );
                        }
+               }
+               while( getRecord( READ ) );
+       }
+       catch( exception& e )
+       {
+               L.log( m_myname + " getDomainInfo: Caught STL exception - " + e.what(),  Logger::Error );
+               return false;
+       }
 
-                       if( ( tmp = odbx_field_value( m_result, 6 ) ) != NULL )
+       return true;
+}
+
+
+
+bool OdbxBackend::getSOA( const string& domain, SOAData& sd, DNSPacket* p )
+{
+       const char* tmp;
+
+
+       try
+       {
+               DLOG( L.log( m_myname + " getSOA()", Logger::Debug ) );
+
+               string stmt = getArg( "sql-lookupsoa" );
+               string& stmtref = strbind( ":name", escape( toLower( domain ), READ ), stmt );
+
+               if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
+               if( !getRecord( READ ) ) { return false; }
+
+               do
+               {
+                       sd.serial = 0;
+
+                       if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
                        {
-                               SOAData sd;
+                               fillSOAData( string( tmp, odbx_field_length( m_result, 2 ) ), sd );
+                       }
 
-                               sd.serial = 0;
-                               fillSOAData( string( tmp, odbx_field_length( m_result, 6 ) ), sd );
-                               di.serial = sd.serial;
+                       if( sd.serial == 0 && ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
+                       {
+                               sd.serial = strtol( tmp, NULL, 10 );
                        }
+
+                       if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
+                       {
+                               sd.domain_id = strtol( tmp, NULL, 10 );
+                       }
+
+                       if( sd.nameserver.empty() )
+                       {
+                               sd.nameserver = arg()["default-soa-name"];
+                       }
+
+                       if( sd.hostmaster.empty() )
+                       {
+                               sd.hostmaster = "hostmaster." + domain;
+                       }
+
+                       sd.db = this;
                }
                while( getRecord( READ ) );
        }
        catch( exception& e )
        {
-               L.log( m_myname + " getDomainInfo: Caught STL exception - " + e.what(),  Logger::Error );
+               L.log( m_myname + " getSOA: Caught STL exception - " + e.what(),  Logger::Error );
                return false;
        }
 
@@ -211,7 +275,7 @@ void OdbxBackend::lookup( const QType& qtype, const string& qname, DNSPacket* dn
 
                m_result = NULL;
                m_qname = qname;
-               
+
                if( zoneid < 0 )
                {
                        if( qtype.getCode() == QType::ANY )
@@ -231,7 +295,7 @@ void OdbxBackend::lookup( const QType& qtype, const string& qname, DNSPacket* dn
                                stmt = getArg( "sql-lookuptypeid" );
                                stmtref = strbind( ":type", qtype.getName(), stmt );
                        }
-                       
+
                        size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
 
                        if( len < 0 )
@@ -306,7 +370,7 @@ bool OdbxBackend::get( DNSResourceRecord& rr )
 
                        if( ( tmp = odbx_field_value( m_result, 4 ) ) != NULL )
                        {
-                               rr.priority = (u_int16_t) strtoul( tmp, NULL, 10 );
+                               rr.priority = (uint16_t) strtoul( tmp, NULL, 10 );
                        }
 
                        if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
@@ -327,7 +391,7 @@ bool OdbxBackend::get( DNSResourceRecord& rr )
 }
 
 
-void OdbxBackend::setFresh( u_int32_t domain_id )
+void OdbxBackend::setFresh( uint32_t domain_id )
 {
        size_t len;
 
@@ -370,7 +434,7 @@ void OdbxBackend::setFresh( u_int32_t domain_id )
 
 
 
-void OdbxBackend::setNotified( u_int32_t domain_id, u_int32_t serial )
+void OdbxBackend::setNotified( uint32_t domain_id, uint32_t serial )
 {
        try
        {
index 2387c91f1033e9c421ef0dca3668a5a349c2b078..cc44b0d54ddb26d4bb1b4e86af435fa573bd8106 100644 (file)
@@ -45,8 +45,8 @@ using std::vector;
 
 
 
-bool checkSlave( u_int32_t last, u_int32_t notified, SOAData* sd, DomainInfo* di );
-bool checkMaster( u_int32_t last, u_int32_t notified, SOAData* sd, DomainInfo* di );
+bool checkSlave( uint32_t last, uint32_t notified, SOAData* sd, DomainInfo* di );
+bool checkMaster( uint32_t last, uint32_t notified, SOAData* sd, DomainInfo* di );
 
 
 class OdbxBackend : public DNSBackend
@@ -65,7 +65,7 @@ class OdbxBackend : public DNSBackend
 
        string escape( const string& str, QueryType type );
        bool connectTo( const vector<string>& host, QueryType type );
-       bool getDomainList( const string& query, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) );
+       bool getDomainList( const string& query, vector<DomainInfo>* list, bool (*check_fcn)(uint32_t,uint32_t,SOAData*,DomainInfo*) );
        bool execStmt( const char* stmt, unsigned long length, QueryType type );
        bool getRecord( QueryType type );
 
@@ -76,6 +76,7 @@ public:
        ~OdbxBackend();
 
        void lookup( const QType& qtype, const string& qdomain, DNSPacket* p = 0, int zoneid = -1 );
+       bool getSOA( const string& domain, SOAData& sd, DNSPacket* p );
        bool list( const string& target, int domain_id );
        bool get( DNSResourceRecord& rr );
 
@@ -92,8 +93,8 @@ public:
        void getUpdatedMasters( vector<DomainInfo>* updated );
        void getUnfreshSlaveInfos( vector<DomainInfo>* unfresh );
 
-       void setFresh( u_int32_t domain_id );
-       void setNotified( u_int32_t domain_id, u_int32_t serial );
+       void setFresh( uint32_t domain_id );
+       void setNotified( uint32_t domain_id, uint32_t serial );
 };
 
 
@@ -116,15 +117,16 @@ public:
                declare( suffix, "username","User for connecting to the DBMS","powerdns");
                declare( suffix, "password","Password for connecting to the DBMS","");
 
-               declare( suffix, "sql-list", "AXFR query", "SELECT \"domain_id\", \"name\", \"type\", \"ttl\", \"prio\", \"content\" FROM \"records\" WHERE \"domain_id\"=:id" );
+               declare( suffix, "sql-list", "AXFR query", "SELECT r.\"domain_id\", r.\"name\", r.\"type\", r.\"ttl\", r.\"prio\", r.\"content\" FROM \"records\" r WHERE r.\"domain_id\"=:id" );
 
-               declare( suffix, "sql-lookup", "Lookup query","SELECT \"domain_id\", \"name\", \"type\", \"ttl\", \"prio\", \"content\" FROM \"records\" WHERE \"name\"=':name'" );
-               declare( suffix, "sql-lookupid", "Lookup query with id","SELECT \"domain_id\", \"name\", \"type\", \"ttl\", \"prio\", \"content\" FROM \"records\" WHERE \"domain_id\"=:id AND \"name\"=':name'" );
-               declare( suffix, "sql-lookuptype", "Lookup query with type","SELECT \"domain_id\", \"name\", \"type\", \"ttl\", \"prio\", \"content\" FROM \"records\" WHERE \"name\"=':name' AND \"type\"=':type'" );
-               declare( suffix, "sql-lookuptypeid", "Lookup query with type and id","SELECT \"domain_id\", \"name\", \"type\", \"ttl\", \"prio\", \"content\" FROM \"records\" WHERE \"domain_id\"=:id AND \"name\"=':name' AND \"type\"=':type'" );
+               declare( suffix, "sql-lookup", "Lookup query","SELECT r.\"domain_id\", r.\"name\", r.\"type\", r.\"ttl\", r.\"prio\", r.\"content\" FROM \"records\" r WHERE r.\"name\"=':name'" );
+               declare( suffix, "sql-lookupid", "Lookup query with id","SELECT r.\"domain_id\", r.\"name\", r.\"type\", r.\"ttl\", r.\"prio\", r.\"content\" FROM \"records\" r WHERE r.\"domain_id\"=:id AND r.\"name\"=':name'" );
+               declare( suffix, "sql-lookuptype", "Lookup query with type","SELECT r.\"domain_id\", r.\"name\", r.\"type\", r.\"ttl\", r.\"prio\", r.\"content\" FROM \"records\" r WHERE r.\"name\"=':name' AND r.\"type\"=':type'" );
+               declare( suffix, "sql-lookuptypeid", "Lookup query with type and id","SELECT r.\"domain_id\", r.\"name\", r.\"type\", r.\"ttl\", r.\"prio\", r.\"content\" FROM \"records\" r WHERE r.\"domain_id\"=:id AND r.\"name\"=':name' AND r.\"type\"=':type'" );
+               declare( suffix, "sql-lookupsoa","Lookup query for SOA record","SELECT d.\"id\", d.\"auto_serial\", r.\"content\" FROM \"records\" r JOIN \"domains\" d ON r.\"domain_id\"=d.\"id\" WHERE r.\"name\"=':name' AND r.\"type\"='SOA' AND d.\"status\"='A'" );
 
-               declare( suffix, "sql-zonedelete","Delete all records for this zone","DELETE FROM \"records\" WHERE \"domain_id\"=:id" );
-               declare( suffix, "sql-zoneinfo","Get domain info","SELECT d.\"id\", d.\"name\", d.\"type\", d.\"master\", d.\"last_check\", r.\"content\" FROM \"domains\" d LEFT JOIN \"records\" r ON ( d.\"id\"=r.\"domain_id\" AND r.\"type\"='SOA' ) WHERE d.\"name\"=':name' AND d.\"status\"='A'" );
+               declare( suffix, "sql-zonedelete","Delete all records for this zone","DELETE FROM \"records\" r WHERE r.\"domain_id\"=:id" );
+               declare( suffix, "sql-zoneinfo","Get domain info","SELECT d.\"id\", d.\"name\", d.\"type\", d.\"master\", d.\"last_check\", d.\"auto_serial\", r.\"content\" FROM \"domains\" d LEFT JOIN \"records\" r ON ( d.\"id\"=r.\"domain_id\" AND r.\"type\"='SOA' ) WHERE d.\"name\"=':name' AND d.\"status\"='A'" );
 
                declare( suffix, "sql-transactbegin", "Start transaction", "BEGIN" );
                declare( suffix, "sql-transactend", "Finish transaction", "COMMIT" );
@@ -133,14 +135,14 @@ public:
                declare( suffix, "sql-insert-slave","Add slave domain", "INSERT INTO \"domains\" ( \"name\", \"type\", \"master\", \"account\" ) VALUES ( '%s', 'SLAVE', '%s', '%s' )" );
                declare( suffix, "sql-insert-record","Feed record into table", "INSERT INTO \"records\" ( \"domain_id\", \"name\", \"type\", \"ttl\", \"prio\", \"content\" ) VALUES ( %d, '%s', '%s', %d, %d, '%s' )" );
 
-               declare( suffix, "sql-update-serial", "Set zone to notified", "UPDATE \"domains\" SET \"notified_serial\"=%d WHERE \"id\"=%d" );
-               declare( suffix, "sql-update-lastcheck", "Set time of last check", "UPDATE \"domains\" SET \"last_check\"=%d WHERE \"id\"=%d" );
+               declare( suffix, "sql-update-serial", "Set zone to notified", "UPDATE \"domains\" d SET d.\"notified_serial\"=%d WHERE d.\"id\"=%d" );
+               declare( suffix, "sql-update-lastcheck", "Set time of last check", "UPDATE \"domains\" d SET d.\"last_check\"=%d WHERE d.\"id\"=%d" );
 
-               declare( suffix, "sql-master", "Get master record for zone", "SELECT \"master\" FROM \"domains\" WHERE \"name\"=':name' AND \"status\"='A' AND \"type\"='SLAVE'" );
-               declare( suffix, "sql-supermaster","Get supermaster info", "SELECT \"account\" FROM \"supermasters\" WHERE \"ip\"=':ip' AND \"nameserver\"=':ns'" );
+               declare( suffix, "sql-master", "Get master record for zone", "SELECT d.\"master\" FROM \"domains\" d WHERE d.\"name\"=':name' AND d.\"status\"='A' AND d.\"type\"='SLAVE'" );
+               declare( suffix, "sql-supermaster","Get supermaster info", "SELECT s.\"account\" FROM \"supermasters\" s WHERE s.\"ip\"=':ip' AND s.\"nameserver\"=':ns'" );
 
-               declare( suffix, "sql-infoslaves", "Get all unfresh slaves", "SELECT d.\"id\", d.\"name\", d.\"master\", d.\"notified_serial\", d.\"last_check\", r.\"change_date\", r.\"content\" FROM \"domains\" d LEFT JOIN \"records\" r ON ( d.\"id\"=r.\"domain_id\" AND r.\"type\"='SOA' ) WHERE d.\"status\"='A' AND d.\"type\"='SLAVE'" );
-               declare( suffix, "sql-infomasters", "Get all updated masters", "SELECT d.\"id\", d.\"name\", d.\"master\", d.\"notified_serial\", d.\"last_check\", r.\"change_date\", r.\"content\" FROM \"domains\" d JOIN \"records\" r ON d.\"id\"=r.\"domain_id\" WHERE d.\"status\"='A' AND d.\"type\"='MASTER' AND r.\"type\"='SOA'" );
+               declare( suffix, "sql-infoslaves", "Get all unfresh slaves", "SELECT d.\"id\", d.\"name\", d.\"master\", d.\"last_check\", d.\"notified_serial\", d.\"auto_serial\", r.\"content\" FROM \"domains\" d LEFT JOIN \"records\" r ON ( d.\"id\"=r.\"domain_id\" AND r.\"type\"='SOA' ) WHERE d.\"status\"='A' AND d.\"type\"='SLAVE'" );
+               declare( suffix, "sql-infomasters", "Get all updated masters", "SELECT d.\"id\", d.\"name\", d.\"master\", d.\"last_check\", d.\"notified_serial\", d.\"auto_serial\", r.\"content\" FROM \"domains\" d LEFT JOIN \"records\" r ON ( d.\"id\"=r.\"domain_id\" AND r.\"type\"='SOA' ) WHERE d.\"status\"='A' AND d.\"type\"='MASTER'" );
 
                declare( suffix, "host", "depricated, use host-read and host-write instead","" );
        }
index cabacbc55e2b64cb9a48677c8c62cb1cec921b45..bde9eecbda48bfc52bef0b2dc374e853f16e2ca1 100644 (file)
@@ -20,6 +20,13 @@ bool OdbxBackend::connectTo( const vector<string>& hosts, QueryType type )
                m_handle[type] = NULL;
        }
 
+       if( type == WRITE && getArg( "backend" ) == "sqlite" )
+       {
+               L.log( m_myname + " Using same SQLite connection for reading and writeing to '" + hosts[odbx_host_index[READ]] + "'", Logger::Notice );
+               m_handle[WRITE] = m_handle[READ];
+               return true;
+       }
+
        for( i = 0; i < hosts.size(); i++ )
        {
                h = ( idx + i ) % hosts.size();
@@ -156,10 +163,10 @@ string OdbxBackend::escape( const string& str, QueryType type )
 
 
 
-bool OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) )
+bool OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, bool (*check_fcn)(uint32_t,uint32_t,SOAData*,DomainInfo*) )
 {
        const char* tmp;
-       u_int32_t nlast, nserial;
+       uint32_t nlast, nserial;
        DomainInfo di;
        SOAData sd;
 
@@ -188,12 +195,12 @@ bool OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, b
 
                if( ( tmp = odbx_field_value( m_result, 4 ) ) != NULL )
                {
-                       nlast = strtol( tmp, NULL, 10 );
+                       nserial = strtol( tmp, NULL, 10 );
                }
 
                if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
                {
-                       nserial = strtol( tmp, NULL, 10 );
+                       nlast = strtol( tmp, NULL, 10 );
                }
 
                if( (*check_fcn)( nlast, nserial, &sd, &di ) )
@@ -228,9 +235,9 @@ bool OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, b
 
 
 
-bool checkSlave( u_int32_t nlast, u_int32_t nserial, SOAData* sd, DomainInfo* di )
+bool checkSlave( uint32_t nlast, uint32_t nserial, SOAData* sd, DomainInfo* di )
 {
-       if( nlast + sd->refresh < (u_int32_t) time( 0 ) )
+       if( nlast + sd->refresh < (uint32_t) time( 0 ) )
        {
                di->kind = DomainInfo::Slave;
                return true;
@@ -241,7 +248,7 @@ bool checkSlave( u_int32_t nlast, u_int32_t nserial, SOAData* sd, DomainInfo* di
 
 
 
-bool checkMaster( u_int32_t nlast, u_int32_t nserial, SOAData* sd, DomainInfo* di )
+bool checkMaster( uint32_t nlast, uint32_t nserial, SOAData* sd, DomainInfo* di )
 {
        if( nserial != sd->serial )
        {