xref: /freebsd/contrib/ldns/zone.c (revision 5afab0e5)
17b5038d7SDag-Erling Smørgrav /* zone.c
27b5038d7SDag-Erling Smørgrav  *
37b5038d7SDag-Erling Smørgrav  * Functions for ldns_zone structure
47b5038d7SDag-Erling Smørgrav  * a Net::DNS like library for C
57b5038d7SDag-Erling Smørgrav  *
67b5038d7SDag-Erling Smørgrav  * (c) NLnet Labs, 2005-2006
77b5038d7SDag-Erling Smørgrav  * See the file LICENSE for the license
87b5038d7SDag-Erling Smørgrav  */
97b5038d7SDag-Erling Smørgrav #include <ldns/config.h>
107b5038d7SDag-Erling Smørgrav 
117b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
125afab0e5SDag-Erling Smørgrav #include <ldns/internal.h>
137b5038d7SDag-Erling Smørgrav 
147b5038d7SDag-Erling Smørgrav #include <strings.h>
157b5038d7SDag-Erling Smørgrav #include <limits.h>
167b5038d7SDag-Erling Smørgrav 
177b5038d7SDag-Erling Smørgrav ldns_rr *
ldns_zone_soa(const ldns_zone * z)187b5038d7SDag-Erling Smørgrav ldns_zone_soa(const ldns_zone *z)
197b5038d7SDag-Erling Smørgrav {
207b5038d7SDag-Erling Smørgrav         return z->_soa;
217b5038d7SDag-Erling Smørgrav }
227b5038d7SDag-Erling Smørgrav 
237b5038d7SDag-Erling Smørgrav size_t
ldns_zone_rr_count(const ldns_zone * z)247b5038d7SDag-Erling Smørgrav ldns_zone_rr_count(const ldns_zone *z)
257b5038d7SDag-Erling Smørgrav {
267b5038d7SDag-Erling Smørgrav 	return ldns_rr_list_rr_count(z->_rrs);
277b5038d7SDag-Erling Smørgrav }
287b5038d7SDag-Erling Smørgrav 
297b5038d7SDag-Erling Smørgrav void
ldns_zone_set_soa(ldns_zone * z,ldns_rr * soa)307b5038d7SDag-Erling Smørgrav ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa)
317b5038d7SDag-Erling Smørgrav {
327b5038d7SDag-Erling Smørgrav 	z->_soa = soa;
337b5038d7SDag-Erling Smørgrav }
347b5038d7SDag-Erling Smørgrav 
357b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_zone_rrs(const ldns_zone * z)367b5038d7SDag-Erling Smørgrav ldns_zone_rrs(const ldns_zone *z)
377b5038d7SDag-Erling Smørgrav {
387b5038d7SDag-Erling Smørgrav 	return z->_rrs;
397b5038d7SDag-Erling Smørgrav }
407b5038d7SDag-Erling Smørgrav 
417b5038d7SDag-Erling Smørgrav void
ldns_zone_set_rrs(ldns_zone * z,ldns_rr_list * rrlist)427b5038d7SDag-Erling Smørgrav ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist)
437b5038d7SDag-Erling Smørgrav {
447b5038d7SDag-Erling Smørgrav 	z->_rrs = rrlist;
457b5038d7SDag-Erling Smørgrav }
467b5038d7SDag-Erling Smørgrav 
477b5038d7SDag-Erling Smørgrav bool
ldns_zone_push_rr_list(ldns_zone * z,const ldns_rr_list * list)48986ba33cSDag-Erling Smørgrav ldns_zone_push_rr_list(ldns_zone *z, const ldns_rr_list *list)
497b5038d7SDag-Erling Smørgrav {
507b5038d7SDag-Erling Smørgrav 	return ldns_rr_list_cat(ldns_zone_rrs(z), list);
517b5038d7SDag-Erling Smørgrav }
527b5038d7SDag-Erling Smørgrav 
537b5038d7SDag-Erling Smørgrav bool
ldns_zone_push_rr(ldns_zone * z,ldns_rr * rr)547b5038d7SDag-Erling Smørgrav ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
557b5038d7SDag-Erling Smørgrav {
567b5038d7SDag-Erling Smørgrav 	return ldns_rr_list_push_rr(ldns_zone_rrs(z), rr);
577b5038d7SDag-Erling Smørgrav }
587b5038d7SDag-Erling Smørgrav 
597b5038d7SDag-Erling Smørgrav 
607b5038d7SDag-Erling Smørgrav /*
617b5038d7SDag-Erling Smørgrav  * Get the list of glue records in a zone
627b5038d7SDag-Erling Smørgrav  * XXX: there should be a way for this to return error, other than NULL,
637b5038d7SDag-Erling Smørgrav  *      since NULL is a valid return
647b5038d7SDag-Erling Smørgrav  */
657b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_zone_glue_rr_list(const ldns_zone * z)667b5038d7SDag-Erling Smørgrav ldns_zone_glue_rr_list(const ldns_zone *z)
677b5038d7SDag-Erling Smørgrav {
687b5038d7SDag-Erling Smørgrav 	/* when do we find glue? It means we find an IP address
697b5038d7SDag-Erling Smørgrav 	 * (AAAA/A) for a nameserver listed in the zone
707b5038d7SDag-Erling Smørgrav 	 *
717b5038d7SDag-Erling Smørgrav 	 * Alg used here:
727b5038d7SDag-Erling Smørgrav 	 * first find all the zonecuts (NS records)
737b5038d7SDag-Erling Smørgrav 	 * find all the AAAA or A records (can be done it the
747b5038d7SDag-Erling Smørgrav 	 * above loop).
757b5038d7SDag-Erling Smørgrav 	 *
767b5038d7SDag-Erling Smørgrav 	 * Check if the aaaa/a list are subdomains under the
777b5038d7SDag-Erling Smørgrav 	 * NS domains.
787b5038d7SDag-Erling Smørgrav 	 * If yes -> glue, if no -> not glue
797b5038d7SDag-Erling Smørgrav 	 */
807b5038d7SDag-Erling Smørgrav 
817b5038d7SDag-Erling Smørgrav 	ldns_rr_list *zone_cuts;
827b5038d7SDag-Erling Smørgrav 	ldns_rr_list *addr;
837b5038d7SDag-Erling Smørgrav 	ldns_rr_list *glue;
847b5038d7SDag-Erling Smørgrav 	ldns_rr *r, *ns, *a;
857b5038d7SDag-Erling Smørgrav 	ldns_rdf *dname_a, *ns_owner;
867b5038d7SDag-Erling Smørgrav 	size_t i,j;
877b5038d7SDag-Erling Smørgrav 
887b5038d7SDag-Erling Smørgrav 	zone_cuts = NULL;
897b5038d7SDag-Erling Smørgrav 	addr = NULL;
907b5038d7SDag-Erling Smørgrav 	glue = NULL;
917b5038d7SDag-Erling Smørgrav 
927b5038d7SDag-Erling Smørgrav 	/* we cannot determine glue in a 'zone' without a SOA */
937b5038d7SDag-Erling Smørgrav 	if (!ldns_zone_soa(z)) {
947b5038d7SDag-Erling Smørgrav 		return NULL;
957b5038d7SDag-Erling Smørgrav 	}
967b5038d7SDag-Erling Smørgrav 
977b5038d7SDag-Erling Smørgrav 	zone_cuts = ldns_rr_list_new();
987b5038d7SDag-Erling Smørgrav 	if (!zone_cuts) goto memory_error;
997b5038d7SDag-Erling Smørgrav 	addr = ldns_rr_list_new();
1007b5038d7SDag-Erling Smørgrav 	if (!addr) goto memory_error;
1017b5038d7SDag-Erling Smørgrav 	glue = ldns_rr_list_new();
1027b5038d7SDag-Erling Smørgrav 	if (!glue) goto memory_error;
1037b5038d7SDag-Erling Smørgrav 
1047b5038d7SDag-Erling Smørgrav 	for(i = 0; i < ldns_zone_rr_count(z); i++) {
1057b5038d7SDag-Erling Smørgrav 		r = ldns_rr_list_rr(ldns_zone_rrs(z), i);
1067b5038d7SDag-Erling Smørgrav 		if (ldns_rr_get_type(r) == LDNS_RR_TYPE_A ||
1077b5038d7SDag-Erling Smørgrav 				ldns_rr_get_type(r) == LDNS_RR_TYPE_AAAA) {
1087b5038d7SDag-Erling Smørgrav 			/* possibly glue */
1097b5038d7SDag-Erling Smørgrav 			if (!ldns_rr_list_push_rr(addr, r)) goto memory_error;
1107b5038d7SDag-Erling Smørgrav 			continue;
1117b5038d7SDag-Erling Smørgrav 		}
1127b5038d7SDag-Erling Smørgrav 		if (ldns_rr_get_type(r) == LDNS_RR_TYPE_NS) {
1137b5038d7SDag-Erling Smørgrav 			/* multiple zones will end up here -
1147b5038d7SDag-Erling Smørgrav 			 * for now; not a problem
1157b5038d7SDag-Erling Smørgrav 			 */
1167b5038d7SDag-Erling Smørgrav 			/* don't add NS records for the current zone itself */
1177b5038d7SDag-Erling Smørgrav 			if (ldns_rdf_compare(ldns_rr_owner(r),
1187b5038d7SDag-Erling Smørgrav 						ldns_rr_owner(ldns_zone_soa(z))) != 0) {
1197b5038d7SDag-Erling Smørgrav 				if (!ldns_rr_list_push_rr(zone_cuts, r)) goto memory_error;
1207b5038d7SDag-Erling Smørgrav 			}
1217b5038d7SDag-Erling Smørgrav 			continue;
1227b5038d7SDag-Erling Smørgrav 		}
1237b5038d7SDag-Erling Smørgrav 	}
1247b5038d7SDag-Erling Smørgrav 
1257b5038d7SDag-Erling Smørgrav 	/* will sorting make it quicker ?? */
1267b5038d7SDag-Erling Smørgrav 	for(i = 0; i < ldns_rr_list_rr_count(zone_cuts); i++) {
1277b5038d7SDag-Erling Smørgrav 		ns = ldns_rr_list_rr(zone_cuts, i);
1287b5038d7SDag-Erling Smørgrav 		ns_owner = ldns_rr_owner(ns);
1297b5038d7SDag-Erling Smørgrav 
1307b5038d7SDag-Erling Smørgrav 		for(j = 0; j < ldns_rr_list_rr_count(addr); j++) {
1317b5038d7SDag-Erling Smørgrav 			a = ldns_rr_list_rr(addr, j);
1327b5038d7SDag-Erling Smørgrav 			dname_a = ldns_rr_owner(a);
1337b5038d7SDag-Erling Smørgrav 
1347b5038d7SDag-Erling Smørgrav 			if (ldns_dname_is_subdomain(dname_a, ns_owner) ||
1357b5038d7SDag-Erling Smørgrav 				ldns_dname_compare(dname_a, ns_owner) == 0) {
1367b5038d7SDag-Erling Smørgrav 				/* GLUE! */
1377b5038d7SDag-Erling Smørgrav 				if (!ldns_rr_list_push_rr(glue, a)) goto memory_error;
1387b5038d7SDag-Erling Smørgrav 			}
1397b5038d7SDag-Erling Smørgrav 		}
1407b5038d7SDag-Erling Smørgrav 	}
1417b5038d7SDag-Erling Smørgrav 
1427b5038d7SDag-Erling Smørgrav 	ldns_rr_list_free(addr);
1437b5038d7SDag-Erling Smørgrav 	ldns_rr_list_free(zone_cuts);
1447b5038d7SDag-Erling Smørgrav 
1457b5038d7SDag-Erling Smørgrav 	if (ldns_rr_list_rr_count(glue) == 0) {
1467b5038d7SDag-Erling Smørgrav 		ldns_rr_list_free(glue);
1477b5038d7SDag-Erling Smørgrav 		return NULL;
1487b5038d7SDag-Erling Smørgrav 	} else {
1497b5038d7SDag-Erling Smørgrav 		return glue;
1507b5038d7SDag-Erling Smørgrav 	}
1517b5038d7SDag-Erling Smørgrav 
1527b5038d7SDag-Erling Smørgrav memory_error:
1537b5038d7SDag-Erling Smørgrav 	if (zone_cuts) {
1547b5038d7SDag-Erling Smørgrav 		LDNS_FREE(zone_cuts);
1557b5038d7SDag-Erling Smørgrav 	}
1567b5038d7SDag-Erling Smørgrav 	if (addr) {
1577b5038d7SDag-Erling Smørgrav 		ldns_rr_list_free(addr);
1587b5038d7SDag-Erling Smørgrav 	}
1597b5038d7SDag-Erling Smørgrav 	if (glue) {
1607b5038d7SDag-Erling Smørgrav 		ldns_rr_list_free(glue);
1617b5038d7SDag-Erling Smørgrav 	}
1627b5038d7SDag-Erling Smørgrav 	return NULL;
1637b5038d7SDag-Erling Smørgrav }
1647b5038d7SDag-Erling Smørgrav 
1657b5038d7SDag-Erling Smørgrav ldns_zone *
ldns_zone_new(void)1667b5038d7SDag-Erling Smørgrav ldns_zone_new(void)
1677b5038d7SDag-Erling Smørgrav {
1687b5038d7SDag-Erling Smørgrav 	ldns_zone *z;
1697b5038d7SDag-Erling Smørgrav 
1707b5038d7SDag-Erling Smørgrav 	z = LDNS_MALLOC(ldns_zone);
1717b5038d7SDag-Erling Smørgrav 	if (!z) {
1727b5038d7SDag-Erling Smørgrav 		return NULL;
1737b5038d7SDag-Erling Smørgrav 	}
1747b5038d7SDag-Erling Smørgrav 
1757b5038d7SDag-Erling Smørgrav 	z->_rrs = ldns_rr_list_new();
1767b5038d7SDag-Erling Smørgrav 	if (!z->_rrs) {
1777b5038d7SDag-Erling Smørgrav 		LDNS_FREE(z);
1787b5038d7SDag-Erling Smørgrav 		return NULL;
1797b5038d7SDag-Erling Smørgrav 	}
1807b5038d7SDag-Erling Smørgrav 	ldns_zone_set_soa(z, NULL);
1817b5038d7SDag-Erling Smørgrav 	return z;
1827b5038d7SDag-Erling Smørgrav }
1837b5038d7SDag-Erling Smørgrav 
1845afab0e5SDag-Erling Smørgrav /* we recognize:
1857b5038d7SDag-Erling Smørgrav  * $TTL, $ORIGIN
1867b5038d7SDag-Erling Smørgrav  */
1877b5038d7SDag-Erling Smørgrav ldns_status
ldns_zone_new_frm_fp(ldns_zone ** z,FILE * fp,const ldns_rdf * origin,uint32_t ttl,ldns_rr_class c)188986ba33cSDag-Erling Smørgrav ldns_zone_new_frm_fp(ldns_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c)
1897b5038d7SDag-Erling Smørgrav {
1907b5038d7SDag-Erling Smørgrav 	return ldns_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
1917b5038d7SDag-Erling Smørgrav }
1927b5038d7SDag-Erling Smørgrav 
1937b5038d7SDag-Erling Smørgrav /* XXX: class is never used */
1947b5038d7SDag-Erling Smørgrav ldns_status
ldns_zone_new_frm_fp_l(ldns_zone ** z,FILE * fp,const ldns_rdf * origin,uint32_t default_ttl,ldns_rr_class ATTR_UNUSED (c),int * line_nr)1955afab0e5SDag-Erling Smørgrav ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, const ldns_rdf *origin,
1965afab0e5SDag-Erling Smørgrav 	uint32_t default_ttl, ldns_rr_class ATTR_UNUSED(c), int *line_nr)
1977b5038d7SDag-Erling Smørgrav {
1987b5038d7SDag-Erling Smørgrav 	ldns_zone *newzone;
1995afab0e5SDag-Erling Smørgrav 	ldns_rr *rr, *prev_rr = NULL;
2007b5038d7SDag-Erling Smørgrav 	uint32_t my_ttl;
2017b5038d7SDag-Erling Smørgrav 	ldns_rdf *my_origin;
2027b5038d7SDag-Erling Smørgrav 	ldns_rdf *my_prev;
2037b5038d7SDag-Erling Smørgrav 	bool soa_seen = false; 	/* 2 soa are an error */
2047b5038d7SDag-Erling Smørgrav 	ldns_status s;
2057b5038d7SDag-Erling Smørgrav 	ldns_status ret;
2065afab0e5SDag-Erling Smørgrav 	/* RFC 1035 Section 5.1, says 'Omitted class and TTL values are default
2075afab0e5SDag-Erling Smørgrav 	 * to the last explicitly stated values.'
2085afab0e5SDag-Erling Smørgrav 	 */
2095afab0e5SDag-Erling Smørgrav 	bool ttl_from_TTL = false;
2105afab0e5SDag-Erling Smørgrav 	bool explicit_ttl = false;
2117b5038d7SDag-Erling Smørgrav 
2127b5038d7SDag-Erling Smørgrav 	/* most cases of error are memory problems */
2137b5038d7SDag-Erling Smørgrav 	ret = LDNS_STATUS_MEM_ERR;
2147b5038d7SDag-Erling Smørgrav 
2157b5038d7SDag-Erling Smørgrav 	newzone = NULL;
2167b5038d7SDag-Erling Smørgrav 	my_origin = NULL;
2177b5038d7SDag-Erling Smørgrav 	my_prev = NULL;
2187b5038d7SDag-Erling Smørgrav 
2195afab0e5SDag-Erling Smørgrav 	my_ttl    = default_ttl;
2207b5038d7SDag-Erling Smørgrav 
2217b5038d7SDag-Erling Smørgrav 	if (origin) {
2227b5038d7SDag-Erling Smørgrav 		my_origin = ldns_rdf_clone(origin);
2237b5038d7SDag-Erling Smørgrav 		if (!my_origin) goto error;
2247b5038d7SDag-Erling Smørgrav 		/* also set the prev */
2257b5038d7SDag-Erling Smørgrav 		my_prev   = ldns_rdf_clone(origin);
2267b5038d7SDag-Erling Smørgrav 		if (!my_prev) goto error;
2277b5038d7SDag-Erling Smørgrav 	}
2287b5038d7SDag-Erling Smørgrav 
2297b5038d7SDag-Erling Smørgrav 	newzone = ldns_zone_new();
2307b5038d7SDag-Erling Smørgrav 	if (!newzone) goto error;
2317b5038d7SDag-Erling Smørgrav 
2327b5038d7SDag-Erling Smørgrav 	while(!feof(fp)) {
2335afab0e5SDag-Erling Smørgrav 		/* If ttl came from $TTL line, then it should be the default.
2345afab0e5SDag-Erling Smørgrav 		 * (RFC 2308 Section 4)
2355afab0e5SDag-Erling Smørgrav 		 * Otherwise it "defaults to the last explicitly stated value"
2365afab0e5SDag-Erling Smørgrav 		 * (RFC 1035 Section 5.1)
2375afab0e5SDag-Erling Smørgrav 		 */
2385afab0e5SDag-Erling Smørgrav 		if (ttl_from_TTL)
2395afab0e5SDag-Erling Smørgrav 			my_ttl = default_ttl;
2405afab0e5SDag-Erling Smørgrav 		s = _ldns_rr_new_frm_fp_l_internal(&rr, fp, &my_ttl, &my_origin,
2415afab0e5SDag-Erling Smørgrav 				&my_prev, line_nr, &explicit_ttl);
2427b5038d7SDag-Erling Smørgrav 		switch (s) {
2437b5038d7SDag-Erling Smørgrav 		case LDNS_STATUS_OK:
2445afab0e5SDag-Erling Smørgrav 			if (explicit_ttl) {
2455afab0e5SDag-Erling Smørgrav 				if (!ttl_from_TTL) {
2465afab0e5SDag-Erling Smørgrav 					/* No $TTL, so ttl "defaults to the
2475afab0e5SDag-Erling Smørgrav 					 * last explicitly stated value"
2485afab0e5SDag-Erling Smørgrav 					 * (RFC 1035 Section 5.1)
2495afab0e5SDag-Erling Smørgrav 					 */
2505afab0e5SDag-Erling Smørgrav 					my_ttl = ldns_rr_ttl(rr);
2515afab0e5SDag-Erling Smørgrav 				}
2525afab0e5SDag-Erling Smørgrav 			/* When ttl is implicit, try to adhere to the rules as
2535afab0e5SDag-Erling Smørgrav 			 * much as possible. (also for compatibility with bind)
2545afab0e5SDag-Erling Smørgrav 			 * This was changed when fixing an issue with ZONEMD
2555afab0e5SDag-Erling Smørgrav 			 * which hashes the TTL too.
2565afab0e5SDag-Erling Smørgrav 			 */
2575afab0e5SDag-Erling Smørgrav 			} else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SIG
2585afab0e5SDag-Erling Smørgrav 			       ||  ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
2595afab0e5SDag-Erling Smørgrav 				if (ldns_rr_rd_count(rr) >= 4
2605afab0e5SDag-Erling Smørgrav 				&&  ldns_rdf_get_type(ldns_rr_rdf(rr, 3)) == LDNS_RDF_TYPE_INT32)
2615afab0e5SDag-Erling Smørgrav 
2625afab0e5SDag-Erling Smørgrav 					/* SIG without explicit ttl get ttl
2635afab0e5SDag-Erling Smørgrav 					 * from the original_ttl field
2645afab0e5SDag-Erling Smørgrav 					 * (RFC 2535 Section 7.2)
2655afab0e5SDag-Erling Smørgrav 					 *
2665afab0e5SDag-Erling Smørgrav 					 * Similarly for RRSIG, but stated less
2675afab0e5SDag-Erling Smørgrav 					 * specifically in the spec.
2685afab0e5SDag-Erling Smørgrav 					 * (RFC 4034 Section 3)
2695afab0e5SDag-Erling Smørgrav 					 */
2705afab0e5SDag-Erling Smørgrav 					ldns_rr_set_ttl(rr,
2715afab0e5SDag-Erling Smørgrav 					    ldns_rdf2native_int32(
2725afab0e5SDag-Erling Smørgrav 					        ldns_rr_rdf(rr, 3)));
2735afab0e5SDag-Erling Smørgrav 
2745afab0e5SDag-Erling Smørgrav 			} else if (prev_rr
2755afab0e5SDag-Erling Smørgrav 			       &&  ldns_rr_get_type(prev_rr) == ldns_rr_get_type(rr)
2765afab0e5SDag-Erling Smørgrav 			       &&  ldns_dname_compare( ldns_rr_owner(prev_rr)
2775afab0e5SDag-Erling Smørgrav 			                             , ldns_rr_owner(rr)) == 0)
2785afab0e5SDag-Erling Smørgrav 
2795afab0e5SDag-Erling Smørgrav 				/* "TTLs of all RRs in an RRSet must be the same"
2805afab0e5SDag-Erling Smørgrav 				 * (RFC 2881 Section 5.2)
2815afab0e5SDag-Erling Smørgrav 				 */
2825afab0e5SDag-Erling Smørgrav 				ldns_rr_set_ttl(rr, ldns_rr_ttl(prev_rr));
2835afab0e5SDag-Erling Smørgrav 
2845afab0e5SDag-Erling Smørgrav 			prev_rr = rr;
2857b5038d7SDag-Erling Smørgrav 			if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
2867b5038d7SDag-Erling Smørgrav 				if (soa_seen) {
2877b5038d7SDag-Erling Smørgrav 					/* second SOA
2887b5038d7SDag-Erling Smørgrav 					 * just skip, maybe we want to say
2897b5038d7SDag-Erling Smørgrav 					 * something??? */
2907b5038d7SDag-Erling Smørgrav 					ldns_rr_free(rr);
2917b5038d7SDag-Erling Smørgrav 					continue;
2927b5038d7SDag-Erling Smørgrav 				}
2937b5038d7SDag-Erling Smørgrav 				soa_seen = true;
2947b5038d7SDag-Erling Smørgrav 				ldns_zone_set_soa(newzone, rr);
2957b5038d7SDag-Erling Smørgrav 				/* set origin to soa if not specified */
2967b5038d7SDag-Erling Smørgrav 				if (!my_origin) {
2977b5038d7SDag-Erling Smørgrav 					my_origin = ldns_rdf_clone(ldns_rr_owner(rr));
2987b5038d7SDag-Erling Smørgrav 				}
2997b5038d7SDag-Erling Smørgrav 				continue;
3007b5038d7SDag-Erling Smørgrav 			}
3017b5038d7SDag-Erling Smørgrav 
3027b5038d7SDag-Erling Smørgrav 			/* a normal RR - as sofar the DNS is normal */
3035afab0e5SDag-Erling Smørgrav 			if (!ldns_zone_push_rr(newzone, rr)) {
3045afab0e5SDag-Erling Smørgrav 				ldns_rr_free(rr);
3055afab0e5SDag-Erling Smørgrav 				goto error;
3065afab0e5SDag-Erling Smørgrav 			}
3075afab0e5SDag-Erling Smørgrav 			break;
3087b5038d7SDag-Erling Smørgrav 
3097b5038d7SDag-Erling Smørgrav 		case LDNS_STATUS_SYNTAX_EMPTY:
3107b5038d7SDag-Erling Smørgrav 			/* empty line was seen */
3117b5038d7SDag-Erling Smørgrav 		case LDNS_STATUS_SYNTAX_TTL:
3127b5038d7SDag-Erling Smørgrav 			/* the function set the ttl */
3135afab0e5SDag-Erling Smørgrav 			default_ttl = my_ttl;
3145afab0e5SDag-Erling Smørgrav 			ttl_from_TTL = true;
3157b5038d7SDag-Erling Smørgrav 			break;
3167b5038d7SDag-Erling Smørgrav 		case LDNS_STATUS_SYNTAX_ORIGIN:
3177b5038d7SDag-Erling Smørgrav 			/* the function set the origin */
3187b5038d7SDag-Erling Smørgrav 			break;
3197b5038d7SDag-Erling Smørgrav 		case LDNS_STATUS_SYNTAX_INCLUDE:
3207b5038d7SDag-Erling Smørgrav 			ret = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
3215afab0e5SDag-Erling Smørgrav 			goto error;
3227b5038d7SDag-Erling Smørgrav 		default:
3237b5038d7SDag-Erling Smørgrav 			ret = s;
3247b5038d7SDag-Erling Smørgrav 			goto error;
3257b5038d7SDag-Erling Smørgrav 		}
3267b5038d7SDag-Erling Smørgrav 	}
3277b5038d7SDag-Erling Smørgrav 
3287b5038d7SDag-Erling Smørgrav 	if (my_origin) {
3297b5038d7SDag-Erling Smørgrav 		ldns_rdf_deep_free(my_origin);
3307b5038d7SDag-Erling Smørgrav 	}
3317b5038d7SDag-Erling Smørgrav 	if (my_prev) {
3327b5038d7SDag-Erling Smørgrav 		ldns_rdf_deep_free(my_prev);
3337b5038d7SDag-Erling Smørgrav 	}
3347b5038d7SDag-Erling Smørgrav 	if (z) {
3357b5038d7SDag-Erling Smørgrav 		*z = newzone;
3367b5038d7SDag-Erling Smørgrav 	} else {
3377b5038d7SDag-Erling Smørgrav 		ldns_zone_free(newzone);
3387b5038d7SDag-Erling Smørgrav 	}
3397b5038d7SDag-Erling Smørgrav 
3407b5038d7SDag-Erling Smørgrav 	return LDNS_STATUS_OK;
3417b5038d7SDag-Erling Smørgrav 
3427b5038d7SDag-Erling Smørgrav error:
3437b5038d7SDag-Erling Smørgrav 	if (my_origin) {
3447b5038d7SDag-Erling Smørgrav 		ldns_rdf_deep_free(my_origin);
3457b5038d7SDag-Erling Smørgrav 	}
3467b5038d7SDag-Erling Smørgrav 	if (my_prev) {
3477b5038d7SDag-Erling Smørgrav 		ldns_rdf_deep_free(my_prev);
3487b5038d7SDag-Erling Smørgrav 	}
3497b5038d7SDag-Erling Smørgrav 	if (newzone) {
3507b5038d7SDag-Erling Smørgrav 		ldns_zone_free(newzone);
3517b5038d7SDag-Erling Smørgrav 	}
3527b5038d7SDag-Erling Smørgrav 	return ret;
3537b5038d7SDag-Erling Smørgrav }
3547b5038d7SDag-Erling Smørgrav 
3557b5038d7SDag-Erling Smørgrav void
ldns_zone_sort(ldns_zone * zone)3567b5038d7SDag-Erling Smørgrav ldns_zone_sort(ldns_zone *zone)
3577b5038d7SDag-Erling Smørgrav {
3587b5038d7SDag-Erling Smørgrav 	ldns_rr_list *zrr;
3597b5038d7SDag-Erling Smørgrav 	assert(zone != NULL);
3607b5038d7SDag-Erling Smørgrav 
3617b5038d7SDag-Erling Smørgrav 	zrr = ldns_zone_rrs(zone);
3627b5038d7SDag-Erling Smørgrav 	ldns_rr_list_sort(zrr);
3637b5038d7SDag-Erling Smørgrav }
3647b5038d7SDag-Erling Smørgrav 
3657b5038d7SDag-Erling Smørgrav void
ldns_zone_free(ldns_zone * zone)3667b5038d7SDag-Erling Smørgrav ldns_zone_free(ldns_zone *zone)
3677b5038d7SDag-Erling Smørgrav {
3687b5038d7SDag-Erling Smørgrav 	ldns_rr_list_free(zone->_rrs);
3697b5038d7SDag-Erling Smørgrav 	LDNS_FREE(zone);
3707b5038d7SDag-Erling Smørgrav }
3717b5038d7SDag-Erling Smørgrav 
3727b5038d7SDag-Erling Smørgrav void
ldns_zone_deep_free(ldns_zone * zone)3737b5038d7SDag-Erling Smørgrav ldns_zone_deep_free(ldns_zone *zone)
3747b5038d7SDag-Erling Smørgrav {
3757b5038d7SDag-Erling Smørgrav 	ldns_rr_free(zone->_soa);
3767b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(zone->_rrs);
3777b5038d7SDag-Erling Smørgrav 	LDNS_FREE(zone);
3787b5038d7SDag-Erling Smørgrav }
379