1*7b5038d7SDag-Erling Smørgrav /* zone.c 2*7b5038d7SDag-Erling Smørgrav * 3*7b5038d7SDag-Erling Smørgrav * Functions for ldns_zone structure 4*7b5038d7SDag-Erling Smørgrav * a Net::DNS like library for C 5*7b5038d7SDag-Erling Smørgrav * 6*7b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2005-2006 7*7b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 8*7b5038d7SDag-Erling Smørgrav */ 9*7b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 10*7b5038d7SDag-Erling Smørgrav 11*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 12*7b5038d7SDag-Erling Smørgrav 13*7b5038d7SDag-Erling Smørgrav #include <strings.h> 14*7b5038d7SDag-Erling Smørgrav #include <limits.h> 15*7b5038d7SDag-Erling Smørgrav 16*7b5038d7SDag-Erling Smørgrav ldns_rr * 17*7b5038d7SDag-Erling Smørgrav ldns_zone_soa(const ldns_zone *z) 18*7b5038d7SDag-Erling Smørgrav { 19*7b5038d7SDag-Erling Smørgrav return z->_soa; 20*7b5038d7SDag-Erling Smørgrav } 21*7b5038d7SDag-Erling Smørgrav 22*7b5038d7SDag-Erling Smørgrav size_t 23*7b5038d7SDag-Erling Smørgrav ldns_zone_rr_count(const ldns_zone *z) 24*7b5038d7SDag-Erling Smørgrav { 25*7b5038d7SDag-Erling Smørgrav return ldns_rr_list_rr_count(z->_rrs); 26*7b5038d7SDag-Erling Smørgrav } 27*7b5038d7SDag-Erling Smørgrav 28*7b5038d7SDag-Erling Smørgrav void 29*7b5038d7SDag-Erling Smørgrav ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa) 30*7b5038d7SDag-Erling Smørgrav { 31*7b5038d7SDag-Erling Smørgrav z->_soa = soa; 32*7b5038d7SDag-Erling Smørgrav } 33*7b5038d7SDag-Erling Smørgrav 34*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 35*7b5038d7SDag-Erling Smørgrav ldns_zone_rrs(const ldns_zone *z) 36*7b5038d7SDag-Erling Smørgrav { 37*7b5038d7SDag-Erling Smørgrav return z->_rrs; 38*7b5038d7SDag-Erling Smørgrav } 39*7b5038d7SDag-Erling Smørgrav 40*7b5038d7SDag-Erling Smørgrav void 41*7b5038d7SDag-Erling Smørgrav ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist) 42*7b5038d7SDag-Erling Smørgrav { 43*7b5038d7SDag-Erling Smørgrav z->_rrs = rrlist; 44*7b5038d7SDag-Erling Smørgrav } 45*7b5038d7SDag-Erling Smørgrav 46*7b5038d7SDag-Erling Smørgrav bool 47*7b5038d7SDag-Erling Smørgrav ldns_zone_push_rr_list(ldns_zone *z, ldns_rr_list *list) 48*7b5038d7SDag-Erling Smørgrav { 49*7b5038d7SDag-Erling Smørgrav return ldns_rr_list_cat(ldns_zone_rrs(z), list); 50*7b5038d7SDag-Erling Smørgrav 51*7b5038d7SDag-Erling Smørgrav } 52*7b5038d7SDag-Erling Smørgrav 53*7b5038d7SDag-Erling Smørgrav bool 54*7b5038d7SDag-Erling Smørgrav ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr) 55*7b5038d7SDag-Erling Smørgrav { 56*7b5038d7SDag-Erling Smørgrav return ldns_rr_list_push_rr( ldns_zone_rrs(z), rr); 57*7b5038d7SDag-Erling Smørgrav } 58*7b5038d7SDag-Erling Smørgrav 59*7b5038d7SDag-Erling Smørgrav /* return a clone of the given rr list, without the glue records 60*7b5038d7SDag-Erling Smørgrav * rr list should be the complete zone 61*7b5038d7SDag-Erling Smørgrav * if present, stripped records are added to the list *glue_records 62*7b5038d7SDag-Erling Smørgrav */ 63*7b5038d7SDag-Erling Smørgrav static ldns_rr_list * 64*7b5038d7SDag-Erling Smørgrav ldns_zone_strip_glue_rrs(const ldns_rdf *zone_name, const ldns_rr_list *rrs, ldns_rr_list *glue_rrs) 65*7b5038d7SDag-Erling Smørgrav { 66*7b5038d7SDag-Erling Smørgrav ldns_rr_list *new_list; 67*7b5038d7SDag-Erling Smørgrav 68*7b5038d7SDag-Erling Smørgrav /* when do we find glue? It means we find an IP address 69*7b5038d7SDag-Erling Smørgrav * (AAAA/A) for a nameserver listed in the zone 70*7b5038d7SDag-Erling Smørgrav * 71*7b5038d7SDag-Erling Smørgrav * Alg used here: 72*7b5038d7SDag-Erling Smørgrav * first find all the zonecuts (NS records) 73*7b5038d7SDag-Erling Smørgrav * find all the AAAA or A records (can be done it the 74*7b5038d7SDag-Erling Smørgrav * above loop). 75*7b5038d7SDag-Erling Smørgrav * 76*7b5038d7SDag-Erling Smørgrav * Check if the aaaa/a list are subdomains under the 77*7b5038d7SDag-Erling Smørgrav * NS domains. 78*7b5038d7SDag-Erling Smørgrav * If yes -> glue, if no -> not glue 79*7b5038d7SDag-Erling Smørgrav */ 80*7b5038d7SDag-Erling Smørgrav 81*7b5038d7SDag-Erling Smørgrav ldns_rr_list *zone_cuts; 82*7b5038d7SDag-Erling Smørgrav ldns_rr_list *addr; 83*7b5038d7SDag-Erling Smørgrav ldns_rr *r, *ns, *a; 84*7b5038d7SDag-Erling Smørgrav ldns_rdf *dname_a, *ns_owner; 85*7b5038d7SDag-Erling Smørgrav uint16_t i,j; 86*7b5038d7SDag-Erling Smørgrav 87*7b5038d7SDag-Erling Smørgrav new_list = NULL; 88*7b5038d7SDag-Erling Smørgrav zone_cuts = NULL; 89*7b5038d7SDag-Erling Smørgrav addr = NULL; 90*7b5038d7SDag-Erling Smørgrav 91*7b5038d7SDag-Erling Smørgrav new_list = ldns_rr_list_new(); 92*7b5038d7SDag-Erling Smørgrav if (!new_list) goto memory_error; 93*7b5038d7SDag-Erling Smørgrav zone_cuts = ldns_rr_list_new(); 94*7b5038d7SDag-Erling Smørgrav if (!zone_cuts) goto memory_error; 95*7b5038d7SDag-Erling Smørgrav addr = ldns_rr_list_new(); 96*7b5038d7SDag-Erling Smørgrav if (!addr) goto memory_error; 97*7b5038d7SDag-Erling Smørgrav 98*7b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 99*7b5038d7SDag-Erling Smørgrav r = ldns_rr_list_rr(rrs, i); 100*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(r) == LDNS_RR_TYPE_A || 101*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(r) == LDNS_RR_TYPE_AAAA) { 102*7b5038d7SDag-Erling Smørgrav /* possibly glue */ 103*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(addr, r)) goto memory_error; 104*7b5038d7SDag-Erling Smørgrav continue; 105*7b5038d7SDag-Erling Smørgrav } 106*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(r) == LDNS_RR_TYPE_NS) { 107*7b5038d7SDag-Erling Smørgrav /* multiple zones will end up here - 108*7b5038d7SDag-Erling Smørgrav * for now; not a problem 109*7b5038d7SDag-Erling Smørgrav */ 110*7b5038d7SDag-Erling Smørgrav /* don't add NS records for the current zone itself */ 111*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_compare(ldns_rr_owner(r), 112*7b5038d7SDag-Erling Smørgrav zone_name) != 0) { 113*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(zone_cuts, r)) goto memory_error; 114*7b5038d7SDag-Erling Smørgrav } 115*7b5038d7SDag-Erling Smørgrav continue; 116*7b5038d7SDag-Erling Smørgrav } 117*7b5038d7SDag-Erling Smørgrav } 118*7b5038d7SDag-Erling Smørgrav 119*7b5038d7SDag-Erling Smørgrav /* will sorting make it quicker ?? */ 120*7b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(zone_cuts); i++) { 121*7b5038d7SDag-Erling Smørgrav ns = ldns_rr_list_rr(zone_cuts, i); 122*7b5038d7SDag-Erling Smørgrav ns_owner = ldns_rr_owner(ns); 123*7b5038d7SDag-Erling Smørgrav for(j = 0; j < ldns_rr_list_rr_count(addr); j++) { 124*7b5038d7SDag-Erling Smørgrav a = ldns_rr_list_rr(addr, j); 125*7b5038d7SDag-Erling Smørgrav dname_a = ldns_rr_owner(a); 126*7b5038d7SDag-Erling Smørgrav 127*7b5038d7SDag-Erling Smørgrav if (ldns_dname_is_subdomain(dname_a, ns_owner)) { 128*7b5038d7SDag-Erling Smørgrav /* GLUE! */ 129*7b5038d7SDag-Erling Smørgrav if (glue_rrs) { 130*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(glue_rrs, a)) goto memory_error; 131*7b5038d7SDag-Erling Smørgrav } 132*7b5038d7SDag-Erling Smørgrav break; 133*7b5038d7SDag-Erling Smørgrav } else { 134*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(new_list, a)) goto memory_error; 135*7b5038d7SDag-Erling Smørgrav } 136*7b5038d7SDag-Erling Smørgrav } 137*7b5038d7SDag-Erling Smørgrav } 138*7b5038d7SDag-Erling Smørgrav 139*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(addr); 140*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(zone_cuts); 141*7b5038d7SDag-Erling Smørgrav 142*7b5038d7SDag-Erling Smørgrav return new_list; 143*7b5038d7SDag-Erling Smørgrav 144*7b5038d7SDag-Erling Smørgrav memory_error: 145*7b5038d7SDag-Erling Smørgrav if (new_list) { 146*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(new_list); 147*7b5038d7SDag-Erling Smørgrav } 148*7b5038d7SDag-Erling Smørgrav if (zone_cuts) { 149*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(zone_cuts); 150*7b5038d7SDag-Erling Smørgrav } 151*7b5038d7SDag-Erling Smørgrav if (addr) { 152*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(addr); 153*7b5038d7SDag-Erling Smørgrav } 154*7b5038d7SDag-Erling Smørgrav return NULL; 155*7b5038d7SDag-Erling Smørgrav } 156*7b5038d7SDag-Erling Smørgrav 157*7b5038d7SDag-Erling Smørgrav /* 158*7b5038d7SDag-Erling Smørgrav * Get the list of glue records in a zone 159*7b5038d7SDag-Erling Smørgrav * XXX: there should be a way for this to return error, other than NULL, 160*7b5038d7SDag-Erling Smørgrav * since NULL is a valid return 161*7b5038d7SDag-Erling Smørgrav */ 162*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 163*7b5038d7SDag-Erling Smørgrav ldns_zone_glue_rr_list(const ldns_zone *z) 164*7b5038d7SDag-Erling Smørgrav { 165*7b5038d7SDag-Erling Smørgrav /* when do we find glue? It means we find an IP address 166*7b5038d7SDag-Erling Smørgrav * (AAAA/A) for a nameserver listed in the zone 167*7b5038d7SDag-Erling Smørgrav * 168*7b5038d7SDag-Erling Smørgrav * Alg used here: 169*7b5038d7SDag-Erling Smørgrav * first find all the zonecuts (NS records) 170*7b5038d7SDag-Erling Smørgrav * find all the AAAA or A records (can be done it the 171*7b5038d7SDag-Erling Smørgrav * above loop). 172*7b5038d7SDag-Erling Smørgrav * 173*7b5038d7SDag-Erling Smørgrav * Check if the aaaa/a list are subdomains under the 174*7b5038d7SDag-Erling Smørgrav * NS domains. 175*7b5038d7SDag-Erling Smørgrav * If yes -> glue, if no -> not glue 176*7b5038d7SDag-Erling Smørgrav */ 177*7b5038d7SDag-Erling Smørgrav 178*7b5038d7SDag-Erling Smørgrav ldns_rr_list *zone_cuts; 179*7b5038d7SDag-Erling Smørgrav ldns_rr_list *addr; 180*7b5038d7SDag-Erling Smørgrav ldns_rr_list *glue; 181*7b5038d7SDag-Erling Smørgrav ldns_rr *r, *ns, *a; 182*7b5038d7SDag-Erling Smørgrav ldns_rdf *dname_a, *ns_owner; 183*7b5038d7SDag-Erling Smørgrav size_t i,j; 184*7b5038d7SDag-Erling Smørgrav 185*7b5038d7SDag-Erling Smørgrav zone_cuts = NULL; 186*7b5038d7SDag-Erling Smørgrav addr = NULL; 187*7b5038d7SDag-Erling Smørgrav glue = NULL; 188*7b5038d7SDag-Erling Smørgrav 189*7b5038d7SDag-Erling Smørgrav /* we cannot determine glue in a 'zone' without a SOA */ 190*7b5038d7SDag-Erling Smørgrav if (!ldns_zone_soa(z)) { 191*7b5038d7SDag-Erling Smørgrav return NULL; 192*7b5038d7SDag-Erling Smørgrav } 193*7b5038d7SDag-Erling Smørgrav 194*7b5038d7SDag-Erling Smørgrav zone_cuts = ldns_rr_list_new(); 195*7b5038d7SDag-Erling Smørgrav if (!zone_cuts) goto memory_error; 196*7b5038d7SDag-Erling Smørgrav addr = ldns_rr_list_new(); 197*7b5038d7SDag-Erling Smørgrav if (!addr) goto memory_error; 198*7b5038d7SDag-Erling Smørgrav glue = ldns_rr_list_new(); 199*7b5038d7SDag-Erling Smørgrav if (!glue) goto memory_error; 200*7b5038d7SDag-Erling Smørgrav 201*7b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_zone_rr_count(z); i++) { 202*7b5038d7SDag-Erling Smørgrav r = ldns_rr_list_rr(ldns_zone_rrs(z), i); 203*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(r) == LDNS_RR_TYPE_A || 204*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(r) == LDNS_RR_TYPE_AAAA) { 205*7b5038d7SDag-Erling Smørgrav /* possibly glue */ 206*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(addr, r)) goto memory_error; 207*7b5038d7SDag-Erling Smørgrav continue; 208*7b5038d7SDag-Erling Smørgrav } 209*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(r) == LDNS_RR_TYPE_NS) { 210*7b5038d7SDag-Erling Smørgrav /* multiple zones will end up here - 211*7b5038d7SDag-Erling Smørgrav * for now; not a problem 212*7b5038d7SDag-Erling Smørgrav */ 213*7b5038d7SDag-Erling Smørgrav /* don't add NS records for the current zone itself */ 214*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_compare(ldns_rr_owner(r), 215*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_zone_soa(z))) != 0) { 216*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(zone_cuts, r)) goto memory_error; 217*7b5038d7SDag-Erling Smørgrav } 218*7b5038d7SDag-Erling Smørgrav continue; 219*7b5038d7SDag-Erling Smørgrav } 220*7b5038d7SDag-Erling Smørgrav } 221*7b5038d7SDag-Erling Smørgrav 222*7b5038d7SDag-Erling Smørgrav /* will sorting make it quicker ?? */ 223*7b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(zone_cuts); i++) { 224*7b5038d7SDag-Erling Smørgrav ns = ldns_rr_list_rr(zone_cuts, i); 225*7b5038d7SDag-Erling Smørgrav ns_owner = ldns_rr_owner(ns); 226*7b5038d7SDag-Erling Smørgrav 227*7b5038d7SDag-Erling Smørgrav for(j = 0; j < ldns_rr_list_rr_count(addr); j++) { 228*7b5038d7SDag-Erling Smørgrav a = ldns_rr_list_rr(addr, j); 229*7b5038d7SDag-Erling Smørgrav dname_a = ldns_rr_owner(a); 230*7b5038d7SDag-Erling Smørgrav 231*7b5038d7SDag-Erling Smørgrav if (ldns_dname_is_subdomain(dname_a, ns_owner) || 232*7b5038d7SDag-Erling Smørgrav ldns_dname_compare(dname_a, ns_owner) == 0) { 233*7b5038d7SDag-Erling Smørgrav /* GLUE! */ 234*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(glue, a)) goto memory_error; 235*7b5038d7SDag-Erling Smørgrav } 236*7b5038d7SDag-Erling Smørgrav } 237*7b5038d7SDag-Erling Smørgrav } 238*7b5038d7SDag-Erling Smørgrav 239*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(addr); 240*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(zone_cuts); 241*7b5038d7SDag-Erling Smørgrav 242*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(glue) == 0) { 243*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(glue); 244*7b5038d7SDag-Erling Smørgrav return NULL; 245*7b5038d7SDag-Erling Smørgrav } else { 246*7b5038d7SDag-Erling Smørgrav return glue; 247*7b5038d7SDag-Erling Smørgrav } 248*7b5038d7SDag-Erling Smørgrav 249*7b5038d7SDag-Erling Smørgrav memory_error: 250*7b5038d7SDag-Erling Smørgrav if (zone_cuts) { 251*7b5038d7SDag-Erling Smørgrav LDNS_FREE(zone_cuts); 252*7b5038d7SDag-Erling Smørgrav } 253*7b5038d7SDag-Erling Smørgrav if (addr) { 254*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(addr); 255*7b5038d7SDag-Erling Smørgrav } 256*7b5038d7SDag-Erling Smørgrav if (glue) { 257*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(glue); 258*7b5038d7SDag-Erling Smørgrav } 259*7b5038d7SDag-Erling Smørgrav return NULL; 260*7b5038d7SDag-Erling Smørgrav } 261*7b5038d7SDag-Erling Smørgrav 262*7b5038d7SDag-Erling Smørgrav ldns_zone * 263*7b5038d7SDag-Erling Smørgrav ldns_zone_new(void) 264*7b5038d7SDag-Erling Smørgrav { 265*7b5038d7SDag-Erling Smørgrav ldns_zone *z; 266*7b5038d7SDag-Erling Smørgrav 267*7b5038d7SDag-Erling Smørgrav z = LDNS_MALLOC(ldns_zone); 268*7b5038d7SDag-Erling Smørgrav if (!z) { 269*7b5038d7SDag-Erling Smørgrav return NULL; 270*7b5038d7SDag-Erling Smørgrav } 271*7b5038d7SDag-Erling Smørgrav 272*7b5038d7SDag-Erling Smørgrav z->_rrs = ldns_rr_list_new(); 273*7b5038d7SDag-Erling Smørgrav if (!z->_rrs) { 274*7b5038d7SDag-Erling Smørgrav LDNS_FREE(z); 275*7b5038d7SDag-Erling Smørgrav return NULL; 276*7b5038d7SDag-Erling Smørgrav } 277*7b5038d7SDag-Erling Smørgrav ldns_zone_set_soa(z, NULL); 278*7b5038d7SDag-Erling Smørgrav return z; 279*7b5038d7SDag-Erling Smørgrav } 280*7b5038d7SDag-Erling Smørgrav 281*7b5038d7SDag-Erling Smørgrav /* we regocnize: 282*7b5038d7SDag-Erling Smørgrav * $TTL, $ORIGIN 283*7b5038d7SDag-Erling Smørgrav */ 284*7b5038d7SDag-Erling Smørgrav ldns_status 285*7b5038d7SDag-Erling Smørgrav ldns_zone_new_frm_fp(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c) 286*7b5038d7SDag-Erling Smørgrav { 287*7b5038d7SDag-Erling Smørgrav return ldns_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL); 288*7b5038d7SDag-Erling Smørgrav } 289*7b5038d7SDag-Erling Smørgrav 290*7b5038d7SDag-Erling Smørgrav /* XXX: class is never used */ 291*7b5038d7SDag-Erling Smørgrav ldns_status 292*7b5038d7SDag-Erling Smørgrav ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, 293*7b5038d7SDag-Erling Smørgrav ldns_rr_class ATTR_UNUSED(c), int *line_nr) 294*7b5038d7SDag-Erling Smørgrav { 295*7b5038d7SDag-Erling Smørgrav ldns_zone *newzone; 296*7b5038d7SDag-Erling Smørgrav ldns_rr *rr; 297*7b5038d7SDag-Erling Smørgrav uint32_t my_ttl; 298*7b5038d7SDag-Erling Smørgrav ldns_rdf *my_origin; 299*7b5038d7SDag-Erling Smørgrav ldns_rdf *my_prev; 300*7b5038d7SDag-Erling Smørgrav bool soa_seen = false; /* 2 soa are an error */ 301*7b5038d7SDag-Erling Smørgrav ldns_status s; 302*7b5038d7SDag-Erling Smørgrav ldns_status ret; 303*7b5038d7SDag-Erling Smørgrav 304*7b5038d7SDag-Erling Smørgrav /* most cases of error are memory problems */ 305*7b5038d7SDag-Erling Smørgrav ret = LDNS_STATUS_MEM_ERR; 306*7b5038d7SDag-Erling Smørgrav 307*7b5038d7SDag-Erling Smørgrav newzone = NULL; 308*7b5038d7SDag-Erling Smørgrav my_origin = NULL; 309*7b5038d7SDag-Erling Smørgrav my_prev = NULL; 310*7b5038d7SDag-Erling Smørgrav 311*7b5038d7SDag-Erling Smørgrav my_ttl = ttl; 312*7b5038d7SDag-Erling Smørgrav 313*7b5038d7SDag-Erling Smørgrav if (origin) { 314*7b5038d7SDag-Erling Smørgrav my_origin = ldns_rdf_clone(origin); 315*7b5038d7SDag-Erling Smørgrav if (!my_origin) goto error; 316*7b5038d7SDag-Erling Smørgrav /* also set the prev */ 317*7b5038d7SDag-Erling Smørgrav my_prev = ldns_rdf_clone(origin); 318*7b5038d7SDag-Erling Smørgrav if (!my_prev) goto error; 319*7b5038d7SDag-Erling Smørgrav } 320*7b5038d7SDag-Erling Smørgrav 321*7b5038d7SDag-Erling Smørgrav newzone = ldns_zone_new(); 322*7b5038d7SDag-Erling Smørgrav if (!newzone) goto error; 323*7b5038d7SDag-Erling Smørgrav 324*7b5038d7SDag-Erling Smørgrav while(!feof(fp)) { 325*7b5038d7SDag-Erling Smørgrav s = ldns_rr_new_frm_fp_l(&rr, fp, &my_ttl, &my_origin, &my_prev, line_nr); 326*7b5038d7SDag-Erling Smørgrav switch (s) { 327*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_OK: 328*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { 329*7b5038d7SDag-Erling Smørgrav if (soa_seen) { 330*7b5038d7SDag-Erling Smørgrav /* second SOA 331*7b5038d7SDag-Erling Smørgrav * just skip, maybe we want to say 332*7b5038d7SDag-Erling Smørgrav * something??? */ 333*7b5038d7SDag-Erling Smørgrav ldns_rr_free(rr); 334*7b5038d7SDag-Erling Smørgrav continue; 335*7b5038d7SDag-Erling Smørgrav } 336*7b5038d7SDag-Erling Smørgrav soa_seen = true; 337*7b5038d7SDag-Erling Smørgrav ldns_zone_set_soa(newzone, rr); 338*7b5038d7SDag-Erling Smørgrav /* set origin to soa if not specified */ 339*7b5038d7SDag-Erling Smørgrav if (!my_origin) { 340*7b5038d7SDag-Erling Smørgrav my_origin = ldns_rdf_clone(ldns_rr_owner(rr)); 341*7b5038d7SDag-Erling Smørgrav } 342*7b5038d7SDag-Erling Smørgrav continue; 343*7b5038d7SDag-Erling Smørgrav } 344*7b5038d7SDag-Erling Smørgrav 345*7b5038d7SDag-Erling Smørgrav /* a normal RR - as sofar the DNS is normal */ 346*7b5038d7SDag-Erling Smørgrav if (!ldns_zone_push_rr(newzone, rr)) goto error; 347*7b5038d7SDag-Erling Smørgrav 348*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_EMPTY: 349*7b5038d7SDag-Erling Smørgrav /* empty line was seen */ 350*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_TTL: 351*7b5038d7SDag-Erling Smørgrav /* the function set the ttl */ 352*7b5038d7SDag-Erling Smørgrav break; 353*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_ORIGIN: 354*7b5038d7SDag-Erling Smørgrav /* the function set the origin */ 355*7b5038d7SDag-Erling Smørgrav break; 356*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_INCLUDE: 357*7b5038d7SDag-Erling Smørgrav ret = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL; 358*7b5038d7SDag-Erling Smørgrav break; 359*7b5038d7SDag-Erling Smørgrav default: 360*7b5038d7SDag-Erling Smørgrav ret = s; 361*7b5038d7SDag-Erling Smørgrav goto error; 362*7b5038d7SDag-Erling Smørgrav } 363*7b5038d7SDag-Erling Smørgrav } 364*7b5038d7SDag-Erling Smørgrav 365*7b5038d7SDag-Erling Smørgrav if (my_origin) { 366*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(my_origin); 367*7b5038d7SDag-Erling Smørgrav } 368*7b5038d7SDag-Erling Smørgrav if (my_prev) { 369*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(my_prev); 370*7b5038d7SDag-Erling Smørgrav } 371*7b5038d7SDag-Erling Smørgrav if (z) { 372*7b5038d7SDag-Erling Smørgrav *z = newzone; 373*7b5038d7SDag-Erling Smørgrav } else { 374*7b5038d7SDag-Erling Smørgrav ldns_zone_free(newzone); 375*7b5038d7SDag-Erling Smørgrav } 376*7b5038d7SDag-Erling Smørgrav 377*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 378*7b5038d7SDag-Erling Smørgrav 379*7b5038d7SDag-Erling Smørgrav error: 380*7b5038d7SDag-Erling Smørgrav if (my_origin) { 381*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(my_origin); 382*7b5038d7SDag-Erling Smørgrav } 383*7b5038d7SDag-Erling Smørgrav if (my_prev) { 384*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(my_prev); 385*7b5038d7SDag-Erling Smørgrav } 386*7b5038d7SDag-Erling Smørgrav if (newzone) { 387*7b5038d7SDag-Erling Smørgrav ldns_zone_free(newzone); 388*7b5038d7SDag-Erling Smørgrav } 389*7b5038d7SDag-Erling Smørgrav return ret; 390*7b5038d7SDag-Erling Smørgrav } 391*7b5038d7SDag-Erling Smørgrav 392*7b5038d7SDag-Erling Smørgrav void 393*7b5038d7SDag-Erling Smørgrav ldns_zone_sort(ldns_zone *zone) 394*7b5038d7SDag-Erling Smørgrav { 395*7b5038d7SDag-Erling Smørgrav ldns_rr_list *zrr; 396*7b5038d7SDag-Erling Smørgrav assert(zone != NULL); 397*7b5038d7SDag-Erling Smørgrav 398*7b5038d7SDag-Erling Smørgrav zrr = ldns_zone_rrs(zone); 399*7b5038d7SDag-Erling Smørgrav ldns_rr_list_sort(zrr); 400*7b5038d7SDag-Erling Smørgrav } 401*7b5038d7SDag-Erling Smørgrav 402*7b5038d7SDag-Erling Smørgrav #if 0 403*7b5038d7SDag-Erling Smørgrav /** 404*7b5038d7SDag-Erling Smørgrav * ixfr function. Work on a ldns_zone and remove and add 405*7b5038d7SDag-Erling Smørgrav * the rrs from the rrlist 406*7b5038d7SDag-Erling Smørgrav * \param[in] z the zone to work on 407*7b5038d7SDag-Erling Smørgrav * \param[in] del rr_list to remove from the zone 408*7b5038d7SDag-Erling Smørgrav * \param[in] add rr_list to add to the zone 409*7b5038d7SDag-Erling Smørgrav * \return Tja, wat zouden we eens returnen TODO 410*7b5038d7SDag-Erling Smørgrav */ 411*7b5038d7SDag-Erling Smørgrav void 412*7b5038d7SDag-Erling Smørgrav ldns_zone_ixfr_del_add(ldns_zone *z, ldns_rr_list *del, ldns_rr_list *add) 413*7b5038d7SDag-Erling Smørgrav { 414*7b5038d7SDag-Erling Smørgrav 415*7b5038d7SDag-Erling Smørgrav } 416*7b5038d7SDag-Erling Smørgrav #endif 417*7b5038d7SDag-Erling Smørgrav 418*7b5038d7SDag-Erling Smørgrav void 419*7b5038d7SDag-Erling Smørgrav ldns_zone_free(ldns_zone *zone) 420*7b5038d7SDag-Erling Smørgrav { 421*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(zone->_rrs); 422*7b5038d7SDag-Erling Smørgrav LDNS_FREE(zone); 423*7b5038d7SDag-Erling Smørgrav } 424*7b5038d7SDag-Erling Smørgrav 425*7b5038d7SDag-Erling Smørgrav void 426*7b5038d7SDag-Erling Smørgrav ldns_zone_deep_free(ldns_zone *zone) 427*7b5038d7SDag-Erling Smørgrav { 428*7b5038d7SDag-Erling Smørgrav ldns_rr_free(zone->_soa); 429*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(zone->_rrs); 430*7b5038d7SDag-Erling Smørgrav LDNS_FREE(zone); 431*7b5038d7SDag-Erling Smørgrav } 432