diff --git a/CHANGES b/CHANGES index c177a44dd57efd3daaf891030b5aaf0a59866a0e..2e557ae642e477c676d72ea6afeda0aa53ab9888 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4439. [bug] Address race conditions getting ownernames of nodes. + [RT #43005] + 4438. [func] Use LIFO rather than FIFO when processing startup notify and refresh queries. [RT #42825] diff --git a/bin/tests/system/dyndb/driver/db.c b/bin/tests/system/dyndb/driver/db.c index deb73a06fc0780f71c195283f53edb82105b3f5c..ef74e66ac9bba2dfd8ef39b4a68aea7e8bda6598 100644 --- a/bin/tests/system/dyndb/driver/db.c +++ b/bin/tests/system/dyndb/driver/db.c @@ -622,7 +622,8 @@ static dns_dbmethods_t sampledb_methods = { findnodeext, findext, setcachestats, - hashsize + hashsize, + NULL }; /* Auxiliary driver functions. */ diff --git a/lib/dns/db.c b/lib/dns/db.c index 83c8268045286909b5376c770e65adbdc588f4ea..49be6e22afb163355dc071ed02e89073969158f2 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -1100,3 +1100,14 @@ dns_db_updatenotify_unregister(dns_db_t *db, return (ISC_R_NOTFOUND); } + +isc_result_t +dns_db_nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name) { + REQUIRE(db != NULL); + REQUIRE(node != NULL); + REQUIRE(name != NULL); + + if (db->methods->nodefullname == NULL) + return (ISC_R_NOTIMPLEMENTED); + return ((db->methods->nodefullname)(db, node, name)); +} diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c index f431bb65ef192dc2dffa1f96630bc3e209eb3871..27135bfedb20132c4ccc727823f201da96607770 100644 --- a/lib/dns/ecdb.c +++ b/lib/dns/ecdb.c @@ -581,7 +581,8 @@ static dns_dbmethods_t ecdb_methods = { NULL, /* findnodeext */ NULL, /* findext */ NULL, /* setcachestats */ - NULL /* hashsize */ + NULL, /* hashsize */ + NULL /* nodefullname */ }; static isc_result_t diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index 7c7ce9598bde4fcb4083f6ce4922a99d2803a912..c2e1228e6ddcb82121fd5d1c28971bc2011253ff 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -186,6 +186,8 @@ typedef struct dns_dbmethods { dns_rdataset_t *sigrdataset); isc_result_t (*setcachestats)(dns_db_t *db, isc_stats_t *stats); size_t (*hashsize)(dns_db_t *db); + isc_result_t (*nodefullname)(dns_db_t *db, dns_dbnode_t *node, + dns_name_t *name); } dns_dbmethods_t; typedef isc_result_t @@ -1654,6 +1656,16 @@ dns_db_updatenotify_unregister(dns_db_t *db, * */ +isc_result_t +dns_db_nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name); +/*%< + * Get the name associated with a database node. + * + * Requires: + * + * \li 'db' is a valid database + * \li 'node' and 'name' are not NULL + */ ISC_LANG_ENDDECLS #endif /* DNS_DB_H */ diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 7a900202609b5d1523056ad13b731eea27f9a36d..663cf18f6a9d1792120eacfdb51a7d1e75facdb6 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -218,6 +218,7 @@ typedef isc_uint64_t rbtdb_serial_t; #define new_reference new_reference64 #define newversion newversion64 #define nodecount nodecount64 +#define nodefullname nodefullname64 #define overmem overmem64 #define previous_closest_nsec previous_closest_nsec64 #define printnode printnode64 @@ -6630,7 +6631,9 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); + RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); dns_rbt_fullnamefromnode(node, name); + RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); dns_rdataset_getownercase(rdataset, name); newheader = (rdatasetheader_t *)region.base; @@ -8061,6 +8064,23 @@ getrrsetstats(dns_db_t *db) { return (rbtdb->rrsetstats); } +static isc_result_t +nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name) { + dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; + dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; + isc_result_t result; + + REQUIRE(VALID_RBTDB(rbtdb)); + REQUIRE(node != NULL); + REQUIRE(name != NULL); + + RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); + result = dns_rbt_fullnamefromnode(rbtnode, name); + RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); + + return (result); +} + static dns_dbmethods_t zone_methods = { attach, detach, @@ -8104,7 +8124,8 @@ static dns_dbmethods_t zone_methods = { NULL, NULL, NULL, - hashsize + hashsize, + nodefullname }; static dns_dbmethods_t cache_methods = { @@ -8150,7 +8171,8 @@ static dns_dbmethods_t cache_methods = { NULL, NULL, setcachestats, - hashsize + hashsize, + nodefullname }; isc_result_t diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 5535ab839557b0e1c13a2e570705f1ef4354a66b..c86ef960941d09d1d7a107c115ba17fbf2110162 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -1289,7 +1289,8 @@ static dns_dbmethods_t sdb_methods = { findnodeext, findext, NULL, /* setcachestats */ - NULL /* hashsize */ + NULL, /* hashsize */ + NULL /* nodefullname */ }; static isc_result_t diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c index 301cfbadf2755129e3ab25bf04699b898fca6e92..fb77f9b9d1f0613459c1e4deaa6f34868a6facc7 100644 --- a/lib/dns/sdlz.c +++ b/lib/dns/sdlz.c @@ -1323,7 +1323,8 @@ static dns_dbmethods_t sdlzdb_methods = { findnodeext, findext, NULL, /* setcachestats */ - NULL /* hashsize */ + NULL, /* hashsize */ + NULL /* nodefullname */ }; /* diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 2c5f8f49282b4bb6f03be645977f33bd297f2c6e..ff860fa21e36480a8450ea6f945a695492d5375a 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -227,6 +227,7 @@ dns_db_load2 dns_db_load3 dns_db_newversion dns_db_nodecount +dns_db_nodefullname dns_db_ondestroy dns_db_origin dns_db_overmem diff --git a/lib/dns/zone.c b/lib/dns/zone.c index d59e719eeff723b83d4e54688635eccc9d7e9dfe..e3c884f5bda0410045fd8f71923ebfa7497b6458 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include @@ -13980,9 +13979,11 @@ checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_init(&temprdataset); result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); - dns_rbtnode_nodename(node, name); + result = dns_db_nodefullname(db, node, name); + RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdataset_getownercase(rdataset, name); dns_rdataset_setownercase(&temprdataset, name); return (dns_db_addrdataset(db, node, version, 0, &temprdataset,