static void xfrd_free_namedb() { namedb_close(xfrd->nsd->db); xfrd->nsd->db = 0; }
struct namedb * namedb_open (const char *filename, nsd_options_t* opt, size_t num_children) { namedb_type *db; /* * Temporary region used while loading domain names from the * database. The region is freed after each time a dname is * read from the database. */ region_type *dname_region; /* * Temporary region used to store array of domains and zones * while loading the database. The region is freed before * returning. */ region_type *temp_region; uint32_t dname_count; domain_type **domains; /* Indexed by domain number. */ uint32_t zone_count; zone_type **zones; /* Indexed by zone number. */ uint32_t i; uint32_t rrset_count = 0; uint32_t rr_count = 0; rrset_type *rrset; DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(namedb_type) = %lu\n", (unsigned long) sizeof(namedb_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(zone_type) = %lu\n", (unsigned long) sizeof(zone_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(domain_type) = %lu\n", (unsigned long) sizeof(domain_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rrset_type) = %lu\n", (unsigned long) sizeof(rrset_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rr_type) = %lu\n", (unsigned long) sizeof(rr_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rdata_atom_type) = %lu\n", (unsigned long) sizeof(rdata_atom_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rbnode_t) = %lu\n", (unsigned long) sizeof(rbnode_t))); if ((db = namedb_create()) == NULL) { log_msg(LOG_ERR, "insufficient memory to create database"); return NULL; } db->filename = region_strdup(db->region, filename); if (gettimeofday(&(db->diff_timestamp), NULL) != 0) { log_msg(LOG_ERR, "unable to load %s: cannot initialize" "timestamp", db->filename); namedb_destroy(db); return NULL; } /* Open it... */ db->fd = fopen(db->filename, "r"); if (db->fd == NULL) { log_msg(LOG_ERR, "unable to load %s: %s", db->filename, strerror(errno)); namedb_destroy(db); return NULL; } if (!read_magic(db)) { log_msg(LOG_ERR, "corrupted database (read magic): %s", db->filename); log_msg(LOG_ERR, "cannot load database, incompatible version " "number. Please rebuild database and " "start again."); namedb_close(db); return NULL; } if (!read_size(db, &zone_count)) { log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename); namedb_close(db); return NULL; } DEBUG(DEBUG_DBACCESS, 1, (LOG_INFO, "Retrieving %lu zones\n", (unsigned long) zone_count)); temp_region = region_create(xalloc, free); dname_region = region_create(xalloc, free); db->zone_count = zone_count; zones = (zone_type **) region_alloc(temp_region, zone_count * sizeof(zone_type *)); for (i = 0; i < zone_count; ++i) { const dname_type *dname = read_dname(db->fd, dname_region); if (!dname) { log_msg(LOG_ERR, "corrupted database (read dname): %s", db->filename); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } zones[i] = (zone_type *) region_alloc(db->region, sizeof(zone_type)); zones[i]->next = db->zones; db->zones = zones[i]; zones[i]->apex = domain_table_insert(db->domains, dname); zones[i]->soa_rrset = NULL; zones[i]->soa_nx_rrset = NULL; zones[i]->ns_rrset = NULL; #ifdef NSEC3 zones[i]->nsec3_soa_rr = NULL; zones[i]->nsec3_last = NULL; #endif zones[i]->opts = zone_options_find(opt, domain_dname(zones[i]->apex)); zones[i]->number = i + 1; zones[i]->is_secure = 0; zones[i]->updated = 1; zones[i]->is_ok = 0; zones[i]->dirty = region_alloc(db->region, sizeof(uint8_t)*num_children); memset(zones[i]->dirty, 0, sizeof(uint8_t)*num_children); if(!zones[i]->opts) { log_msg(LOG_ERR, "cannot load database. Zone %s in db " "%s, but not in config file (might " "happen if you edited the config " "file). Please rebuild database and " "start again.", dname_to_string(dname, NULL), db->filename); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } #ifdef NSEC3 #ifndef FULL_PREHASH zones[i]->nsec3_domains = NULL; if (0 != zone_nsec3_domains_create(db, zones[i])) { log_msg(LOG_ERR, "insufficient memory for NSEC3 tree, " "unable to read database"); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ region_free_all(dname_region); } if (!read_size(db, &dname_count)) { log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } DEBUG(DEBUG_DBACCESS, 1, (LOG_INFO, "Retrieving %lu domain names\n", (unsigned long) dname_count)); domains = (domain_type **) region_alloc( temp_region, dname_count * sizeof(domain_type *)); for (i = 0; i < dname_count; ++i) { const dname_type *dname = read_dname(db->fd, dname_region); if (!dname) { log_msg(LOG_ERR, "corrupted database (read dname): %s", db->filename); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } domains[i] = domain_table_insert(db->domains, dname); region_free_all(dname_region); } region_destroy(dname_region); #ifndef NDEBUG fprintf(stderr, "database region after loading domain names: "); region_dump_stats(db->region, stderr); fprintf(stderr, "\n"); #endif while ((rrset = read_rrset(db, dname_count, domains, zone_count, zones))) { ++rrset_count; rr_count += rrset->rr_count; } DEBUG(DEBUG_DBACCESS, 1, (LOG_INFO, "Retrieved %lu RRs in %lu RRsets\n", (unsigned long) rr_count, (unsigned long) rrset_count)); region_destroy(temp_region); if ((db->crc_pos = ftello(db->fd)) == -1) { log_msg(LOG_ERR, "ftello %s failed: %s", db->filename, strerror(errno)); namedb_close(db); return NULL; } if (!read_size(db, &db->crc)) { log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename); namedb_close(db); return NULL; } if (!read_magic(db)) { log_msg(LOG_ERR, "corrupted database (read magic): %s", db->filename); log_msg(LOG_ERR, "cannot load database, incompatible version " "number. Please rebuild database and " "start again."); namedb_close(db); return NULL; } fclose(db->fd); db->fd = NULL; #ifndef NDEBUG fprintf(stderr, "database region after loading database: "); region_dump_stats(db->region, stderr); fprintf(stderr, "\n"); #endif return db; }