Esempio n. 1
0
/** list zone contents */
static void
list_zone_contents(udb_base* udb, udb_ptr* zone)
{
	udb_ptr dtree;
	udb_ptr_new(&dtree, udb, &ZONE(zone)->domains);
	if(v) {
		time_t t = (time_t)ZONE(zone)->mtime;
		uint32_t serial;
		printf("# %llu domains, %llu RRsets, %llu RRs%s, ",
			ULL RADTREE(&dtree)->count,
			ULL ZONE(zone)->rrset_count,
			ULL ZONE(zone)->rr_count,
			ZONE(zone)->expired?", is_expired":"");
		if(udb_zone_get_serial(udb, zone, &serial)) {
			printf("%u, ", (unsigned)serial);
		}
		printf("%s", ctime(&t));
		if(ZONE(zone)->nsec3param.data) {
			udb_ptr n3;
			udb_ptr_new(&n3, udb, &ZONE(zone)->nsec3param);
#ifdef NSEC3
			printf("# nsec3param %s\n", udb_nsec3param_string(&n3));
#else
			printf("# nsec3param ");
			print_udb_rr(ZONE(zone)->name, &n3);
#endif
			udb_ptr_unlink(&n3, udb);
		}
	}
	if(v >= 2) {
		list_domains(udb, &dtree);
	}
	udb_ptr_unlink(&dtree, udb);
}
Esempio n. 2
0
/** list domain RRs */
static void
list_domains(udb_base* udb, udb_ptr* dtree)
{
	udb_ptr d;
	for(udb_radix_first(udb,dtree,&d); d.data; udb_radix_next(udb,&d)) {
		udb_ptr domain;
		udb_ptr_new(&domain, udb, &RADNODE(&d)->elem);
		list_rrsets(udb, &domain);
		udb_ptr_unlink(&domain, udb);
	}
	udb_ptr_unlink(&d, udb);
}
Esempio n. 3
0
/** list zones in zone tree */
static void
list_zones(udb_base* udb, udb_ptr* ztree)
{
	udb_ptr z;
	for(udb_radix_first(udb,ztree,&z); z.data; udb_radix_next(udb,&z)) {
		udb_ptr zone;
		udb_ptr_new(&zone, udb, &RADNODE(&z)->elem);
		printf("zone: name: \"");
		print_dname(ZONE(&zone)->name, ZONE(&zone)->namelen);
		printf("\"\n");
		if(v) list_zone_contents(udb, &zone);
		udb_ptr_unlink(&zone, udb);
	}
	udb_ptr_unlink(&z, udb);
}
Esempio n. 4
0
/** create and write a zone */
int
write_zone_to_udb(udb_base* udb, zone_type* zone, struct timespec* mtime,
	const char* file_str)
{
	udb_ptr z;
	/* make udb dirty */
	udb_base_set_userflags(udb, 1);
	/* find or create zone */
	if(udb_zone_search(udb, &z, dname_name(domain_dname(zone->apex)),
		domain_dname(zone->apex)->name_size)) {
		/* wipe existing contents */
		udb_zone_clear(udb, &z);
	} else {
		if(!udb_zone_create(udb, &z, dname_name(domain_dname(
			zone->apex)), domain_dname(zone->apex)->name_size)) {
			udb_base_set_userflags(udb, 0);
			return 0;
		}
	}
	/* set mtime */
	ZONE(&z)->mtime = (uint64_t)mtime->tv_sec;
	ZONE(&z)->mtime_nsec = (uint64_t)mtime->tv_nsec;
	ZONE(&z)->is_changed = 0;
	udb_zone_set_log_str(udb, &z, NULL);
	udb_zone_set_file_str(udb, &z, file_str);
	/* write zone */
	if(!write_zone(udb, &z, zone)) {
		udb_base_set_userflags(udb, 0);
		return 0;
	}
	udb_ptr_unlink(&z, udb);
	udb_base_set_userflags(udb, 0);
	return 1;
}
Esempio n. 5
0
/** list contents of NSD.DB file */
static void
list_file(char* fname)
{
	udb_base* udb;
	udb_ptr ztree;
	log_init("udb-inspect");
	udb = udb_base_create_read(fname, &namedb_walkfunc, NULL);
	if(!udb) { printf("cannot open udb %s\n", fname); exit(1); }
	udb_ptr_new(&ztree, udb, udb_base_get_userdata(udb));
	if(udb_ptr_is_null(&ztree)) {
		printf("file is not inited\n");
		exit(1);
	}
	/* print header info */
	printf("%s: %llu zones, %llu bytes\n", fname,
		ULL RADTREE(&ztree)->count,
		ULL udb->alloc->disk->nextgrow);
	if(udb_base_get_userflags(udb)) {
		printf("file is corrupted! (%u)\n",
			(unsigned)udb_base_get_userflags(udb));
	}
	/* print detail info */
	list_zones(udb, &ztree);
	udb_ptr_unlink(&ztree, udb);
	udb_base_free(udb);
}
Esempio n. 6
0
/** list RRsets */
static void
list_rrsets(udb_base* udb, udb_ptr* domain)
{
	udb_ptr rrset;
	udb_ptr_new(&rrset, udb, &DOMAIN(domain)->rrsets);
	while(rrset.data) {
		list_rrs(udb, &rrset, domain);
		udb_ptr_set_rptr(&rrset, udb, &RRSET(&rrset)->next);
	}
	udb_ptr_unlink(&rrset, udb);
}
Esempio n. 7
0
/** list rrs */
static void
list_rrs(udb_base* udb, udb_ptr* rrset, udb_ptr* domain)
{
	udb_ptr rr;
	udb_ptr_new(&rr, udb, &RRSET(rrset)->rrs);
	while(rr.data) {
		print_udb_rr(DOMAIN(domain)->name, &rr);
		udb_ptr_set_rptr(&rr, udb, &RR(&rr)->next);
	}
	udb_ptr_unlink(&rr, udb);
}
Esempio n. 8
0
/** find soa serial (if any) */
static int
udb_zone_get_serial(udb_base* udb, udb_ptr* zone, uint32_t* serial)
{
	udb_ptr domain, rrset, rr;
	buffer_type buffer;
	if(!udb_domain_find(udb, zone, ZONE(zone)->name, ZONE(zone)->namelen,
		&domain))
		return 0;
	if(!udb_rrset_find(udb, &domain, TYPE_SOA, &rrset)) {
		udb_ptr_unlink(&domain, udb);
		return 0;
	}
	/* got SOA rrset, use first RR */
	if(!RRSET(&rrset)->rrs.data) {
		udb_ptr_unlink(&domain, udb);
		udb_ptr_unlink(&rrset, udb);
		return 0;
	}
	udb_ptr_new(&rr, udb, &RRSET(&rrset)->rrs);
	udb_ptr_unlink(&domain, udb);
	udb_ptr_unlink(&rrset, udb);
	/* find serial */
	buffer_create_from(&buffer, RR(&rr)->wire, RR(&rr)->len);
	/* skip two dnames */
	if(!packet_skip_dname(&buffer) || !packet_skip_dname(&buffer)) {
		udb_ptr_unlink(&rr, udb);
		return 0;
	}
	if(!buffer_available(&buffer, 4*5)) { /* soa rdata u32s */
		udb_ptr_unlink(&rr, udb);
		return 0;
	}
	*serial = buffer_read_u32(&buffer);
	udb_ptr_unlink(&rr, udb);
	return 1;
}
Esempio n. 9
0
void
namedb_write_zonefile(struct nsd* nsd, struct zone_options* zopt)
{
	const char* zfile;
	int notexist = 0;
	zone_type* zone;
	/* if no zone exists, it has no contents or it has no zonefile
	 * configured, then no need to write data to disk */
	if(!zopt->pattern->zonefile)
		return;
	zone = namedb_find_zone(nsd->db, (const dname_type*)zopt->node.key);
	if(!zone || !zone->apex || !zone->soa_rrset)
		return;
	/* write if file does not exist, or if changed */
	/* so, determine filename, create directory components, check exist*/
	zfile = config_make_zonefile(zopt, nsd);
	if(!create_path_components(zfile, &notexist)) {
		log_msg(LOG_ERR, "could not write zone %s to file %s because "
			"the path could not be created", zopt->name, zfile);
		return;
	}

	/* if not changed, do not write. */
	if(notexist || zone->is_changed) {
		char logs[4096];
		char bakfile[4096];
		struct timespec mtime;
		udb_ptr zudb;
		if(nsd->db->udb) {
			if(!udb_zone_search(nsd->db->udb, &zudb,
				dname_name(domain_dname(zone->apex)),
				domain_dname(zone->apex)->name_size))
				return; /* zone does not exist in db */
		}
		/* write to zfile~ first, then rename if that works */
		snprintf(bakfile, sizeof(bakfile), "%s~", zfile);
		if(nsd->db->udb && ZONE(&zudb)->log_str.data) {
			udb_ptr s;
			udb_ptr_new(&s, nsd->db->udb, &ZONE(&zudb)->log_str);
			strlcpy(logs, (char*)udb_ptr_data(&s), sizeof(logs));
			udb_ptr_unlink(&s, nsd->db->udb);
		} else if(zone->logstr) {
			strlcpy(logs, zone->logstr, sizeof(logs));
		} else logs[0] = 0;
		VERBOSITY(1, (LOG_INFO, "writing zone %s to file %s",
			zone->opts->name, zfile));
		if(!write_to_zonefile(zone, bakfile, logs)) {
			if(nsd->db->udb)
				udb_ptr_unlink(&zudb, nsd->db->udb);
			(void)unlink(bakfile); /* delete failed file */
			return; /* error already printed */
		}
		if(rename(bakfile, zfile) == -1) {
			log_msg(LOG_ERR, "rename(%s to %s) failed: %s",
				bakfile, zfile, strerror(errno));
			if(nsd->db->udb)
				udb_ptr_unlink(&zudb, nsd->db->udb);
			(void)unlink(bakfile); /* delete failed file */
			return;
		}
		zone->is_changed = 0;
		/* fetch the mtime of the just created zonefile so we
		 * do not waste effort reading it back in */
		if(!file_get_mtime(zfile, &mtime, &notexist)) {
			get_time(&mtime);
		}
		if(nsd->db->udb) {
			ZONE(&zudb)->mtime = (uint64_t)mtime.tv_sec;
			ZONE(&zudb)->mtime_nsec = (uint64_t)mtime.tv_nsec;
			ZONE(&zudb)->is_changed = 0;
			udb_zone_set_log_str(nsd->db->udb, &zudb, NULL);
			udb_ptr_unlink(&zudb, nsd->db->udb);
		} else {
			zone->mtime = mtime;
			if(zone->filename)
				region_recycle(nsd->db->region, zone->filename,
					strlen(zone->filename)+1);
			zone->filename = region_strdup(nsd->db->region, zfile);
			if(zone->logstr)
				region_recycle(nsd->db->region, zone->logstr,
					strlen(zone->logstr)+1);
			zone->logstr = NULL;
		}
	}
}