BIND 10 trac1065, updated. 39a0a5c65d0802f40ab428474b1e6d981a91fbce [1065] Subdomain match for SQLite3

BIND 10 source code commits bind10-changes at lists.isc.org
Sat Aug 13 16:02:17 UTC 2011


The branch, trac1065 has been updated
       via  39a0a5c65d0802f40ab428474b1e6d981a91fbce (commit)
       via  0c9db8bbeb7187218a5b47d82df18e38128d06a3 (commit)
       via  9882d600d0bbbc115671b12646e690ccddbf5348 (commit)
      from  59b545e90d30444a97c8e925569d240c819d42b4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 39a0a5c65d0802f40ab428474b1e6d981a91fbce
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Sat Aug 13 17:56:53 2011 +0200

    [1065] Subdomain match for SQLite3
    
    By simple WHERE name LIKE %.domain statement and switching between them.

commit 0c9db8bbeb7187218a5b47d82df18e38128d06a3
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Sat Aug 13 17:42:41 2011 +0200

    [1065] Tests for subdomain match in SQLite
    
    Both test where it should match and test where it should not.

commit 9882d600d0bbbc115671b12646e690ccddbf5348
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Sat Aug 13 17:17:09 2011 +0200

    [1065] Implement empty nonterminal in databases
    
    When there's a subdomain, we fake we found at RRset in this domain in
    the right place.

-----------------------------------------------------------------------

Summary of changes:
 src/lib/datasrc/database.cc                        |   11 ++++++
 src/lib/datasrc/sqlite3_accessor.cc                |   34 +++++++++++++++-----
 src/lib/datasrc/tests/sqlite3_accessor_unittest.cc |   10 ++++++
 3 files changed, 47 insertions(+), 8 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc
index d2202cd..70ce62f 100644
--- a/src/lib/datasrc/database.cc
+++ b/src/lib/datasrc/database.cc
@@ -254,6 +254,17 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
                                                 RDATA_COLUMN]);
             }
         }
+        if (!result_rrset && !records_found) {
+            // Nothing lives here. But check if something lives below this
+            // domain and if so, pretend something is here as well.
+            database_->searchForRecords(zone_id_, name.toText(), true);
+            if (database_->getNextRecord(columns,
+                                         DatabaseAccessor::COLUMN_COUNT)) {
+                records_found = true;
+                // We don't consume everything, so get rid of the rest
+                database_->resetSearch();
+            }
+        }
     } catch (const DataSourceError& dse) {
         logger.error(DATASRC_DATABASE_FIND_ERROR)
             .arg(database_->getDBName()).arg(dse.what());
diff --git a/src/lib/datasrc/sqlite3_accessor.cc b/src/lib/datasrc/sqlite3_accessor.cc
index e66aff4..ed929ca 100644
--- a/src/lib/datasrc/sqlite3_accessor.cc
+++ b/src/lib/datasrc/sqlite3_accessor.cc
@@ -25,7 +25,8 @@ namespace datasrc {
 struct SQLite3Parameters {
     SQLite3Parameters() :
         db_(NULL), version_(-1),
-        q_zone_(NULL), q_any_(NULL)
+        q_zone_(NULL), q_any_(NULL),
+        q_any_sub_(NULL), q_current_(NULL)
         /*q_record_(NULL), q_addrs_(NULL), q_referral_(NULL),
         q_count_(NULL), q_previous_(NULL), q_nsec3_(NULL),
         q_prevnsec3_(NULL) */
@@ -34,6 +35,8 @@ struct SQLite3Parameters {
     int version_;
     sqlite3_stmt* q_zone_;
     sqlite3_stmt* q_any_;
+    sqlite3_stmt* q_any_sub_;
+    sqlite3_stmt* q_current_;
     /*
     TODO: Yet unneeded statements
     sqlite3_stmt* q_record_;
@@ -76,6 +79,11 @@ public:
         if (params_.q_any_ != NULL) {
             sqlite3_finalize(params_.q_any_);
         }
+        if (params_.q_any_sub_ != NULL) {
+            sqlite3_finalize(params_.q_any_sub_);
+        }
+        // we do NOT finalize q_current_ - that is just a pointer to one of
+        // the other statements, not a separate one.
         /*
         if (params_.q_record_ != NULL) {
             sqlite3_finalize(params_.q_record_);
@@ -139,6 +147,9 @@ const char* const q_zone_str = "SELECT id FROM zones WHERE name=?1 AND rdclass =
 const char* const q_any_str = "SELECT rdtype, ttl, sigtype, rdata "
     "FROM records WHERE zone_id=?1 AND name=?2";
 
+const char* const q_any_sub_str = "SELECT rdtype, ttl, sigtype, rdata "
+    "FROM records WHERE zone_id=?1 AND name LIKE (\"%.\" || ?2)";
+
 /* TODO: Prune the statements, not everything will be needed maybe?
 const char* const q_record_str = "SELECT rdtype, ttl, sigtype, rdata "
     "FROM records WHERE zone_id=?1 AND name=?2 AND "
@@ -204,7 +215,10 @@ checkAndSetupSchema(Initializer* initializer) {
     }
 
     initializer->params_.q_zone_ = prepare(db, q_zone_str);
-    initializer->params_.q_any_ = prepare(db, q_any_str);
+    // Make sure the current is initialized to one of the statements, not NULL
+    initializer->params_.q_current_ = initializer->params_.q_any_ =
+        prepare(db, q_any_str);
+    initializer->params_.q_any_sub_ = prepare(db, q_any_sub_str);
     /* TODO: Yet unneeded statements
     initializer->params_.q_record_ = prepare(db, q_record_str);
     initializer->params_.q_addrs_ = prepare(db, q_addrs_str);
@@ -323,15 +337,19 @@ SQLite3Database::getZone(const isc::dns::Name& name) const {
 }
 
 void
-SQLite3Database::searchForRecords(int zone_id, const std::string& name, bool) {
+SQLite3Database::searchForRecords(int zone_id, const std::string& name,
+                                  bool subdomains)
+{
+    dbparameters_->q_current_ = subdomains ? dbparameters_->q_any_sub_ :
+        dbparameters_->q_any_;
     resetSearch();
-    if (sqlite3_bind_int(dbparameters_->q_any_, 1, zone_id) != SQLITE_OK) {
+    if (sqlite3_bind_int(dbparameters_->q_current_, 1, zone_id) != SQLITE_OK) {
         isc_throw(DataSourceError,
                   "Error in sqlite3_bind_int() for zone_id " <<
                   zone_id << ": " << sqlite3_errmsg(dbparameters_->db_));
     }
     // use transient since name is a ref and may disappear
-    if (sqlite3_bind_text(dbparameters_->q_any_, 2, name.c_str(), -1,
+    if (sqlite3_bind_text(dbparameters_->q_current_, 2, name.c_str(), -1,
                                SQLITE_TRANSIENT) != SQLITE_OK) {
         isc_throw(DataSourceError,
                   "Error in sqlite3_bind_text() for name " <<
@@ -376,7 +394,7 @@ SQLite3Database::getNextRecord(std::string columns[], size_t column_count) {
                     "of size " << COLUMN_COUNT << " to getNextRecord()");
     }
 
-    sqlite3_stmt* current_stmt = dbparameters_->q_any_;
+    sqlite3_stmt* current_stmt = dbparameters_->q_current_;
     const int rc = sqlite3_step(current_stmt);
 
     if (rc == SQLITE_ROW) {
@@ -404,8 +422,8 @@ SQLite3Database::getNextRecord(std::string columns[], size_t column_count) {
 
 void
 SQLite3Database::resetSearch() {
-    sqlite3_reset(dbparameters_->q_any_);
-    sqlite3_clear_bindings(dbparameters_->q_any_);
+    sqlite3_reset(dbparameters_->q_current_);
+    sqlite3_clear_bindings(dbparameters_->q_current_);
 }
 
 }
diff --git a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
index 097c821..9a7a41d 100644
--- a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
+++ b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
@@ -240,6 +240,16 @@ TEST_F(SQLite3Access, getRecords) {
     checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
                    "DNSKEY 5 2 3600 20100322084538 20100220084538 "
                    "33495 example.com. FAKEFAKEFAKEFAKE");
+
+    // Try searching for subdomain
+    // There's foo.bar.example.com in the data
+    db->searchForRecords(zone_id, "bar.example.com.", true);
+    EXPECT_TRUE(db->getNextRecord(columns, column_count));
+    checkRecordRow(columns, "A", "3600", "", "192.0.2.1");
+    EXPECT_FALSE(db->getNextRecord(columns, column_count));
+    // But we shouldn't match mix.example.com here
+    db->searchForRecords(zone_id, "ix.example.com.", true);
+    EXPECT_FALSE(db->getNextRecord(columns, column_count));
 }
 
 } // end anonymous namespace




More information about the bind10-changes mailing list