diff --git a/bin/tests/db_test.c b/bin/tests/db_test.c index dbff317c01..8431931bfc 100644 --- a/bin/tests/db_test.c +++ b/bin/tests/db_test.c @@ -742,7 +742,8 @@ main(int argc, char *argv[]) { if (dbi != NULL && addmode && !found_as) { rdataset.ttl++; result = dns_db_addrdataset(db, node, version, - 0, &rdataset); + 0, &rdataset, + NULL); if (result != DNS_R_SUCCESS) printf("%s\n", dns_result_totext(result)); diff --git a/lib/dns/db.c b/lib/dns/db.c index 11e498adfd..8cb18d22a8 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -394,7 +394,8 @@ dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_result_t dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset) + isc_stdtime_t now, dns_rdataset_t *rdataset, + dns_rdataset_t *addedrdataset) { /* * Add 'rdataset' to 'node' in version 'version' of 'db'. @@ -407,8 +408,12 @@ dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); REQUIRE(rdataset->rdclass == db->rdclass); + REQUIRE(addedrdataset == NULL || + (DNS_RDATASET_VALID(addedrdataset) && + addedrdataset->methods == NULL)); - return ((db->methods->addrdataset)(db, node, version, now, rdataset)); + return ((db->methods->addrdataset)(db, node, version, now, rdataset, + addedrdataset)); } dns_result_t diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index 3b7b5c1d61..13f9a0284c 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -114,7 +114,8 @@ typedef struct dns_dbmethods { dns_result_t (*addrdataset)(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, - dns_rdataset_t *rdataset); + dns_rdataset_t *rdataset, + dns_rdataset_t *addedrdataset); dns_result_t (*deleterdataset)(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type); @@ -754,7 +755,8 @@ dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_result_t dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset); + isc_stdtime_t now, dns_rdataset_t *rdataset, + dns_rdataset_t *addedrdataset); /* * Add 'rdataset' to 'node' in version 'version' of 'db'. * @@ -764,6 +766,9 @@ dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, * a cache database, then the added rdataset will expire no later than * now + rdataset->ttl. * + * If 'addedrdataset' is not NULL, then it will be attached to the + * rdataset added to the database. + * * Requires: * * 'db' is a valid database. @@ -773,6 +778,8 @@ dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, * 'rdataset' is a valid, associated rdataset with the same class * as 'db'. * + * 'addedrdataset' is NULL, or a valid, unassociated rdataset. + * * The database has zone semantics and 'version' is a valid * read-write version, or the database has cache semantics * and version is NULL. diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 3c759d2f24..18cd2f6b7a 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -2230,7 +2230,8 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, static dns_result_t add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, - rdatasetheader_t *newheader, isc_boolean_t merge, isc_boolean_t loading) + rdatasetheader_t *newheader, isc_boolean_t merge, isc_boolean_t loading, + dns_rdataset_t *addedrdataset, isc_stdtime_t now) { rbtdb_changed_t *changed = NULL; rdatasetheader_t *header, *header_prev; @@ -2293,8 +2294,13 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, newheader = (rdatasetheader_t *)merged; } else { free_rdataset(rbtdb->common.mctx, newheader); - if (result == DNS_R_UNCHANGED) + if (result == DNS_R_UNCHANGED) { + if (addedrdataset != NULL) + bind_rdataset(rbtdb, rbtnode, + header, now, + addedrdataset); return (DNS_R_SUCCESS); + } return (result); } } @@ -2330,6 +2336,9 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, rbtnode->data = newheader; } + if (addedrdataset != NULL) + bind_rdataset(rbtdb, rbtnode, newheader, now, addedrdataset); + return (DNS_R_SUCCESS); } @@ -2348,7 +2357,8 @@ delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, static dns_result_t addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset) + isc_stdtime_t now, dns_rdataset_t *rdataset, + dns_rdataset_t *addedrdataset) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; @@ -2399,7 +2409,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); - result = add(rbtdb, rbtnode, rbtversion, newheader, merge, ISC_FALSE); + result = add(rbtdb, rbtnode, rbtversion, newheader, merge, ISC_FALSE, + addedrdataset, now); if (result == DNS_R_SUCCESS && delegating) rbtnode->find_callback = 1; @@ -2440,7 +2451,7 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); result = add(rbtdb, rbtnode, rbtversion, newheader, ISC_FALSE, - ISC_FALSE); + ISC_FALSE, NULL, 0); UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); @@ -2487,7 +2498,7 @@ add_rdataset_callback(dns_rdatacallbacks_t *callbacks, dns_name_t *name, newheader->serial = 1; result = add(rbtdb, node, rbtdb->current_version, newheader, ISC_TRUE, - ISC_TRUE); + ISC_TRUE, NULL, 0); if (result == DNS_R_SUCCESS && delegating_type(rbtdb, node, rdataset->type)) node->find_callback = 1;