diff --git a/Knot.files b/Knot.files index 315e42c2d5a5b1fd421b3af34821eadf98172854..d370f89c6ea626729627aba86200014e7a98693b 100644 --- a/Knot.files +++ b/Knot.files @@ -129,6 +129,8 @@ src/knot/server/tcp-handler.c src/knot/server/tcp-handler.h src/knot/server/udp-handler.c src/knot/server/udp-handler.h +src/knot/server/zones.c +src/knot/server/zones.h src/knot/ctl/process.c src/knot/ctl/process.h src/knot/conf/cf-lex.l diff --git a/src/dnslib/zonedb.c b/src/dnslib/zonedb.c index f97782ae505053846b3bc5642c2033b811ac0dbd..2a2f2e0e2df3bdc2d6f7e1dd9cd58f03ad2176f7 100644 --- a/src/dnslib/zonedb.c +++ b/src/dnslib/zonedb.c @@ -165,6 +165,10 @@ void dnslib_zonedb_free(dnslib_zonedb_t **db) void dnslib_zonedb_deep_free(dnslib_zonedb_t **db) { + debug_dnslib_zonedb("Deleting zone db (%p).\n", *db); + debug_dnslib_zonedb("Is it empty (%p)? %s\n", + (*db)->zones, skip_is_empty((*db)->zones) ? "yes" : "no"); + const skip_node_t *zn = skip_first((*db)->zones); dnslib_zone_t *zone = NULL; diff --git a/src/knot/other/debug.h b/src/knot/other/debug.h index 01feaff68fa099012030cc54a8c0371426d9eba4..121efb3ecd31a972f9134417926fb81f780b8398 100644 --- a/src/knot/other/debug.h +++ b/src/knot/other/debug.h @@ -20,7 +20,7 @@ //#define SERVER_DEBUG //#define DT_DEBUG //#define NET_DEBUG -#define ZONES_DEBUG +//#define ZONES_DEBUG #ifdef SERVER_DEBUG #define debug_server(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg) diff --git a/src/knot/server/name-server.c b/src/knot/server/name-server.c index 0f2205d2466c943ef312a6e8cc4c6727ee3f8609..1133cfda156a2bbabf7c9d761207cd38b284db28 100644 --- a/src/knot/server/name-server.c +++ b/src/knot/server/name-server.c @@ -1763,18 +1763,27 @@ static int ns_response_to_wire(dnslib_response_t *resp, uint8_t *wire, /* Public functions */ /*----------------------------------------------------------------------------*/ -ns_nameserver_t *ns_create(dnslib_zonedb_t *database) +ns_nameserver_t *ns_create() { ns_nameserver_t *ns = malloc(sizeof(ns_nameserver_t)); if (ns == NULL) { ERR_ALLOC_FAILED; return NULL; } - ns->zone_db = database; + + // Create zone database structure + debug_ns("Creating Zone Database structure...\n"); + ns->zone_db = dnslib_zonedb_new(); + if (ns->zone_db == NULL) { + ERR_ALLOC_FAILED; + free(ns); + return NULL; + } // prepare empty response with SERVFAIL error dnslib_response_t *err = dnslib_response_new_empty(NULL); if (err == NULL) { + ERR_ALLOC_FAILED; free(ns); return NULL; } @@ -1913,11 +1922,16 @@ int ns_answer_request(ns_nameserver_t *nameserver, const uint8_t *query_wire, void ns_destroy(ns_nameserver_t **nameserver) { - // do nothing with the zone database! + synchronize_rcu(); + free((*nameserver)->err_response); if ((*nameserver)->opt_rr != NULL) { dnslib_edns_free(&(*nameserver)->opt_rr); } + + // destroy the zone db + dnslib_zonedb_deep_free(&(*nameserver)->zone_db); + free(*nameserver); *nameserver = NULL; } @@ -1927,7 +1941,7 @@ void ns_destroy(ns_nameserver_t **nameserver) int ns_conf_hook(const struct conf_t *conf, void *data) { ns_nameserver_t *ns = (ns_nameserver_t *)data; - debug_server("Event: reconfiguring name server.\n"); + debug_ns("Event: reconfiguring name server.\n"); dnslib_zonedb_t *old_db = 0; @@ -1938,6 +1952,8 @@ int ns_conf_hook(const struct conf_t *conf, void *data) // Wait until all readers finish with reading the zones. synchronize_rcu(); + debug_ns("Nameserver's zone db: %p, old db: %p\n", ns->zone_db, old_db); + // Delete all deprecated zones and delete the old database. dnslib_zonedb_deep_free(&old_db); diff --git a/src/knot/server/name-server.h b/src/knot/server/name-server.h index bd67adf0bfef1a70b7bc4309a87847331b37d668..8fc348126e355fe6aeabb75c74671b1d5890d41f 100644 --- a/src/knot/server/name-server.h +++ b/src/knot/server/name-server.h @@ -55,7 +55,7 @@ typedef struct ns_nameserver { * * \return Pointer to the name server structure. */ -ns_nameserver_t *ns_create(dnslib_zonedb_t *database); +ns_nameserver_t *ns_create(); /*! * \brief Creates a response for the given query using the data of the name diff --git a/src/knot/server/server.c b/src/knot/server/server.c index 595a5e1399f36b734fb4efcbe5e94e7af4e5b9a0..e98584f7112bec5025dd78177e757e76e7b50672 100644 --- a/src/knot/server/server.c +++ b/src/knot/server/server.c @@ -328,20 +328,10 @@ server_t *server_create() server->ifaces = malloc(sizeof(list)); init_list(server->ifaces); - // Create zone database structure - debug_server("Creating Zone Database structure...\n"); - server->zone_db = dnslib_zonedb_new(); - if (server->zone_db == NULL) { - ERR_ALLOC_FAILED; - free(server); - return NULL; - } - // Create name server debug_server("Creating Name Server structure...\n"); - server->nameserver = ns_create(server->zone_db); + server->nameserver = ns_create(); if (server->nameserver == NULL) { - dnslib_zonedb_deep_free(&server->zone_db); free(server); return NULL; } @@ -634,7 +624,7 @@ void server_destroy(server_t **server) stat_static_gath_free(); ns_destroy(&(*server)->nameserver); - dnslib_zonedb_deep_free(&(*server)->zone_db); + free(*server); EVP_cleanup(); diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index f7c55ae6f5c2f404556e89dd33b5a46853a200fb..3c25c66b1f21221e5eba40262d08a8c218de6f43 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -167,9 +167,15 @@ int zones_update_db_from_config(const conf_t *conf, ns_nameserver_t *ns, return ret; } + debug_zones("Old db in nameserver: %p, old db stored: %p, new db: %p\n", + ns->zone_db, *db_old, db_new); + // Switch the databases. (void)rcu_xchg_pointer(&ns->zone_db, db_new); + debug_zones("db in nameserver: %p, old db stored: %p, new db: %p\n", + ns->zone_db, *db_old, db_new); + /* * Remove all zones present in the new DB from the old DB. * No new thread can access these zones in the old DB, as the