/*
* dbaccess.c -- access methods for nsd(8) database
*
* Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
void
namedb_zone_delete(namedb_type* db, zone_type* zone)
{
/* RRs and UDB and NSEC3 and so on must be already deleted */
radix_delete(db->zonetree, zone->node);
/* see if apex can be deleted */
if(zone->apex) {
zone->apex->usage --;
zone->apex->is_apex = 0;
if(zone->apex->usage == 0) {
/* delete the apex, possibly */
domain_table_deldomain(db, zone->apex);
}
}
/* soa_rrset is freed when the SOA was deleted */
if(zone->soa_nx_rrset) {
region_recycle(db->region, zone->soa_nx_rrset->rrs,
sizeof(rr_type));
region_recycle(db->region, zone->soa_nx_rrset,
sizeof(rrset_type));
}
#ifdef NSEC3
hash_tree_delete(db->region, zone->nsec3tree);
hash_tree_delete(db->region, zone->hashtree);
hash_tree_delete(db->region, zone->wchashtree);
hash_tree_delete(db->region, zone->dshashtree);
#endif
zone_ixfr_free(zone->ixfr);
if(zone->filename)
region_recycle(db->region, zone->filename,
strlen(zone->filename)+1);
if(zone->logstr)
region_recycle(db->region, zone->logstr,
strlen(zone->logstr)+1);
region_recycle(db->region, zone, sizeof(zone_type));
}
void
namedb_read_zonefile(struct nsd* nsd, struct zone* zone, udb_base* taskudb,
udb_ptr* last_task)
{
struct timespec mtime;
int nonexist = 0;
unsigned int errors;
const char* fname;
struct ixfr_create* ixfrcr = NULL;
int ixfr_create_already_done = 0;
if(!nsd->db || !zone || !zone->opts || !zone->opts->pattern->zonefile)
return;
mtime.tv_sec = 0;
mtime.tv_nsec = 0;
fname = config_make_zonefile(zone->opts, nsd);
assert(fname);
if(!file_get_mtime(fname, &mtime, &nonexist)) {
if(nonexist) {
if(zone_is_slave(zone->opts)) {
/* for slave zones not as bad, no zonefile
* may just mean we have to transfer it */
VERBOSITY(2, (LOG_INFO, "zonefile %s does not exist",
fname));
} else {
/* without a download option, we can never
* serve data, more severe error printout */
log_msg(LOG_ERR, "zonefile %s does not exist", fname);
}
} else
log_msg(LOG_ERR, "zonefile %s: %s",
fname, strerror(errno));
if(taskudb) task_new_soainfo(taskudb, last_task, zone, 0);
return;
} else {
const char* zone_fname = zone->filename;
struct timespec zone_mtime = zone->mtime;
/* if no zone_fname, then it was acquired in zone transfer,
* see if the file is newer than the zone transfer
* (regardless if this is a different file), because the
* zone transfer is a different content source too */
if(!zone_fname && timespec_compare(&zone_mtime, &mtime) >= 0) {
VERBOSITY(3, (LOG_INFO, "zonefile %s is older than "
"zone transfer in memory", fname));
return;
/* if zone_fname, then the file was acquired from reading it,
* and see if filename changed or mtime newer to read it */
} else if(zone_fname && strcmp(zone_fname, fname) == 0 &&
timespec_compare(&zone_mtime, &mtime) == 0) {
VERBOSITY(3, (LOG_INFO, "zonefile %s is not modified",
fname));
return;
}
}
if(ixfr_create_from_difference(zone, fname,
&ixfr_create_already_done)) {
ixfrcr = ixfr_create_start(zone, fname,
zone->opts->pattern->ixfr_size, 0);
if(!ixfrcr) {
/* leaves the ixfrcr at NULL, so it is not created */
log_msg(LOG_ERR, "out of memory starting ixfr create");
}
}