00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <ldns/config.h>
00010
00011 #include <ldns/ldns.h>
00012
00013 #include <strings.h>
00014 #include <limits.h>
00015
00016 ldns_rr *
00017 ldns_zone_soa(const ldns_zone *z)
00018 {
00019 return z->_soa;
00020 }
00021
00022 uint16_t
00023 ldns_zone_rr_count(const ldns_zone *z)
00024 {
00025 return ldns_rr_list_rr_count(z->_rrs);
00026 }
00027
00028 void
00029 ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa)
00030 {
00031 z->_soa = soa;
00032 }
00033
00034 ldns_rr_list *
00035 ldns_zone_rrs(const ldns_zone *z)
00036 {
00037 return z->_rrs;
00038 }
00039
00040 void
00041 ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist)
00042 {
00043 z->_rrs = rrlist;
00044 }
00045
00046 bool
00047 ldns_zone_push_rr_list(ldns_zone *z, ldns_rr_list *list)
00048 {
00049 return ldns_rr_list_cat(ldns_zone_rrs(z), list);
00050
00051 }
00052
00053 bool
00054 ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
00055 {
00056 return ldns_rr_list_push_rr( ldns_zone_rrs(z), rr);
00057 }
00058
00059
00060
00061
00062
00063 ldns_rr_list *
00064 ldns_zone_strip_glue_rrs(const ldns_rdf *zone_name, const ldns_rr_list *rrs, ldns_rr_list *glue_rrs)
00065 {
00066 ldns_rr_list *new_list = ldns_rr_list_new();
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 ldns_rr_list *zone_cuts;
00081 ldns_rr_list *addr;
00082 ldns_rr *r, *ns, *a;
00083 ldns_rdf *dname_a, *dname_ns, *ns_owner;
00084 uint16_t i,j;
00085
00086 zone_cuts = ldns_rr_list_new();
00087 addr = ldns_rr_list_new();
00088
00089 for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00090 r = ldns_rr_list_rr(rrs, i);
00091 if (ldns_rr_get_type(r) == LDNS_RR_TYPE_A ||
00092 ldns_rr_get_type(r) == LDNS_RR_TYPE_AAAA) {
00093
00094 ldns_rr_list_push_rr(addr, r);
00095 continue;
00096 }
00097 if (ldns_rr_get_type(r) == LDNS_RR_TYPE_NS) {
00098
00099
00100
00101
00102 if (ldns_rdf_compare(ldns_rr_owner(r),
00103 zone_name) != 0) {
00104 ldns_rr_list_push_rr(zone_cuts, r);
00105 }
00106 continue;
00107 }
00108 }
00109
00110
00111 for(i = 0; i < ldns_rr_list_rr_count(zone_cuts); i++) {
00112 ns = ldns_rr_list_rr(zone_cuts, i);
00113 ns_owner = ldns_rr_owner(ns);
00114 dname_ns = ldns_rr_ns_nsdname(ns);
00115 for(j = 0; j < ldns_rr_list_rr_count(addr); j++) {
00116 a = ldns_rr_list_rr(addr, j);
00117 dname_a = ldns_rr_owner(a);
00118
00119 if (ldns_dname_is_subdomain(dname_a, ns_owner) &&
00120 ldns_rdf_compare(dname_ns, dname_a) == 0) {
00121
00122 if (glue_rrs) {
00123 ldns_rr_list_push_rr(glue_rrs, a);
00124 }
00125 break;
00126 } else {
00127 ldns_rr_list_push_rr(new_list, a);
00128 }
00129 }
00130 }
00131
00132 ldns_rr_list_free(addr);
00133 ldns_rr_list_free(zone_cuts);
00134
00135 return new_list;
00136 }
00137
00138
00139 ldns_rr_list *
00140 ldns_zone_glue_rr_list(const ldns_zone *z)
00141 {
00142 #if 0
00143 ldns_rr_list *rrs = ldns_zone_rrs(z);
00144 ldns_rr_list *glue_rrs = ldns_rr_list_new();
00145 ldns_rr_list *stripped_rrs = ldns_zone_strip_glue_rrs(ldns_rr_owner(ldns_zone_soa(z)), rrs, glue_rrs);
00146 printf("stripped:\n");
00147 ldns_rr_list_print(stdout, stripped_rrs);
00148 printf("glue:\n");
00149 ldns_rr_list_print(stdout, glue_rrs);
00150 ldns_rr_list_free(stripped_rrs);
00151 return glue_rrs;
00152 #endif
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 ldns_rr_list *zone_cuts;
00167 ldns_rr_list *addr;
00168 ldns_rr_list *glue;
00169 ldns_rr *r, *ns, *a;
00170 ldns_rdf *dname_a, *dname_ns, *ns_owner;
00171 uint16_t i,j;
00172
00173 zone_cuts = ldns_rr_list_new();
00174 addr = ldns_rr_list_new();
00175 glue = ldns_rr_list_new();
00176
00177 for(i = 0; i < ldns_zone_rr_count(z); i++) {
00178 r = ldns_rr_list_rr(ldns_zone_rrs(z), i);
00179 if (ldns_rr_get_type(r) == LDNS_RR_TYPE_A ||
00180 ldns_rr_get_type(r) == LDNS_RR_TYPE_AAAA) {
00181
00182 ldns_rr_list_push_rr(addr, r);
00183 continue;
00184 }
00185 if (ldns_rr_get_type(r) == LDNS_RR_TYPE_NS) {
00186
00187
00188
00189
00190 if (ldns_rdf_compare(ldns_rr_owner(r),
00191 ldns_rr_owner(ldns_zone_soa(z))) != 0) {
00192 ldns_rr_list_push_rr(zone_cuts, r);
00193 }
00194 continue;
00195 }
00196 }
00197
00198
00199 for(i = 0; i < ldns_rr_list_rr_count(zone_cuts); i++) {
00200 ns = ldns_rr_list_rr(zone_cuts, i);
00201 ns_owner = ldns_rr_owner(ns);
00202
00203 dname_ns = ldns_rr_ns_nsdname(ns);
00204 for(j = 0; j < ldns_rr_list_rr_count(addr); j++) {
00205 a = ldns_rr_list_rr(addr, j);
00206 dname_a = ldns_rr_owner(a);
00207
00208
00209
00210
00211
00212 if (ldns_dname_is_subdomain(dname_a, ns_owner)) {
00213
00214 ldns_rr_list_push_rr(glue, a);
00215 }
00216 }
00217 }
00218
00219 ldns_rr_list_free(addr);
00220 ldns_rr_list_free(zone_cuts);
00221
00222 if (ldns_rr_list_rr_count(glue) == 0) {
00223 ldns_rr_list_free(glue);
00224 return NULL;
00225 } else {
00226 return glue;
00227 }
00228
00229 }
00230
00231 ldns_zone *
00232 ldns_zone_new(void)
00233 {
00234 ldns_zone *z;
00235
00236 z = LDNS_MALLOC(ldns_zone);
00237 if (!z) {
00238 return NULL;
00239 }
00240
00241 z->_rrs = ldns_rr_list_new();
00242 ldns_zone_set_soa(z, NULL);
00243 return z;
00244 }
00245
00246
00247
00248
00249 ldns_status
00250 ldns_zone_new_frm_fp(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c)
00251 {
00252 return ldns_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
00253 }
00254
00255 ldns_status
00256 ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c,
00257 int *line_nr)
00258 {
00259 ldns_zone *newzone;
00260 ldns_rr *rr;
00261 uint32_t my_ttl = ttl;
00262 ldns_rr_class my_class = c;
00263 ldns_rr *last_rr = NULL;
00264 ldns_rdf *my_origin;
00265 ldns_rdf *my_prev;
00266 bool soa_seen = false;
00267 ldns_status s;
00268
00269 newzone = ldns_zone_new();
00270 my_origin = origin;
00271 my_ttl = ttl;
00272 my_class = c;
00273
00274 if (origin) {
00275 my_origin = ldns_rdf_clone(origin);
00276
00277 my_prev = ldns_rdf_clone(origin);
00278 } else {
00279 my_origin = NULL;
00280 my_prev = NULL;
00281 }
00282
00283 while(!feof(fp)) {
00284 s = ldns_rr_new_frm_fp_l(&rr, fp, &my_ttl, &my_origin, &my_prev, line_nr);
00285 switch (s) {
00286 case LDNS_STATUS_OK:
00287 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
00288 if (soa_seen) {
00289
00290
00291
00292 ldns_rr_free(rr);
00293 continue;
00294 }
00295 soa_seen = true;
00296 ldns_zone_set_soa(newzone, rr);
00297
00298 if (!my_origin) {
00299 my_origin = ldns_rdf_clone(ldns_rr_owner(rr));
00300 }
00301 continue;
00302 }
00303
00304
00305 last_rr = rr;
00306 if (!ldns_zone_push_rr(newzone, rr)) {
00307 if (my_origin) {
00308 ldns_rdf_deep_free(my_origin);
00309 }
00310 ldns_zone_free(newzone);
00311 return LDNS_STATUS_MEM_ERR;
00312 }
00313
00314
00315 my_ttl = ldns_rr_ttl(rr);
00316 my_class = ldns_rr_get_class(rr);
00317 case LDNS_STATUS_SYNTAX_EMPTY:
00318
00319 case LDNS_STATUS_SYNTAX_TTL:
00320
00321 break;
00322 case LDNS_STATUS_SYNTAX_ORIGIN:
00323
00324 break;
00325 default:
00326 ldns_zone_free(newzone);
00327 return s;
00328 }
00329 }
00330
00331 if (my_origin) {
00332 ldns_rdf_deep_free(my_origin);
00333 }
00334 if (my_prev) {
00335 ldns_rdf_deep_free(my_prev);
00336 }
00337 if (z) {
00338 *z = newzone;
00339 }
00340
00341 return LDNS_STATUS_OK;
00342 }
00343
00344 void
00345 ldns_zone_sort(ldns_zone *zone)
00346 {
00347 ldns_rr_list *zrr;
00348 assert(zone != NULL);
00349
00350 zrr = ldns_zone_rrs(zone);
00351 ldns_rr_list_sort(zrr);
00352 }
00353
00354 #if 0
00355
00363 void
00364 ldns_zone_ixfr_del_add(ldns_zone *z, ldns_rr_list *del, ldns_rr_list *add)
00365 {
00366
00367 }
00368 #endif
00369
00370 void
00371 ldns_zone_free(ldns_zone *zone)
00372 {
00373 ldns_rr_list_free(zone->_rrs);
00374 LDNS_FREE(zone);
00375 }
00376
00377 void
00378 ldns_zone_deep_free(ldns_zone *zone)
00379 {
00380 ldns_rr_free(zone->_soa);
00381 ldns_rr_list_deep_free(zone->_rrs);
00382 LDNS_FREE(zone);
00383 }