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 )
}
}
- 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;
}
m_result = NULL;
m_qname = qname;
-
+
if( zoneid < 0 )
{
if( qtype.getCode() == QType::ANY )
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 )
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 )
}
-void OdbxBackend::setFresh( u_int32_t domain_id )
+void OdbxBackend::setFresh( uint32_t domain_id )
{
size_t len;
-void OdbxBackend::setNotified( u_int32_t domain_id, u_int32_t serial )
+void OdbxBackend::setNotified( uint32_t domain_id, uint32_t serial )
{
try
{
-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
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 );
~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 );
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 );
};
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" );
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","" );
}
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();
-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;
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 ) )
-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;
-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 )
{