~ubuntu-branches/ubuntu/maverick/pdns/maverick-updates

« back to all changes in this revision

Viewing changes to modules/opendbxbackend/odbxbackend.cc

  • Committer: Bazaar Package Importer
  • Author(s): Debian PowerDNS Maintainers
  • Date: 2006-05-06 10:40:44 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060506104044-v9hczzfl7dcri6qt
Tags: 2.9.20-3
Disable the recursor, this is in a separate package now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "odbxbackend.hh"
 
2
 
 
3
 
 
4
 
 
5
unsigned int odbx_host_index = 0;
 
6
 
 
7
 
 
8
 
 
9
OdbxBackend::OdbxBackend( const string& suffix )
 
10
{
 
11
        int err = -1;
 
12
        unsigned int  idx, i, h;
 
13
        vector<string> hosts;
 
14
 
 
15
 
 
16
        try
 
17
        {
 
18
                m_result = NULL;
 
19
                m_myname = "[OpendbxBackend]";
 
20
                m_default_ttl = arg().asNum( "default-ttl" );
 
21
                m_qlog = arg().mustDo( "query-logging" );
 
22
 
 
23
                setArgPrefix( "opendbx" + suffix );
 
24
                stringtok( hosts, getArg( "host" ), ", " );
 
25
 
 
26
                idx = odbx_host_index++ % hosts.size();
 
27
 
 
28
                for( i = 0; i < hosts.size(); i++ )
 
29
                {
 
30
                        h = ( idx + i ) % hosts.size();
 
31
                        if( !( err = odbx_init( &m_handle, getArg( "backend" ).c_str(), hosts[h].c_str(), getArg( "port" ).c_str() ) ) ) { break; }
 
32
                }
 
33
 
 
34
                if( err < 0 )
 
35
                {
 
36
                        L.log( m_myname + " OdbxBackend: Unable to connect to server - " + string( odbx_error( m_handle, err ) ),  Logger::Error );
 
37
                        throw( AhuException( "Fatal: odbx_init() failed" ) );
 
38
                }
 
39
 
 
40
                if( ( err = odbx_bind_simple( m_handle, getArg( "database" ).c_str(), getArg( "username" ).c_str(), getArg( "password" ).c_str() ) ) < 0 )
 
41
                {
 
42
                        L.log( m_myname + " OdbxBackend: Unable to bind to database - " + string( odbx_error( m_handle, err ) ),  Logger::Error );
 
43
                        throw( AhuException( "Fatal: odbx_bind_simple() failed" ) );
 
44
                }
 
45
        }
 
46
        catch( exception& e )
 
47
        {
 
48
                L.log( m_myname + " OdbxBackend: Caught STL exception - " + e.what(),  Logger::Error );
 
49
                throw( DBException( "Fatal: STL exception" ) );
 
50
        }
 
51
 
 
52
        L.log( m_myname + " Connection succeeded", Logger::Notice );
 
53
}
 
54
 
 
55
 
 
56
 
 
57
OdbxBackend::~OdbxBackend()
 
58
{
 
59
        odbx_unbind( m_handle );
 
60
        odbx_finish( m_handle );
 
61
}
 
62
 
 
63
 
 
64
 
 
65
bool OdbxBackend::getDomainInfo( const string& domain, DomainInfo& di )
 
66
{
 
67
        const char* tmp;
 
68
        string stmt;
 
69
 
 
70
 
 
71
        try
 
72
        {
 
73
                DLOG( L.log( m_myname + " getDomainInfo()", Logger::Debug ) );
 
74
 
 
75
                stmt = strbind( ":name", escape( toLower( domain ) ), getArg( "sql-zoneinfo" ) );
 
76
                execStmt( stmt.c_str(), stmt.size(), true );
 
77
 
 
78
                if( !getRecord() ) { return false; }
 
79
 
 
80
                do
 
81
                {
 
82
                        di.id = 0;
 
83
                        di.zone = "";
 
84
                        di.master = "";
 
85
                        di.last_check = 0;
 
86
                        di.notified_serial = 0;
 
87
                        di.kind = DomainInfo::Native;
 
88
                        di.backend = this;
 
89
                        di.serial = 0;
 
90
 
 
91
                        if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
 
92
                        {
 
93
                                di.id = strtol( tmp, NULL, 10 );
 
94
                        }
 
95
 
 
96
                        if( ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
 
97
                        {
 
98
                                di.zone = string( tmp );
 
99
                        }
 
100
 
 
101
                        if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
 
102
                        {
 
103
                                if( !strncmp( tmp, "SLAVE", 5 ) )
 
104
                                {
 
105
                                        di.kind = DomainInfo::Slave;
 
106
                                }
 
107
                                else if( !strncmp( tmp, "MASTER", 6 ) )
 
108
                                {
 
109
                                        di.kind = DomainInfo::Master;
 
110
                                }
 
111
                        }
 
112
 
 
113
                        if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
 
114
                        {
 
115
                                di.master = string( tmp );
 
116
                        }
 
117
 
 
118
                        if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
 
119
                        {
 
120
                                di.last_check = strtol( tmp, NULL, 10 );
 
121
                        }
 
122
 
 
123
                        if( ( tmp = odbx_field_value( m_result, 6 ) ) != NULL )
 
124
                        {
 
125
                                SOAData sd;
 
126
 
 
127
                                sd.serial = 0;
 
128
                                        DNSPacket::fillSOAData( string( tmp ), sd );
 
129
                                di.serial = sd.serial;
 
130
                        }
 
131
                }
 
132
                while( getRecord() );
 
133
        }
 
134
        catch( exception& e )
 
135
        {
 
136
                L.log( m_myname + " getDomainInfo: Caught STL exception - " + e.what(),  Logger::Error );
 
137
                throw( DBException( "Error: STL exception" ) );
 
138
        }
 
139
 
 
140
        return true;
 
141
}
 
142
 
 
143
 
 
144
 
 
145
bool OdbxBackend::list( const string& target, int zoneid )
 
146
{
 
147
        string stmt;
 
148
        size_t len;
 
149
 
 
150
 
 
151
 
 
152
        try
 
153
        {
 
154
                DLOG( L.log( m_myname + " list()", Logger::Debug ) );
 
155
 
 
156
                m_qname = "";
 
157
                m_result = NULL;
 
158
 
 
159
                len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
 
160
 
 
161
                if( len < 0 || len > sizeof( m_buffer ) - 1 )
 
162
                {
 
163
                        L.log( m_myname + " list: Unable to convert zone id to string",  Logger::Error );
 
164
                        throw( DBException( "Error: Libc error" ) );
 
165
                }
 
166
 
 
167
                stmt = strbind( ":id", string( m_buffer, len ), getArg( "sql-list" ) );
 
168
 
 
169
                execStmt( stmt.c_str(), stmt.size(), true );
 
170
        }
 
171
        catch( exception& e )
 
172
        {
 
173
                L.log( m_myname + " list: Caught STL exception - " + e.what(),  Logger::Error );
 
174
                throw( DBException( "Error: STL exception" ) );
 
175
        }
 
176
 
 
177
        return true;
 
178
}
 
179
 
 
180
 
 
181
 
 
182
void OdbxBackend::lookup( const QType& qtype, const string& qname, DNSPacket* dnspkt, int zoneid )
 
183
{
 
184
        string stmt;
 
185
 
 
186
 
 
187
        try
 
188
        {
 
189
                DLOG( L.log( m_myname + " lookup()", Logger::Debug ) );
 
190
 
 
191
                m_result = NULL;
 
192
                m_qname = qname;
 
193
                
 
194
                if( zoneid < 0 )
 
195
                {
 
196
                        if( qtype.getCode() == QType::ANY )
 
197
                        {
 
198
                                stmt = getArg( "sql-lookup" );
 
199
                        } else {
 
200
                                stmt = strbind( ":type", qtype.getName(), getArg( "sql-lookuptype" ) );
 
201
                        }
 
202
                }
 
203
                else
 
204
                {
 
205
                        if( qtype.getCode() == QType::ANY )
 
206
                        {
 
207
                                stmt = getArg( "sql-lookupid" );
 
208
                        } else {
 
209
                                stmt = strbind( ":type", qtype.getName(), getArg( "sql-lookuptypeid" ) );
 
210
                        }
 
211
                        
 
212
                        size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
 
213
 
 
214
                        if( len < 0 || len > sizeof( m_buffer ) - 1 )
 
215
                        {
 
216
                                L.log( m_myname + " lookup: Unable to convert zone id to string",  Logger::Error );
 
217
                                throw( DBException( "Error: Libc error" ) );
 
218
                        }
 
219
 
 
220
                        stmt = strbind( ":id", string( m_buffer, len ), stmt );
 
221
                }
 
222
 
 
223
                stmt = strbind( ":name", escape( toLower( qname ) ), stmt );
 
224
                execStmt( stmt.c_str(), stmt.size(), true );
 
225
        }
 
226
        catch( exception& e )
 
227
        {
 
228
                L.log( m_myname + " lookup: Caught STL exception - " + e.what(),  Logger::Error );
 
229
                throw( DBException( "Error: STL exception" ) );
 
230
        }
 
231
}
 
232
 
 
233
 
 
234
 
 
235
bool OdbxBackend::get( DNSResourceRecord& rr )
 
236
{
 
237
        const char* tmp;
 
238
 
 
239
 
 
240
        try
 
241
        {
 
242
                DLOG( L.log( m_myname + " get()", Logger::Debug ) );
 
243
 
 
244
                if( getRecord() )
 
245
                {
 
246
                        rr.content = "";
 
247
                        rr.priority = 0;
 
248
                        rr.domain_id = 0;
 
249
                        rr.last_modified = 0;
 
250
                        rr.ttl = m_default_ttl;
 
251
                        rr.qname = m_qname;
 
252
 
 
253
                        if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
 
254
                        {
 
255
                                rr.domain_id = strtol( tmp, NULL, 10 );
 
256
                        }
 
257
 
 
258
                        if( m_qname.empty() && ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
 
259
                        {
 
260
                                rr.qname = string( tmp );
 
261
                        }
 
262
 
 
263
                        if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
 
264
                        {
 
265
                                rr.qtype = QType( tmp );
 
266
                        }
 
267
 
 
268
                        if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
 
269
                        {
 
270
                                rr.ttl = strtoul( tmp, NULL, 10 );
 
271
                        }
 
272
 
 
273
                        if( ( tmp = odbx_field_value( m_result, 4 ) ) != NULL )
 
274
                        {
 
275
                                rr.priority = (u_int16_t) strtoul( tmp, NULL, 10 );
 
276
                        }
 
277
 
 
278
                        if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
 
279
                        {
 
280
                                rr.content = string( tmp );
 
281
                        }
 
282
 
 
283
                        return true;
 
284
                }
 
285
        }
 
286
        catch( exception& e )
 
287
        {
 
288
                L.log( m_myname + " get: Caught STL exception - " + e.what(),  Logger::Error );
 
289
                throw( DBException( "Error: STL exception" ) );
 
290
        }
 
291
 
 
292
        return false;
 
293
}
 
294
 
 
295
 
 
296
void OdbxBackend::setFresh( u_int32_t domain_id )
 
297
{
 
298
        size_t len;
 
299
 
 
300
 
 
301
        try
 
302
        {
 
303
                DLOG( L.log( m_myname + " setFresh()", Logger::Debug ) );
 
304
 
 
305
                len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-lastcheck" ).c_str(), time( 0 ), domain_id );
 
306
 
 
307
                if( len < 0 || len > sizeof( m_buffer ) - 1 )
 
308
                {
 
309
                        L.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "'",  Logger::Error );
 
310
                        throw( DBException( "Error: Libc error" ) );
 
311
                }
 
312
 
 
313
                execStmt( m_buffer, len, false );
 
314
        }
 
315
        catch ( exception& e )
 
316
        {
 
317
                L.log( m_myname + " setFresh: Caught STL exception - " + e.what(),  Logger::Error );
 
318
                throw( DBException( "Error: STL exception" ) );
 
319
        }
 
320
}
 
321
 
 
322
 
 
323
 
 
324
void OdbxBackend::setNotified( u_int32_t domain_id, u_int32_t serial )
 
325
{
 
326
        size_t len;
 
327
 
 
328
 
 
329
        try
 
330
        {
 
331
                DLOG( L.log( m_myname + " setNotified()", Logger::Debug ) );
 
332
 
 
333
                len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-serial" ).c_str(), serial, domain_id );
 
334
 
 
335
                if( len < 0 || len > sizeof( m_buffer ) - 1 )
 
336
                {
 
337
                        L.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "'",  Logger::Error );
 
338
                        throw( DBException( "Error: Libc error" ) );
 
339
                }
 
340
 
 
341
                execStmt( m_buffer, len, false );
 
342
        }
 
343
        catch ( exception& e )
 
344
        {
 
345
                L.log( m_myname + " setNotified: Caught STL exception - " + e.what(),  Logger::Error );
 
346
                throw( DBException( "Error: STL exception" ) );
 
347
        }
 
348
}
 
349
 
 
350
 
 
351
 
 
352
bool OdbxBackend::isMaster( const string& domain, const string& ip )
 
353
{
 
354
        string stmt;
 
355
 
 
356
 
 
357
        try
 
358
        {
 
359
                DLOG( L.log( m_myname + " isMaster()", Logger::Debug ) );
 
360
 
 
361
                stmt = strbind( ":name", escape( toLower( domain ) ), getArg( "sql-master" ) );
 
362
                execStmt( stmt.c_str(), stmt.size(), true );
 
363
 
 
364
                if( !getRecord() ) { return false; }
 
365
 
 
366
                do
 
367
                {
 
368
                        if( odbx_field_value( m_result, 0 ) != NULL )
 
369
                        {
 
370
                                if( !strcmp( odbx_field_value( m_result, 0 ), ip.c_str() ) )
 
371
                                {
 
372
                                        return true;
 
373
                                }
 
374
                        }
 
375
                }
 
376
                while( getRecord() );
 
377
        }
 
378
        catch ( exception& e )
 
379
        {
 
380
                L.log( m_myname + " isMaster: Caught STL exception - " + e.what(),  Logger::Error );
 
381
                throw( DBException( "Error: STL exception" ) );
 
382
        }
 
383
 
 
384
        return false;
 
385
}
 
386
 
 
387
 
 
388
 
 
389
void OdbxBackend::getUnfreshSlaveInfos( vector<DomainInfo>* unfresh )
 
390
{
 
391
        try
 
392
        {
 
393
                DLOG( L.log( m_myname + " getUnfreshSlaveInfos()", Logger::Debug ) );
 
394
 
 
395
                if( unfresh != NULL )
 
396
                {
 
397
                        getDomainList( getArg( "sql-infoslaves" ), unfresh, &checkSlave );
 
398
                }
 
399
        }
 
400
        catch ( exception& e )
 
401
        {
 
402
                L.log( m_myname + " getUnfreshSlaveInfo: Caught STL exception - " + e.what(),  Logger::Error );
 
403
                throw( DBException( "Error: STL exception" ) );
 
404
        }
 
405
}
 
406
 
 
407
 
 
408
 
 
409
void OdbxBackend::getUpdatedMasters( vector<DomainInfo>* updated )
 
410
{
 
411
        try
 
412
        {
 
413
                DLOG( L.log( m_myname + " getUpdatedMasters()", Logger::Debug ) );
 
414
 
 
415
                if( updated != NULL )
 
416
                {
 
417
                        getDomainList( getArg( "sql-infomasters" ), updated, &checkMaster );
 
418
                }
 
419
        }
 
420
        catch ( exception& e )
 
421
        {
 
422
                L.log( m_myname + " getUpdatedMasters: Caught STL exception - " + e.what(),  Logger::Error );
 
423
                throw( DBException( "Error: STL exception" ) );
 
424
        }
 
425
}
 
426
 
 
427
 
 
428
 
 
429
bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, const vector<DNSResourceRecord>& set, string* account, DNSBackend** ddb )
 
430
{
 
431
        string stmt;
 
432
        vector<DNSResourceRecord>::const_iterator i;
 
433
 
 
434
 
 
435
        try
 
436
        {
 
437
                DLOG( L.log( m_myname + " superMasterBackend()", Logger::Debug ) );
 
438
 
 
439
                if( account != NULL && ddb != NULL )
 
440
                {
 
441
                        for( i = set.begin(); i != set.end(); i++ )
 
442
                        {
 
443
                                stmt = strbind( ":ip", escape( ip ), getArg( "sql-supermaster" ) );
 
444
                                stmt = strbind( ":ns", escape( i->content ), stmt );
 
445
 
 
446
                                execStmt( stmt.c_str(), stmt.size(), true );
 
447
 
 
448
                                if( !getRecord() ) { return false; }
 
449
 
 
450
                                do
 
451
                                {
 
452
                                        if( odbx_field_value( m_result, 0 ) != NULL )
 
453
                                        {
 
454
                                                *account = string( odbx_field_value( m_result, 0 ), odbx_field_length( m_result, 0 ) );
 
455
                                        }
 
456
                                }
 
457
                                while( getRecord() );
 
458
 
 
459
                                *ddb=this;
 
460
                                return true;
 
461
                        }
 
462
                }
 
463
        }
 
464
        catch ( exception& e )
 
465
        {
 
466
                L.log( m_myname + " superMasterBackend: Caught STL exception - " + e.what(),  Logger::Error );
 
467
                throw( DBException( "Error: STL exception" ) );
 
468
        }
 
469
 
 
470
        return false;
 
471
}
 
472
 
 
473
 
 
474
 
 
475
bool OdbxBackend::createSlaveDomain( const string& ip, const string& domain, const string& account )
 
476
{
 
477
        size_t len;
 
478
 
 
479
 
 
480
        try
 
481
        {
 
482
                DLOG( L.log( m_myname + " createSlaveDomain()", Logger::Debug ) );
 
483
 
 
484
                len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-slave" ).c_str(), escape( toLower( domain ) ).c_str(),
 
485
                        escape( ip ).c_str(), escape( account ).c_str() );
 
486
 
 
487
                if( len < 0 || len > sizeof( m_buffer ) - 1 )
 
488
                {
 
489
                        L.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "'",  Logger::Error );
 
490
                        throw( DBException( "Error: Libc error" ) );
 
491
                }
 
492
 
 
493
                execStmt( m_buffer, len, false );
 
494
        }
 
495
        catch ( exception& e )
 
496
        {
 
497
                L.log( m_myname + " createSlaveDomain: Caught STL exception - " + e.what(),  Logger::Error );
 
498
                throw( DBException( "Error: STL exception" ) );
 
499
        }
 
500
 
 
501
        return true;
 
502
}
 
503
 
 
504
 
 
505
 
 
506
bool OdbxBackend::feedRecord( const DNSResourceRecord& rr )
 
507
{
 
508
        size_t len;
 
509
 
 
510
 
 
511
        try
 
512
        {
 
513
                DLOG( L.log( m_myname + " feedRecord()", Logger::Debug ) );
 
514
 
 
515
                len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-record" ).c_str(), rr.domain_id,
 
516
                        escape( toLower( rr.qname ) ).c_str(), rr.qtype.getName().c_str(), rr.ttl, rr.priority, escape( rr.content ).c_str() );
 
517
 
 
518
                if( len < 0 || len > sizeof( m_buffer ) - 1 )
 
519
                {
 
520
                        L.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "'",  Logger::Error );
 
521
                        throw( DBException( "Error: Libc error" ) );
 
522
                }
 
523
 
 
524
                execStmt( m_buffer, len, false );
 
525
        }
 
526
        catch ( exception& e )
 
527
        {
 
528
                L.log( m_myname + " feedRecord: Caught STL exception - " + e.what(),  Logger::Error );
 
529
                throw( DBException( "Error: STL exception" ) );
 
530
        }
 
531
 
 
532
        return true;
 
533
}
 
534
 
 
535
 
 
536
 
 
537
bool OdbxBackend::startTransaction( const string& domain, int zoneid )
 
538
{
 
539
        size_t len;
 
540
        string stmt;
 
541
 
 
542
 
 
543
        try
 
544
        {
 
545
                DLOG( L.log( m_myname + " startTransaction()", Logger::Debug ) );
 
546
 
 
547
                stmt = getArg( "sql-transactbegin" );
 
548
                execStmt( stmt.c_str(), stmt.size(), false );
 
549
 
 
550
                len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
 
551
 
 
552
                if( len < 0 || len > sizeof( m_buffer ) - 1 )
 
553
                {
 
554
                        L.log( m_myname + " lookup: Unable to convert zone id to string",  Logger::Error );
 
555
                        throw( DBException( "Error: Libc error" ) );
 
556
                }
 
557
 
 
558
                stmt = strbind( ":id", string( m_buffer, len ), getArg( "sql-zonedelete" ) );
 
559
 
 
560
                execStmt( stmt.c_str(), stmt.size(), false );
 
561
        }
 
562
        catch ( exception& e )
 
563
        {
 
564
                L.log( m_myname + " startTransaction: Caught STL exception - " + e.what(),  Logger::Error );
 
565
                throw( DBException( "Error: STL exception" ) );
 
566
        }
 
567
 
 
568
        return true;
 
569
}
 
570
 
 
571
 
 
572
 
 
573
bool OdbxBackend::commitTransaction()
 
574
{
 
575
        try
 
576
        {
 
577
                DLOG( L.log( m_myname + " commitTransaction()", Logger::Debug ) );
 
578
 
 
579
                execStmt( getArg( "sql-transactend" ).c_str(), getArg( "sql-transactend" ).size(), false );
 
580
        }
 
581
        catch ( exception& e )
 
582
        {
 
583
                L.log( m_myname + " commitTransaction: Caught STL exception - " + e.what(),  Logger::Error );
 
584
                throw( DBException( "Error: STL exception" ) );
 
585
        }
 
586
 
 
587
        return true;
 
588
}
 
589
 
 
590
 
 
591
 
 
592
bool OdbxBackend::abortTransaction()
 
593
{
 
594
        try
 
595
        {
 
596
                DLOG( L.log( m_myname + " abortTransaction()", Logger::Debug ) );
 
597
 
 
598
                execStmt( getArg( "sql-transactabort" ).c_str(), getArg( "sql-transabort" ).size(), false );
 
599
        }
 
600
        catch ( exception& e )
 
601
        {
 
602
                L.log( m_myname + " abortTransaction: Caught STL exception - " + e.what(),  Logger::Error );
 
603
                throw( DBException( "Error: STL exception" ) );
 
604
        }
 
605
 
 
606
        return true;
 
607
}