1 1.1 christos /* 2 1.1 christos * ixfr.c -- generating IXFR responses. 3 1.1 christos * 4 1.1 christos * Copyright (c) 2021, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * See LICENSE for the license. 7 1.1 christos * 8 1.1 christos */ 9 1.1 christos 10 1.1 christos #include "config.h" 11 1.1 christos 12 1.1 christos #include <errno.h> 13 1.1 christos #include <string.h> 14 1.1 christos #include <ctype.h> 15 1.1 christos #ifdef HAVE_SYS_TYPES_H 16 1.1 christos # include <sys/types.h> 17 1.1 christos #endif 18 1.1 christos #ifdef HAVE_SYS_STAT_H 19 1.1 christos # include <sys/stat.h> 20 1.1 christos #endif 21 1.1 christos #include <unistd.h> 22 1.1 christos 23 1.1 christos #include "ixfr.h" 24 1.1 christos #include "packet.h" 25 1.1 christos #include "rdata.h" 26 1.1 christos #include "axfr.h" 27 1.1 christos #include "options.h" 28 1.1 christos #include "zonec.h" 29 1.1.1.3 christos #include "zone.h" 30 1.1 christos 31 1.1 christos /* 32 1.1 christos * For optimal compression IXFR response packets are limited in size 33 1.1 christos * to MAX_COMPRESSION_OFFSET. 34 1.1 christos */ 35 1.1 christos #define IXFR_MAX_MESSAGE_LEN MAX_COMPRESSION_OFFSET 36 1.1 christos 37 1.1 christos /* draft-ietf-dnsop-rfc2845bis-06, section 5.3.1 says to sign every packet */ 38 1.1 christos #define IXFR_TSIG_SIGN_EVERY_NTH 0 /* tsig sign every N packets. */ 39 1.1 christos 40 1.1 christos /* initial space in rrs data for storing records */ 41 1.1 christos #define IXFR_STORE_INITIAL_SIZE 4096 42 1.1 christos 43 1.1 christos /* store compression for one name */ 44 1.1 christos struct rrcompress_entry { 45 1.1 christos /* rbtree node, key is this struct */ 46 1.1 christos struct rbnode node; 47 1.1 christos /* the uncompressed domain name */ 48 1.1 christos const uint8_t* dname; 49 1.1 christos /* the length of the dname, includes terminating 0 label */ 50 1.1 christos uint16_t len; 51 1.1 christos /* the offset of the dname in the packet */ 52 1.1 christos uint16_t offset; 53 1.1 christos }; 54 1.1 christos 55 1.1 christos /* structure to store compression data for the packet */ 56 1.1 christos struct pktcompression { 57 1.1 christos /* rbtree of rrcompress_entry. sorted by dname */ 58 1.1 christos struct rbtree tree; 59 1.1 christos /* allocation information, how many bytes allocated now */ 60 1.1 christos size_t alloc_now; 61 1.1 christos /* allocation information, total size in block */ 62 1.1 christos size_t alloc_max; 63 1.1 christos /* region to use if block full, this is NULL if unused */ 64 1.1 christos struct region* region; 65 1.1 christos /* block of temp data for allocation */ 66 1.1 christos uint8_t block[sizeof(struct rrcompress_entry)*1024]; 67 1.1 christos }; 68 1.1 christos 69 1.1 christos /* compare two elements in the compression tree. Returns -1, 0, or 1. */ 70 1.1 christos static int compression_cmp(const void* a, const void* b) 71 1.1 christos { 72 1.1 christos struct rrcompress_entry* rra = (struct rrcompress_entry*)a; 73 1.1 christos struct rrcompress_entry* rrb = (struct rrcompress_entry*)b; 74 1.1 christos if(rra->len != rrb->len) { 75 1.1 christos if(rra->len < rrb->len) 76 1.1 christos return -1; 77 1.1 christos return 1; 78 1.1 christos } 79 1.1 christos return memcmp(rra->dname, rrb->dname, rra->len); 80 1.1 christos } 81 1.1 christos 82 1.1 christos /* init the pktcompression to a new packet */ 83 1.1 christos static void pktcompression_init(struct pktcompression* pcomp) 84 1.1 christos { 85 1.1 christos pcomp->alloc_now = 0; 86 1.1 christos pcomp->alloc_max = sizeof(pcomp->block); 87 1.1 christos pcomp->region = NULL; 88 1.1 christos pcomp->tree.root = RBTREE_NULL; 89 1.1 christos pcomp->tree.count = 0; 90 1.1 christos pcomp->tree.region = NULL; 91 1.1 christos pcomp->tree.cmp = &compression_cmp; 92 1.1 christos } 93 1.1 christos 94 1.1 christos /* freeup the pktcompression data */ 95 1.1 christos static void pktcompression_freeup(struct pktcompression* pcomp) 96 1.1 christos { 97 1.1 christos if(pcomp->region) { 98 1.1 christos region_destroy(pcomp->region); 99 1.1 christos pcomp->region = NULL; 100 1.1 christos } 101 1.1 christos pcomp->alloc_now = 0; 102 1.1 christos pcomp->tree.root = RBTREE_NULL; 103 1.1 christos pcomp->tree.count = 0; 104 1.1 christos } 105 1.1 christos 106 1.1 christos /* alloc data in pktcompression */ 107 1.1 christos static void* pktcompression_alloc(struct pktcompression* pcomp, size_t s) 108 1.1 christos { 109 1.1 christos /* first attempt to allocate in the fixed block, 110 1.1 christos * that is very fast and on the stack in the pcomp struct */ 111 1.1 christos if(pcomp->alloc_now + s <= pcomp->alloc_max) { 112 1.1 christos void* ret = pcomp->block + pcomp->alloc_now; 113 1.1 christos pcomp->alloc_now += s; 114 1.1 christos return ret; 115 1.1 christos } 116 1.1 christos 117 1.1 christos /* if that fails, create a region to allocate in, 118 1.1 christos * it is freed in the freeup */ 119 1.1 christos if(!pcomp->region) { 120 1.1 christos pcomp->region = region_create(xalloc, free); 121 1.1 christos if(!pcomp->region) 122 1.1 christos return NULL; 123 1.1 christos } 124 1.1 christos return region_alloc(pcomp->region, s); 125 1.1 christos } 126 1.1 christos 127 1.1 christos /* find a pktcompression name, return offset if found */ 128 1.1 christos static uint16_t pktcompression_find(struct pktcompression* pcomp, 129 1.1 christos const uint8_t* dname, size_t len) 130 1.1 christos { 131 1.1 christos struct rrcompress_entry key, *found; 132 1.1 christos key.node.key = &key; 133 1.1 christos key.dname = dname; 134 1.1 christos key.len = len; 135 1.1 christos found = (struct rrcompress_entry*)rbtree_search(&pcomp->tree, &key); 136 1.1 christos if(found) return found->offset; 137 1.1 christos return 0; 138 1.1 christos } 139 1.1 christos 140 1.1 christos /* insert a new domain name into the compression tree. 141 1.1 christos * it fails silently, no need to compress then. */ 142 1.1 christos static void pktcompression_insert(struct pktcompression* pcomp, 143 1.1 christos const uint8_t* dname, size_t len, uint16_t offset) 144 1.1 christos { 145 1.1 christos struct rrcompress_entry* entry; 146 1.1 christos if(len > 65535) 147 1.1 christos return; 148 1.1 christos if(offset > MAX_COMPRESSION_OFFSET) 149 1.1 christos return; /* too far for a compression pointer */ 150 1.1 christos entry = pktcompression_alloc(pcomp, sizeof(*entry)); 151 1.1 christos if(!entry) 152 1.1 christos return; 153 1.1 christos memset(&entry->node, 0, sizeof(entry->node)); 154 1.1 christos entry->node.key = entry; 155 1.1 christos entry->dname = dname; 156 1.1 christos entry->len = len; 157 1.1 christos entry->offset = offset; 158 1.1 christos (void)rbtree_insert(&pcomp->tree, &entry->node); 159 1.1 christos } 160 1.1 christos 161 1.1 christos /* insert all the labels of a domain name */ 162 1.1 christos static void pktcompression_insert_with_labels(struct pktcompression* pcomp, 163 1.1 christos uint8_t* dname, size_t len, uint16_t offset) 164 1.1 christos { 165 1.1 christos if(!dname) 166 1.1 christos return; 167 1.1 christos if(offset > MAX_COMPRESSION_OFFSET) 168 1.1 christos return; 169 1.1 christos 170 1.1 christos /* while we have not seen the end root label */ 171 1.1 christos while(len > 0 && dname[0] != 0) { 172 1.1 christos size_t lablen; 173 1.1 christos pktcompression_insert(pcomp, dname, len, offset); 174 1.1 christos lablen = (size_t)(dname[0]); 175 1.1 christos if( (lablen&0xc0) ) 176 1.1 christos return; /* the dname should be uncompressed */ 177 1.1 christos if(lablen+1 > len) 178 1.1 christos return; /* len should be uncompressed wireformat len */ 179 1.1 christos if(offset > MAX_COMPRESSION_OFFSET - lablen - 1) 180 1.1 christos return; /* offset moves too far for compression */ 181 1.1 christos /* skip label */ 182 1.1 christos len -= lablen+1; 183 1.1 christos dname += lablen+1; 184 1.1 christos offset += lablen+1; 185 1.1 christos } 186 1.1 christos } 187 1.1 christos 188 1.1 christos /* write a compressed domain name into the packet, 189 1.1 christos * returns uncompressed wireformat length, 190 1.1 christos * 0 if it does not fit and -1 on failure, bad dname. */ 191 1.1 christos static int pktcompression_write_dname(struct buffer* packet, 192 1.1 christos struct pktcompression* pcomp, const uint8_t* rr, size_t rrlen) 193 1.1 christos { 194 1.1 christos size_t wirelen = 0; 195 1.1.1.3 christos size_t dname_len = buf_dname_length(rr, rrlen); 196 1.1 christos if(!rr || rrlen == 0 || dname_len == 0) 197 1.1 christos return 0; 198 1.1 christos while(rrlen > 0 && rr[0] != 0) { 199 1.1 christos size_t lablen = (size_t)(rr[0]); 200 1.1 christos uint16_t offset; 201 1.1 christos if( (lablen&0xc0) ) 202 1.1 christos return -1; /* name should be uncompressed */ 203 1.1 christos if(lablen+1 > rrlen) 204 1.1 christos return -1; /* name should fit */ 205 1.1 christos 206 1.1 christos /* see if the domain name has a compression pointer */ 207 1.1 christos if((offset=pktcompression_find(pcomp, rr, dname_len))!=0) { 208 1.1 christos if(!buffer_available(packet, 2)) 209 1.1 christos return 0; 210 1.1 christos buffer_write_u16(packet, (uint16_t)(0xc000 | offset)); 211 1.1 christos wirelen += dname_len; 212 1.1 christos return wirelen; 213 1.1 christos } else { 214 1.1 christos if(!buffer_available(packet, lablen+1)) 215 1.1 christos return 0; 216 1.1 christos /* insert the domain name at this position */ 217 1.1 christos pktcompression_insert(pcomp, rr, dname_len, 218 1.1 christos buffer_position(packet)); 219 1.1 christos /* write it */ 220 1.1 christos buffer_write(packet, rr, lablen+1); 221 1.1 christos } 222 1.1 christos 223 1.1 christos wirelen += lablen+1; 224 1.1 christos rr += lablen+1; 225 1.1 christos rrlen -= lablen+1; 226 1.1 christos dname_len -= lablen+1; 227 1.1 christos } 228 1.1 christos if(rrlen > 0 && rr[0] == 0) { 229 1.1 christos /* write end root label */ 230 1.1 christos if(!buffer_available(packet, 1)) 231 1.1 christos return 0; 232 1.1 christos buffer_write_u8(packet, 0); 233 1.1 christos wirelen += 1; 234 1.1 christos } 235 1.1 christos return wirelen; 236 1.1 christos } 237 1.1 christos 238 1.1.1.3 christos static int ixfr_write_rdata_pkt(struct buffer* packet, uint16_t tp, 239 1.1.1.3 christos struct pktcompression* pcomp, const uint8_t* rr, size_t rdlen) 240 1.1.1.3 christos { 241 1.1.1.3 christos const struct nsd_type_descriptor* descriptor = nsd_type_descriptor(tp); 242 1.1.1.3 christos size_t i; 243 1.1.1.3 christos uint16_t offset; /* The offset in rr. */ 244 1.1.1.3 christos 245 1.1.1.3 christos /* The rr points at the start of the rdata of length rdlen. 246 1.1.1.3 christos * This is uncompressed wireformat. */ 247 1.1.1.3 christos 248 1.1.1.3 christos if(!descriptor->is_compressible) { 249 1.1.1.3 christos if(!buffer_available(packet, rdlen)) 250 1.1.1.3 christos return 0; 251 1.1.1.3 christos buffer_write(packet, rr, rdlen); 252 1.1.1.3 christos return 1; 253 1.1.1.3 christos } 254 1.1.1.3 christos 255 1.1.1.3 christos /* It is compressible, loop over the fields and write compressed 256 1.1.1.3 christos * domain names, when the rdata has a compressible name. */ 257 1.1.1.3 christos offset = 0; 258 1.1.1.3 christos for(i=0; i < descriptor->rdata.length; i++) { 259 1.1.1.3 christos const nsd_rdata_descriptor_type* field = 260 1.1.1.3 christos &descriptor->rdata.fields[i]; 261 1.1.1.3 christos uint16_t field_len = 0; 262 1.1.1.3 christos int already_written = 0; 263 1.1.1.3 christos if(rdlen == offset && field->is_optional) 264 1.1.1.3 christos break; /* There are no more rdata fields. */ 265 1.1.1.3 christos if(field->calculate_length_uncompressed_wire) { 266 1.1.1.3 christos /* Call field length function. */ 267 1.1.1.3 christos /* This is called with an uncompressed wireformat 268 1.1.1.3 christos * data buffer, instead of the in-memory data buffer. 269 1.1.1.3 christos * For IPSECKEY it does not matter, since it has 270 1.1.1.3 christos * a literal dname storage. */ 271 1.1.1.3 christos struct domain* domain; 272 1.1.1.3 christos int32_t l = field->calculate_length_uncompressed_wire( 273 1.1.1.3 christos rdlen, rr, offset, &domain); 274 1.1.1.3 christos if(l < 0) 275 1.1.1.3 christos return 1; /* attempt to skip malformed rr */ 276 1.1.1.3 christos field_len = l; 277 1.1.1.3 christos if(domain) { 278 1.1.1.3 christos /* Treat as uncompressed dname, to be safe. */ 279 1.1.1.3 christos /* Write as an uncompressed name. */ 280 1.1.1.3 christos if(!buffer_available(packet, 281 1.1.1.3 christos domain_dname(domain)->name_size)) 282 1.1.1.3 christos return 0; 283 1.1.1.3 christos buffer_write(packet, 284 1.1.1.3 christos dname_name(domain_dname(domain)), 285 1.1.1.3 christos domain_dname(domain)->name_size); 286 1.1.1.3 christos already_written = 1; 287 1.1.1.3 christos } 288 1.1.1.3 christos } else if(field->length >= 0) { 289 1.1.1.3 christos field_len = field->length; 290 1.1.1.3 christos } else { 291 1.1.1.3 christos size_t dlen; 292 1.1.1.3 christos int dname_len; 293 1.1.1.3 christos switch(field->length) { 294 1.1.1.3 christos /* The dnames are stored in uncompressed 295 1.1.1.3 christos * wireformat in the uncompressed wireformat 296 1.1.1.3 christos * string. */ 297 1.1.1.3 christos case RDATA_COMPRESSED_DNAME: 298 1.1.1.3 christos /* Attempt to compress the compressible 299 1.1.1.3 christos * name. */ 300 1.1.1.3 christos dname_len = pktcompression_write_dname(packet, 301 1.1.1.3 christos pcomp, rr+offset, rdlen-offset); 302 1.1.1.3 christos if(dname_len == -1) 303 1.1.1.3 christos return 1; /* attempt to skip malformed rr */ 304 1.1.1.3 christos if(dname_len == 0) 305 1.1.1.3 christos return 0; 306 1.1.1.3 christos field_len = dname_len; 307 1.1.1.3 christos already_written = 1; 308 1.1.1.3 christos break; 309 1.1.1.3 christos case RDATA_UNCOMPRESSED_DNAME: 310 1.1.1.3 christos case RDATA_LITERAL_DNAME: 311 1.1.1.3 christos /* Write as an uncompressed name. */ 312 1.1.1.3 christos if(rdlen-offset<1) 313 1.1.1.3 christos return 1; /* attempt to skip malformed rr */ 314 1.1.1.3 christos dlen = buf_dname_length(rr+offset, 315 1.1.1.3 christos rdlen-offset); 316 1.1.1.3 christos if(dlen == 0) 317 1.1.1.3 christos return 1; /* attempt to skip malformed rr */ 318 1.1.1.3 christos field_len = dlen; 319 1.1.1.3 christos break; 320 1.1.1.3 christos case RDATA_STRING: 321 1.1.1.3 christos case RDATA_BINARY: 322 1.1.1.3 christos if(rdlen-offset<1) 323 1.1.1.3 christos return 1; /* attempt to skip malformed rr */ 324 1.1.1.3 christos field_len = ((uint16_t)(rr+offset)[0]) + 1; 325 1.1.1.3 christos break; 326 1.1.1.3 christos case RDATA_IPSECGATEWAY: 327 1.1.1.3 christos case RDATA_AMTRELAY_RELAY: 328 1.1.1.3 christos /* This should have called the callback. */ 329 1.1.1.3 christos return 1; /* attempt to skip malformed rr */ 330 1.1.1.3 christos case RDATA_REMAINDER: 331 1.1.1.3 christos field_len = rdlen - offset; 332 1.1.1.3 christos break; 333 1.1.1.3 christos default: 334 1.1.1.3 christos /* Unknown specialized value. */ 335 1.1.1.3 christos return 1; /* attempt to skip malformed rr */ 336 1.1.1.3 christos } 337 1.1.1.3 christos } 338 1.1.1.3 christos if((size_t)offset+field_len > rdlen) 339 1.1.1.3 christos return 1; /* attempt to skip malformed rr */ 340 1.1.1.3 christos if(!already_written) { 341 1.1.1.3 christos if(!buffer_available(packet, field_len)) 342 1.1.1.3 christos return 0; 343 1.1.1.3 christos buffer_write(packet, rr+offset, field_len); 344 1.1.1.3 christos } 345 1.1.1.3 christos offset += field_len; 346 1.1.1.3 christos } 347 1.1.1.3 christos return 1; 348 1.1.1.3 christos } 349 1.1.1.3 christos 350 1.1 christos /* write an RR into the packet with compression for domain names, 351 1.1 christos * return 0 and resets position if it does not fit in the packet. */ 352 1.1 christos static int ixfr_write_rr_pkt(struct query* query, struct buffer* packet, 353 1.1.1.2 christos struct pktcompression* pcomp, const uint8_t* rr, size_t rrlen, 354 1.1.1.2 christos uint16_t total_added) 355 1.1 christos { 356 1.1 christos size_t oldpos = buffer_position(packet); 357 1.1 christos size_t rdpos; 358 1.1 christos uint16_t tp; 359 1.1 christos int dname_len; 360 1.1 christos size_t rdlen; 361 1.1 christos 362 1.1.1.2 christos if(total_added == 0) { 363 1.1.1.2 christos size_t oldmaxlen = query->maxlen; 364 1.1.1.2 christos /* RR > 16K can be first RR */ 365 1.1.1.2 christos query->maxlen = (query->tcp?TCP_MAX_MESSAGE_LEN:UDP_MAX_MESSAGE_LEN); 366 1.1.1.2 christos if(query_overflow(query)) { 367 1.1.1.2 christos query->maxlen = oldmaxlen; 368 1.1.1.2 christos return 0; 369 1.1.1.2 christos } 370 1.1.1.2 christos query->maxlen = oldmaxlen; 371 1.1.1.2 christos } else { 372 1.1.1.2 christos if(buffer_position(packet) > MAX_COMPRESSION_OFFSET 373 1.1.1.2 christos || query_overflow(query)) { 374 1.1.1.2 christos /* we are past the maximum length */ 375 1.1.1.2 christos return 0; 376 1.1.1.2 christos } 377 1.1 christos } 378 1.1 christos 379 1.1 christos /* write owner */ 380 1.1 christos dname_len = pktcompression_write_dname(packet, pcomp, rr, rrlen); 381 1.1 christos if(dname_len == -1) 382 1.1 christos return 1; /* attempt to skip this malformed rr, could assert */ 383 1.1 christos if(dname_len == 0) { 384 1.1 christos buffer_set_position(packet, oldpos); 385 1.1 christos return 0; 386 1.1 christos } 387 1.1 christos rr += dname_len; 388 1.1 christos rrlen -= dname_len; 389 1.1 christos 390 1.1 christos /* type, class, ttl, rdatalen */ 391 1.1 christos if(!buffer_available(packet, 10)) { 392 1.1 christos buffer_set_position(packet, oldpos); 393 1.1 christos return 0; 394 1.1 christos } 395 1.1 christos if(10 > rrlen) 396 1.1 christos return 1; /* attempt to skip this malformed rr, could assert */ 397 1.1 christos tp = read_uint16(rr); 398 1.1 christos buffer_write(packet, rr, 8); 399 1.1 christos rr += 8; 400 1.1 christos rrlen -= 8; 401 1.1 christos rdlen = read_uint16(rr); 402 1.1 christos rr += 2; 403 1.1 christos rrlen -= 2; 404 1.1 christos rdpos = buffer_position(packet); 405 1.1 christos buffer_write_u16(packet, 0); 406 1.1 christos if(rdlen > rrlen) 407 1.1 christos return 1; /* attempt to skip this malformed rr, could assert */ 408 1.1 christos 409 1.1 christos /* rdata */ 410 1.1.1.3 christos if(!ixfr_write_rdata_pkt(packet, tp, pcomp, rr, rdlen)) { 411 1.1.1.3 christos buffer_set_position(packet, oldpos); 412 1.1.1.3 christos return 0; 413 1.1 christos } 414 1.1.1.3 christos 415 1.1 christos /* write compressed rdata length */ 416 1.1 christos buffer_write_u16_at(packet, rdpos, buffer_position(packet)-rdpos-2); 417 1.1.1.2 christos if(total_added == 0) { 418 1.1.1.2 christos size_t oldmaxlen = query->maxlen; 419 1.1.1.2 christos query->maxlen = (query->tcp?TCP_MAX_MESSAGE_LEN:UDP_MAX_MESSAGE_LEN); 420 1.1.1.2 christos if(query_overflow(query)) { 421 1.1.1.2 christos query->maxlen = oldmaxlen; 422 1.1.1.2 christos buffer_set_position(packet, oldpos); 423 1.1.1.2 christos return 0; 424 1.1.1.2 christos } 425 1.1.1.2 christos query->maxlen = oldmaxlen; 426 1.1.1.2 christos } else { 427 1.1.1.2 christos if(query_overflow(query)) { 428 1.1.1.2 christos /* we are past the maximum length */ 429 1.1.1.2 christos buffer_set_position(packet, oldpos); 430 1.1.1.2 christos return 0; 431 1.1.1.2 christos } 432 1.1 christos } 433 1.1 christos return 1; 434 1.1 christos } 435 1.1 christos 436 1.1 christos /* parse the serial number from the IXFR query */ 437 1.1 christos static int parse_qserial(struct buffer* packet, uint32_t* qserial, 438 1.1 christos size_t* snip_pos) 439 1.1 christos { 440 1.1 christos unsigned int i; 441 1.1 christos uint16_t type, rdlen; 442 1.1 christos /* we must have a SOA in the authority section */ 443 1.1 christos if(NSCOUNT(packet) == 0) 444 1.1 christos return 0; 445 1.1 christos /* skip over the question section, we want only one */ 446 1.1 christos buffer_set_position(packet, QHEADERSZ); 447 1.1 christos if(QDCOUNT(packet) != 1) 448 1.1 christos return 0; 449 1.1 christos if(!packet_skip_rr(packet, 1)) 450 1.1 christos return 0; 451 1.1 christos /* set position to snip off the authority section */ 452 1.1 christos *snip_pos = buffer_position(packet); 453 1.1 christos /* skip over the authority section RRs until we find the SOA */ 454 1.1 christos for(i=0; i<NSCOUNT(packet); i++) { 455 1.1 christos /* is this the SOA record? */ 456 1.1 christos if(!packet_skip_dname(packet)) 457 1.1 christos return 0; /* malformed name */ 458 1.1 christos if(!buffer_available(packet, 10)) 459 1.1 christos return 0; /* no type,class,ttl,rdatalen */ 460 1.1 christos type = buffer_read_u16(packet); 461 1.1 christos buffer_skip(packet, 6); 462 1.1 christos rdlen = buffer_read_u16(packet); 463 1.1 christos if(!buffer_available(packet, rdlen)) 464 1.1 christos return 0; 465 1.1 christos if(type == TYPE_SOA) { 466 1.1 christos /* read serial from rdata, skip two dnames, then 467 1.1 christos * read the 32bit value */ 468 1.1 christos if(!packet_skip_dname(packet)) 469 1.1 christos return 0; /* malformed nsname */ 470 1.1 christos if(!packet_skip_dname(packet)) 471 1.1 christos return 0; /* malformed rname */ 472 1.1 christos if(!buffer_available(packet, 4)) 473 1.1 christos return 0; 474 1.1 christos *qserial = buffer_read_u32(packet); 475 1.1 christos return 1; 476 1.1 christos } 477 1.1 christos buffer_skip(packet, rdlen); 478 1.1 christos } 479 1.1 christos return 0; 480 1.1 christos } 481 1.1 christos 482 1.1.1.3 christos /* get serial from SOA rdata */ 483 1.1.1.3 christos static uint32_t soa_rdata_get_serial(uint8_t* rdata, uint16_t rdlength) 484 1.1.1.3 christos { 485 1.1.1.3 christos if(rdlength < 2*sizeof(void*) /* name ptr */ + 4 /* serial */) 486 1.1.1.3 christos return 0; 487 1.1.1.3 christos return read_uint32(rdata+2*sizeof(void*)); 488 1.1.1.3 christos } 489 1.1.1.3 christos 490 1.1 christos /* get serial from SOA RR */ 491 1.1 christos static uint32_t soa_rr_get_serial(struct rr* rr) 492 1.1 christos { 493 1.1.1.3 christos return soa_rdata_get_serial(rr->rdata, rr->rdlength); 494 1.1 christos } 495 1.1 christos 496 1.1 christos /* get the current serial from the zone */ 497 1.1 christos uint32_t zone_get_current_serial(struct zone* zone) 498 1.1 christos { 499 1.1 christos if(!zone || !zone->soa_rrset) 500 1.1 christos return 0; 501 1.1 christos if(zone->soa_rrset->rr_count == 0) 502 1.1 christos return 0; 503 1.1.1.3 christos return soa_rr_get_serial(zone->soa_rrset->rrs[0]); 504 1.1 christos } 505 1.1 christos 506 1.1 christos /* iterator over ixfr data. find first element, eg. oldest zone version 507 1.1 christos * change. 508 1.1 christos * The iterator can be started with the ixfr_data_first, but also with 509 1.1 christos * ixfr_data_last, or with an existing ixfr_data element to start from. 510 1.1 christos * Continue by using ixfr_data_next or ixfr_data_prev to ask for more elements 511 1.1 christos * until that returns NULL. NULL because end of list or loop was detected. 512 1.1 christos * The ixfr_data_prev uses a counter, start it at 0, it returns NULL when 513 1.1 christos * a loop is detected. 514 1.1 christos */ 515 1.1 christos static struct ixfr_data* ixfr_data_first(struct zone_ixfr* ixfr) 516 1.1 christos { 517 1.1 christos struct ixfr_data* n; 518 1.1 christos if(!ixfr || !ixfr->data || ixfr->data->count==0) 519 1.1 christos return NULL; 520 1.1 christos n = (struct ixfr_data*)rbtree_search(ixfr->data, &ixfr->oldest_serial); 521 1.1 christos if(!n || n == (struct ixfr_data*)RBTREE_NULL) 522 1.1 christos return NULL; 523 1.1 christos return n; 524 1.1 christos } 525 1.1 christos 526 1.1 christos /* iterator over ixfr data. find last element, eg. newest zone version 527 1.1 christos * change. */ 528 1.1 christos static struct ixfr_data* ixfr_data_last(struct zone_ixfr* ixfr) 529 1.1 christos { 530 1.1 christos struct ixfr_data* n; 531 1.1 christos if(!ixfr || !ixfr->data || ixfr->data->count==0) 532 1.1 christos return NULL; 533 1.1 christos n = (struct ixfr_data*)rbtree_search(ixfr->data, &ixfr->newest_serial); 534 1.1 christos if(!n || n == (struct ixfr_data*)RBTREE_NULL) 535 1.1 christos return NULL; 536 1.1 christos return n; 537 1.1 christos } 538 1.1 christos 539 1.1 christos /* iterator over ixfr data. fetch next item. If loop or nothing, NULL */ 540 1.1 christos static struct ixfr_data* ixfr_data_next(struct zone_ixfr* ixfr, 541 1.1 christos struct ixfr_data* cur) 542 1.1 christos { 543 1.1 christos struct ixfr_data* n; 544 1.1 christos if(!cur || cur == (struct ixfr_data*)RBTREE_NULL) 545 1.1 christos return NULL; 546 1.1 christos if(cur->oldserial == ixfr->newest_serial) 547 1.1 christos return NULL; /* that was the last element */ 548 1.1 christos n = (struct ixfr_data*)rbtree_next(&cur->node); 549 1.1 christos if(n && n != (struct ixfr_data*)RBTREE_NULL && 550 1.1 christos cur->newserial == n->oldserial) { 551 1.1 christos /* the next rbtree item is the next ixfr data item */ 552 1.1 christos return n; 553 1.1 christos } 554 1.1 christos /* If the next item is last of tree, and we have to loop around, 555 1.1 christos * the search performs the lookup for the next item we need. 556 1.1 christos * If the next item exists, but also is not connected, the search 557 1.1 christos * finds the correct connected ixfr in the sorted tree. */ 558 1.1 christos /* try searching for the correct ixfr data item */ 559 1.1 christos n = (struct ixfr_data*)rbtree_search(ixfr->data, &cur->newserial); 560 1.1 christos if(!n || n == (struct ixfr_data*)RBTREE_NULL) 561 1.1 christos return NULL; 562 1.1 christos return n; 563 1.1 christos } 564 1.1 christos 565 1.1 christos /* iterator over ixfr data. fetch the previous item. If loop or nothing NULL.*/ 566 1.1 christos static struct ixfr_data* ixfr_data_prev(struct zone_ixfr* ixfr, 567 1.1 christos struct ixfr_data* cur, size_t* prevcount) 568 1.1 christos { 569 1.1 christos struct ixfr_data* prev; 570 1.1 christos if(!cur || cur == (struct ixfr_data*)RBTREE_NULL) 571 1.1 christos return NULL; 572 1.1 christos if(cur->oldserial == ixfr->oldest_serial) 573 1.1 christos return NULL; /* this was the first element */ 574 1.1 christos prev = (struct ixfr_data*)rbtree_previous(&cur->node); 575 1.1 christos if(!prev || prev == (struct ixfr_data*)RBTREE_NULL) { 576 1.1 christos /* We hit the first element in the tree, go again 577 1.1 christos * at the last one. Wrap around. */ 578 1.1 christos prev = (struct ixfr_data*)rbtree_last(ixfr->data); 579 1.1 christos } 580 1.1 christos while(prev && prev != (struct ixfr_data*)RBTREE_NULL) { 581 1.1 christos if(prev->newserial == cur->oldserial) { 582 1.1 christos /* This is the correct matching previous ixfr data */ 583 1.1 christos /* Increase the prevcounter every time the routine 584 1.1 christos * returns an item, and if that becomes too large, we 585 1.1 christos * are in a loop. in that case, stop. */ 586 1.1 christos if(prevcount) { 587 1.1 christos (*prevcount)++; 588 1.1 christos if(*prevcount > ixfr->data->count + 12) { 589 1.1 christos /* Larger than the max number of items 590 1.1 christos * plus a small margin. The longest 591 1.1 christos * chain is all the ixfr elements in 592 1.1 christos * the tree. It loops. */ 593 1.1 christos return NULL; 594 1.1 christos } 595 1.1 christos } 596 1.1 christos return prev; 597 1.1 christos } 598 1.1 christos prev = (struct ixfr_data*)rbtree_previous(&prev->node); 599 1.1 christos if(!prev || prev == (struct ixfr_data*)RBTREE_NULL) { 600 1.1 christos /* We hit the first element in the tree, go again 601 1.1 christos * at the last one. Wrap around. */ 602 1.1 christos prev = (struct ixfr_data*)rbtree_last(ixfr->data); 603 1.1 christos } 604 1.1 christos } 605 1.1 christos /* no elements in list */ 606 1.1 christos return NULL; 607 1.1 christos } 608 1.1 christos 609 1.1 christos /* connect IXFRs, return true if connected, false if not. Return last serial */ 610 1.1 christos static int connect_ixfrs(struct zone_ixfr* ixfr, struct ixfr_data* data, 611 1.1 christos uint32_t* end_serial) 612 1.1 christos { 613 1.1 christos struct ixfr_data* p = data; 614 1.1 christos while(p != NULL) { 615 1.1 christos struct ixfr_data* next = ixfr_data_next(ixfr, p); 616 1.1 christos if(next) { 617 1.1 christos if(p->newserial != next->oldserial) { 618 1.1 christos /* These ixfrs are not connected, 619 1.1 christos * during IXFR processing that could already 620 1.1 christos * have been deleted, but we check here 621 1.1 christos * in any case */ 622 1.1 christos return 0; 623 1.1 christos } 624 1.1 christos } else { 625 1.1 christos /* the chain of IXFRs ends in this serial number */ 626 1.1 christos *end_serial = p->newserial; 627 1.1 christos } 628 1.1 christos p = next; 629 1.1 christos } 630 1.1 christos return 1; 631 1.1 christos } 632 1.1 christos 633 1.1 christos /* Count length of next record in data */ 634 1.1 christos static size_t count_rr_length(const uint8_t* data, size_t data_len, 635 1.1 christos size_t current) 636 1.1 christos { 637 1.1 christos uint8_t label_size; 638 1.1 christos uint16_t rdlen; 639 1.1 christos size_t i = current; 640 1.1 christos if(current >= data_len) 641 1.1 christos return 0; 642 1.1 christos /* pass the owner dname */ 643 1.1 christos while(1) { 644 1.1 christos if(i+1 > data_len) 645 1.1 christos return 0; 646 1.1 christos label_size = data[i++]; 647 1.1 christos if(label_size == 0) { 648 1.1 christos break; 649 1.1 christos } else if((label_size &0xc0) != 0) { 650 1.1 christos return 0; /* uncompressed dnames in IXFR store */ 651 1.1 christos } else if(i+label_size > data_len) { 652 1.1 christos return 0; 653 1.1 christos } else { 654 1.1 christos i += label_size; 655 1.1 christos } 656 1.1 christos } 657 1.1 christos /* after dname, we pass type, class, ttl, rdatalen */ 658 1.1 christos if(i+10 > data_len) 659 1.1 christos return 0; 660 1.1 christos i += 8; 661 1.1 christos rdlen = read_uint16(data+i); 662 1.1 christos i += 2; 663 1.1 christos /* pass over the rdata */ 664 1.1 christos if(i+((size_t)rdlen) > data_len) 665 1.1 christos return 0; 666 1.1 christos i += ((size_t)rdlen); 667 1.1 christos return i-current; 668 1.1 christos } 669 1.1 christos 670 1.1 christos /* Copy RRs into packet until packet full, return number RRs added */ 671 1.1 christos static uint16_t ixfr_copy_rrs_into_packet(struct query* query, 672 1.1 christos struct pktcompression* pcomp) 673 1.1 christos { 674 1.1 christos uint16_t total_added = 0; 675 1.1 christos 676 1.1 christos /* Copy RRs into the packet until the answer is full, 677 1.1 christos * when an RR does not fit, we return and add no more. */ 678 1.1 christos 679 1.1 christos /* Add first SOA */ 680 1.1 christos if(query->ixfr_count_newsoa < query->ixfr_end_data->newsoa_len) { 681 1.1 christos /* the new SOA is added from the end_data segment, it is 682 1.1 christos * the final SOA of the result of the IXFR */ 683 1.1 christos if(ixfr_write_rr_pkt(query, query->packet, pcomp, 684 1.1 christos query->ixfr_end_data->newsoa, 685 1.1.1.2 christos query->ixfr_end_data->newsoa_len, total_added)) { 686 1.1 christos query->ixfr_count_newsoa = query->ixfr_end_data->newsoa_len; 687 1.1 christos total_added++; 688 1.1 christos query->ixfr_pos_of_newsoa = buffer_position(query->packet); 689 1.1 christos } else { 690 1.1 christos /* cannot add another RR, so return */ 691 1.1 christos return total_added; 692 1.1 christos } 693 1.1 christos } 694 1.1 christos 695 1.1 christos /* Add second SOA */ 696 1.1 christos if(query->ixfr_count_oldsoa < query->ixfr_data->oldsoa_len) { 697 1.1 christos if(ixfr_write_rr_pkt(query, query->packet, pcomp, 698 1.1 christos query->ixfr_data->oldsoa, 699 1.1.1.2 christos query->ixfr_data->oldsoa_len, total_added)) { 700 1.1 christos query->ixfr_count_oldsoa = query->ixfr_data->oldsoa_len; 701 1.1 christos total_added++; 702 1.1 christos } else { 703 1.1 christos /* cannot add another RR, so return */ 704 1.1 christos return total_added; 705 1.1 christos } 706 1.1 christos } 707 1.1 christos 708 1.1 christos /* Add del data, with deleted RRs and a SOA */ 709 1.1 christos while(query->ixfr_count_del < query->ixfr_data->del_len) { 710 1.1 christos size_t rrlen = count_rr_length(query->ixfr_data->del, 711 1.1 christos query->ixfr_data->del_len, query->ixfr_count_del); 712 1.1 christos if(rrlen && ixfr_write_rr_pkt(query, query->packet, pcomp, 713 1.1 christos query->ixfr_data->del + query->ixfr_count_del, 714 1.1.1.2 christos rrlen, total_added)) { 715 1.1 christos query->ixfr_count_del += rrlen; 716 1.1 christos total_added++; 717 1.1 christos } else { 718 1.1 christos /* the next record does not fit in the remaining 719 1.1 christos * space of the packet */ 720 1.1 christos return total_added; 721 1.1 christos } 722 1.1 christos } 723 1.1 christos 724 1.1 christos /* Add add data, with added RRs and a SOA */ 725 1.1 christos while(query->ixfr_count_add < query->ixfr_data->add_len) { 726 1.1 christos size_t rrlen = count_rr_length(query->ixfr_data->add, 727 1.1 christos query->ixfr_data->add_len, query->ixfr_count_add); 728 1.1 christos if(rrlen && ixfr_write_rr_pkt(query, query->packet, pcomp, 729 1.1 christos query->ixfr_data->add + query->ixfr_count_add, 730 1.1.1.2 christos rrlen, total_added)) { 731 1.1 christos query->ixfr_count_add += rrlen; 732 1.1 christos total_added++; 733 1.1 christos } else { 734 1.1 christos /* the next record does not fit in the remaining 735 1.1 christos * space of the packet */ 736 1.1 christos return total_added; 737 1.1 christos } 738 1.1 christos } 739 1.1 christos return total_added; 740 1.1 christos } 741 1.1 christos 742 1.1 christos query_state_type query_ixfr(struct nsd *nsd, struct query *query) 743 1.1 christos { 744 1.1 christos uint16_t total_added = 0; 745 1.1 christos struct pktcompression pcomp; 746 1.1 christos 747 1.1 christos if (query->ixfr_is_done) 748 1.1 christos return QUERY_PROCESSED; 749 1.1 christos 750 1.1 christos pktcompression_init(&pcomp); 751 1.1 christos if (query->maxlen > IXFR_MAX_MESSAGE_LEN) 752 1.1 christos query->maxlen = IXFR_MAX_MESSAGE_LEN; 753 1.1 christos 754 1.1 christos assert(!query_overflow(query)); 755 1.1 christos /* only keep running values for most packets */ 756 1.1 christos query->tsig_prepare_it = 0; 757 1.1 christos query->tsig_update_it = 1; 758 1.1 christos if(query->tsig_sign_it) { 759 1.1 christos /* prepare for next updates */ 760 1.1 christos query->tsig_prepare_it = 1; 761 1.1 christos query->tsig_sign_it = 0; 762 1.1 christos } 763 1.1 christos 764 1.1 christos if (query->ixfr_data == NULL) { 765 1.1 christos /* This is the first packet, process the query further */ 766 1.1 christos uint32_t qserial = 0, current_serial = 0, end_serial = 0; 767 1.1 christos struct zone* zone; 768 1.1 christos struct ixfr_data* ixfr_data; 769 1.1 christos size_t oldpos; 770 1.1 christos 771 1.1 christos STATUP(nsd, rixfr); 772 1.1 christos /* parse the serial number from the IXFR request */ 773 1.1 christos oldpos = QHEADERSZ; 774 1.1 christos if(!parse_qserial(query->packet, &qserial, &oldpos)) { 775 1.1 christos NSCOUNT_SET(query->packet, 0); 776 1.1 christos ARCOUNT_SET(query->packet, 0); 777 1.1 christos buffer_set_position(query->packet, oldpos); 778 1.1 christos RCODE_SET(query->packet, RCODE_FORMAT); 779 1.1 christos return QUERY_PROCESSED; 780 1.1 christos } 781 1.1 christos NSCOUNT_SET(query->packet, 0); 782 1.1 christos ARCOUNT_SET(query->packet, 0); 783 1.1 christos buffer_set_position(query->packet, oldpos); 784 1.1 christos DEBUG(DEBUG_XFRD,1, (LOG_INFO, "ixfr query routine, %s IXFR=%u", 785 1.1 christos dname_to_string(query->qname, NULL), (unsigned)qserial)); 786 1.1 christos 787 1.1 christos /* do we have an IXFR with this serial number? If not, serve AXFR */ 788 1.1 christos zone = namedb_find_zone(nsd->db, query->qname); 789 1.1 christos if(!zone) { 790 1.1 christos /* no zone is present */ 791 1.1 christos RCODE_SET(query->packet, RCODE_NOTAUTH); 792 1.1 christos return QUERY_PROCESSED; 793 1.1 christos } 794 1.1 christos ZTATUP(nsd, zone, rixfr); 795 1.1 christos 796 1.1 christos /* if the query is for same or newer serial than our current 797 1.1 christos * serial, then serve a single SOA with our current serial */ 798 1.1 christos current_serial = zone_get_current_serial(zone); 799 1.1 christos if(compare_serial(qserial, current_serial) >= 0) { 800 1.1 christos if(!zone->soa_rrset || zone->soa_rrset->rr_count != 1){ 801 1.1 christos RCODE_SET(query->packet, RCODE_SERVFAIL); 802 1.1 christos return QUERY_PROCESSED; 803 1.1 christos } 804 1.1 christos query_add_compression_domain(query, zone->apex, 805 1.1 christos QHEADERSZ); 806 1.1 christos if(packet_encode_rr(query, zone->apex, 807 1.1.1.3 christos zone->soa_rrset->rrs[0], 808 1.1.1.3 christos zone->soa_rrset->rrs[0]->ttl)) { 809 1.1 christos ANCOUNT_SET(query->packet, 1); 810 1.1 christos } else { 811 1.1 christos RCODE_SET(query->packet, RCODE_SERVFAIL); 812 1.1 christos } 813 1.1 christos AA_SET(query->packet); 814 1.1 christos query_clear_compression_tables(query); 815 1.1 christos if(query->tsig.status == TSIG_OK) 816 1.1 christos query->tsig_sign_it = 1; 817 1.1 christos return QUERY_PROCESSED; 818 1.1 christos } 819 1.1 christos 820 1.1 christos if(!zone->ixfr) { 821 1.1 christos /* we have no ixfr information for the zone, make an AXFR */ 822 1.1 christos if(query->tsig_prepare_it) 823 1.1 christos query->tsig_sign_it = 1; 824 1.1.1.2 christos VERBOSITY(2, (LOG_INFO, "ixfr fallback to axfr, no ixfr info for zone: %s", 825 1.1.1.2 christos dname_to_string(query->qname, NULL))); 826 1.1 christos return query_axfr(nsd, query, 0); 827 1.1 christos } 828 1.1 christos ixfr_data = zone_ixfr_find_serial(zone->ixfr, qserial); 829 1.1 christos if(!ixfr_data) { 830 1.1 christos /* the specific version is not available, make an AXFR */ 831 1.1 christos if(query->tsig_prepare_it) 832 1.1 christos query->tsig_sign_it = 1; 833 1.1.1.2 christos VERBOSITY(2, (LOG_INFO, "ixfr fallback to axfr, no history for serial for zone: %s", 834 1.1.1.2 christos dname_to_string(query->qname, NULL))); 835 1.1 christos return query_axfr(nsd, query, 0); 836 1.1 christos } 837 1.1 christos /* see if the IXFRs connect to the next IXFR, and if it ends 838 1.1 christos * at the current served zone, if not, AXFR */ 839 1.1 christos if(!connect_ixfrs(zone->ixfr, ixfr_data, &end_serial) || 840 1.1 christos end_serial != current_serial) { 841 1.1 christos if(query->tsig_prepare_it) 842 1.1 christos query->tsig_sign_it = 1; 843 1.1.1.2 christos VERBOSITY(2, (LOG_INFO, "ixfr fallback to axfr, incomplete history from this serial for zone: %s", 844 1.1.1.2 christos dname_to_string(query->qname, NULL))); 845 1.1 christos return query_axfr(nsd, query, 0); 846 1.1 christos } 847 1.1 christos 848 1.1 christos query->zone = zone; 849 1.1 christos query->ixfr_data = ixfr_data; 850 1.1 christos query->ixfr_is_done = 0; 851 1.1 christos /* set up to copy the last version's SOA as first SOA */ 852 1.1 christos query->ixfr_end_data = ixfr_data_last(zone->ixfr); 853 1.1 christos query->ixfr_count_newsoa = 0; 854 1.1 christos query->ixfr_count_oldsoa = 0; 855 1.1 christos query->ixfr_count_del = 0; 856 1.1 christos query->ixfr_count_add = 0; 857 1.1 christos query->ixfr_pos_of_newsoa = 0; 858 1.1 christos /* the query name can be compressed to */ 859 1.1 christos pktcompression_insert_with_labels(&pcomp, 860 1.1 christos buffer_at(query->packet, QHEADERSZ), 861 1.1 christos query->qname->name_size, QHEADERSZ); 862 1.1 christos if(query->tsig.status == TSIG_OK) { 863 1.1 christos query->tsig_sign_it = 1; /* sign first packet in stream */ 864 1.1 christos } 865 1.1 christos } else { 866 1.1 christos /* 867 1.1 christos * Query name need not be repeated after the 868 1.1 christos * first response packet. 869 1.1 christos */ 870 1.1 christos buffer_set_limit(query->packet, QHEADERSZ); 871 1.1 christos QDCOUNT_SET(query->packet, 0); 872 1.1 christos query_prepare_response(query); 873 1.1 christos } 874 1.1 christos 875 1.1 christos total_added = ixfr_copy_rrs_into_packet(query, &pcomp); 876 1.1 christos 877 1.1 christos while(query->ixfr_count_add >= query->ixfr_data->add_len) { 878 1.1 christos struct ixfr_data* next = ixfr_data_next(query->zone->ixfr, 879 1.1 christos query->ixfr_data); 880 1.1 christos /* finished the ixfr_data */ 881 1.1 christos if(next) { 882 1.1 christos /* move to the next IXFR */ 883 1.1 christos query->ixfr_data = next; 884 1.1 christos /* we need to skip the SOA records, set len to done*/ 885 1.1 christos /* the newsoa count is already done, at end_data len */ 886 1.1 christos query->ixfr_count_oldsoa = next->oldsoa_len; 887 1.1 christos /* and then set up to copy the del and add sections */ 888 1.1 christos query->ixfr_count_del = 0; 889 1.1 christos query->ixfr_count_add = 0; 890 1.1 christos total_added += ixfr_copy_rrs_into_packet(query, &pcomp); 891 1.1 christos } else { 892 1.1 christos /* we finished the IXFR */ 893 1.1 christos /* sign the last packet */ 894 1.1 christos query->tsig_sign_it = 1; 895 1.1 christos query->ixfr_is_done = 1; 896 1.1 christos break; 897 1.1 christos } 898 1.1 christos } 899 1.1 christos 900 1.1 christos /* return the answer */ 901 1.1 christos AA_SET(query->packet); 902 1.1 christos ANCOUNT_SET(query->packet, total_added); 903 1.1 christos NSCOUNT_SET(query->packet, 0); 904 1.1 christos ARCOUNT_SET(query->packet, 0); 905 1.1 christos 906 1.1 christos if(!query->tcp && !query->ixfr_is_done) { 907 1.1 christos TC_SET(query->packet); 908 1.1 christos if(query->ixfr_pos_of_newsoa) { 909 1.1 christos /* if we recorded the newsoa in the result, snip off 910 1.1 christos * the rest of the response, the RFC1995 response for 911 1.1 christos * when it does not fit is only the latest SOA */ 912 1.1 christos buffer_set_position(query->packet, query->ixfr_pos_of_newsoa); 913 1.1 christos ANCOUNT_SET(query->packet, 1); 914 1.1 christos } 915 1.1 christos query->ixfr_is_done = 1; 916 1.1 christos } 917 1.1 christos 918 1.1 christos /* check if it needs tsig signatures */ 919 1.1 christos if(query->tsig.status == TSIG_OK) { 920 1.1 christos #if IXFR_TSIG_SIGN_EVERY_NTH > 0 921 1.1 christos if(query->tsig.updates_since_last_prepare >= IXFR_TSIG_SIGN_EVERY_NTH) { 922 1.1 christos #endif 923 1.1 christos query->tsig_sign_it = 1; 924 1.1 christos #if IXFR_TSIG_SIGN_EVERY_NTH > 0 925 1.1 christos } 926 1.1 christos #endif 927 1.1 christos } 928 1.1 christos pktcompression_freeup(&pcomp); 929 1.1 christos return QUERY_IN_IXFR; 930 1.1 christos } 931 1.1 christos 932 1.1 christos /* free ixfr_data structure */ 933 1.1 christos static void ixfr_data_free(struct ixfr_data* data) 934 1.1 christos { 935 1.1 christos if(!data) 936 1.1 christos return; 937 1.1 christos free(data->newsoa); 938 1.1 christos free(data->oldsoa); 939 1.1 christos free(data->del); 940 1.1 christos free(data->add); 941 1.1 christos free(data->log_str); 942 1.1 christos free(data); 943 1.1 christos } 944 1.1 christos 945 1.1 christos size_t ixfr_data_size(struct ixfr_data* data) 946 1.1 christos { 947 1.1 christos return sizeof(struct ixfr_data) + data->newsoa_len + data->oldsoa_len 948 1.1 christos + data->del_len + data->add_len; 949 1.1 christos } 950 1.1 christos 951 1.1 christos struct ixfr_store* ixfr_store_start(struct zone* zone, 952 1.1.1.2 christos struct ixfr_store* ixfr_store_mem) 953 1.1 christos { 954 1.1 christos struct ixfr_store* ixfr_store = ixfr_store_mem; 955 1.1 christos memset(ixfr_store, 0, sizeof(*ixfr_store)); 956 1.1 christos ixfr_store->zone = zone; 957 1.1 christos ixfr_store->data = xalloc_zero(sizeof(*ixfr_store->data)); 958 1.1 christos return ixfr_store; 959 1.1 christos } 960 1.1 christos 961 1.1 christos void ixfr_store_cancel(struct ixfr_store* ixfr_store) 962 1.1 christos { 963 1.1 christos ixfr_store->cancelled = 1; 964 1.1 christos ixfr_data_free(ixfr_store->data); 965 1.1 christos ixfr_store->data = NULL; 966 1.1 christos } 967 1.1 christos 968 1.1 christos void ixfr_store_free(struct ixfr_store* ixfr_store) 969 1.1 christos { 970 1.1 christos if(!ixfr_store) 971 1.1 christos return; 972 1.1 christos ixfr_data_free(ixfr_store->data); 973 1.1 christos } 974 1.1 christos 975 1.1 christos /* make space in record data for the new size, grows the allocation */ 976 1.1 christos static void ixfr_rrs_make_space(uint8_t** rrs, size_t* len, size_t* capacity, 977 1.1 christos size_t added) 978 1.1 christos { 979 1.1 christos size_t newsize = 0; 980 1.1 christos if(*rrs == NULL) { 981 1.1 christos newsize = IXFR_STORE_INITIAL_SIZE; 982 1.1 christos } else { 983 1.1 christos if(*len + added <= *capacity) 984 1.1 christos return; /* already enough space */ 985 1.1 christos newsize = (*capacity)*2; 986 1.1 christos } 987 1.1 christos if(*len + added > newsize) 988 1.1 christos newsize = *len + added; 989 1.1 christos if(*rrs == NULL) { 990 1.1 christos *rrs = xalloc(newsize); 991 1.1 christos } else { 992 1.1 christos *rrs = xrealloc(*rrs, newsize); 993 1.1 christos } 994 1.1 christos *capacity = newsize; 995 1.1 christos } 996 1.1 christos 997 1.1 christos /* put new SOA record after delrrs and addrrs */ 998 1.1 christos static void ixfr_put_newsoa(struct ixfr_store* ixfr_store, uint8_t** rrs, 999 1.1 christos size_t* len, size_t* capacity) 1000 1.1 christos { 1001 1.1 christos uint8_t* soa; 1002 1.1 christos size_t soa_len; 1003 1.1 christos if(!ixfr_store->data) 1004 1.1 christos return; /* data should be nonNULL, we are not cancelled */ 1005 1.1 christos soa = ixfr_store->data->newsoa; 1006 1.1 christos soa_len= ixfr_store->data->newsoa_len; 1007 1.1 christos ixfr_rrs_make_space(rrs, len, capacity, soa_len); 1008 1.1 christos if(!*rrs || *len + soa_len > *capacity) { 1009 1.1 christos log_msg(LOG_ERR, "ixfr_store addrr: cannot allocate space"); 1010 1.1 christos ixfr_store_cancel(ixfr_store); 1011 1.1 christos return; 1012 1.1 christos } 1013 1.1 christos memmove(*rrs + *len, soa, soa_len); 1014 1.1 christos *len += soa_len; 1015 1.1 christos } 1016 1.1 christos 1017 1.1 christos /* trim unused storage from the rrs data */ 1018 1.1 christos static void ixfr_trim_capacity(uint8_t** rrs, size_t* len, size_t* capacity) 1019 1.1 christos { 1020 1.1 christos if(*rrs == NULL) 1021 1.1 christos return; 1022 1.1 christos if(*capacity == *len) 1023 1.1 christos return; 1024 1.1 christos *rrs = xrealloc(*rrs, *len); 1025 1.1 christos *capacity = *len; 1026 1.1 christos } 1027 1.1 christos 1028 1.1 christos void ixfr_store_finish_data(struct ixfr_store* ixfr_store) 1029 1.1 christos { 1030 1.1 christos if(ixfr_store->data_trimmed) 1031 1.1 christos return; 1032 1.1 christos ixfr_store->data_trimmed = 1; 1033 1.1 christos 1034 1.1 christos /* put new serial SOA record after delrrs and addrrs */ 1035 1.1 christos ixfr_put_newsoa(ixfr_store, &ixfr_store->data->del, 1036 1.1 christos &ixfr_store->data->del_len, &ixfr_store->del_capacity); 1037 1.1 christos ixfr_put_newsoa(ixfr_store, &ixfr_store->data->add, 1038 1.1 christos &ixfr_store->data->add_len, &ixfr_store->add_capacity); 1039 1.1 christos 1040 1.1 christos /* trim the data in the store, the overhead from capacity is 1041 1.1 christos * removed */ 1042 1.1 christos if(!ixfr_store->data) 1043 1.1 christos return; /* data should be nonNULL, we are not cancelled */ 1044 1.1 christos ixfr_trim_capacity(&ixfr_store->data->del, 1045 1.1 christos &ixfr_store->data->del_len, &ixfr_store->del_capacity); 1046 1.1 christos ixfr_trim_capacity(&ixfr_store->data->add, 1047 1.1 christos &ixfr_store->data->add_len, &ixfr_store->add_capacity); 1048 1.1 christos } 1049 1.1 christos 1050 1.1 christos void ixfr_store_finish(struct ixfr_store* ixfr_store, struct nsd* nsd, 1051 1.1 christos char* log_buf) 1052 1.1 christos { 1053 1.1 christos if(ixfr_store->cancelled) { 1054 1.1 christos ixfr_store_free(ixfr_store); 1055 1.1 christos return; 1056 1.1 christos } 1057 1.1 christos 1058 1.1 christos ixfr_store_finish_data(ixfr_store); 1059 1.1 christos 1060 1.1 christos if(ixfr_store->cancelled) { 1061 1.1 christos ixfr_store_free(ixfr_store); 1062 1.1 christos return; 1063 1.1 christos } 1064 1.1 christos 1065 1.1 christos if(log_buf && !ixfr_store->data->log_str) 1066 1.1 christos ixfr_store->data->log_str = strdup(log_buf); 1067 1.1 christos 1068 1.1 christos /* store the data in the zone */ 1069 1.1 christos if(!ixfr_store->zone->ixfr) 1070 1.1 christos ixfr_store->zone->ixfr = zone_ixfr_create(nsd); 1071 1.1 christos zone_ixfr_make_space(ixfr_store->zone->ixfr, ixfr_store->zone, 1072 1.1 christos ixfr_store->data, ixfr_store); 1073 1.1 christos if(ixfr_store->cancelled) { 1074 1.1 christos ixfr_store_free(ixfr_store); 1075 1.1 christos return; 1076 1.1 christos } 1077 1.1 christos zone_ixfr_add(ixfr_store->zone->ixfr, ixfr_store->data, 1); 1078 1.1 christos ixfr_store->data = NULL; 1079 1.1 christos 1080 1.1 christos /* free structure */ 1081 1.1 christos ixfr_store_free(ixfr_store); 1082 1.1 christos } 1083 1.1 christos 1084 1.1 christos /* read SOA rdata section for SOA storage */ 1085 1.1.1.3 christos static int read_soa_rdata_fields(struct buffer* packet, uint8_t* primns, 1086 1.1 christos int* primns_len, uint8_t* email, int* email_len, 1087 1.1 christos uint32_t* serial, uint32_t* refresh, uint32_t* retry, 1088 1.1 christos uint32_t* expire, uint32_t* minimum, size_t* sz) 1089 1.1 christos { 1090 1.1 christos if(!(*primns_len = dname_make_wire_from_packet(primns, packet, 1))) { 1091 1.1 christos log_msg(LOG_ERR, "ixfr_store: cannot parse soa nsname in packet"); 1092 1.1 christos return 0; 1093 1.1 christos } 1094 1.1 christos *sz += *primns_len; 1095 1.1 christos if(!(*email_len = dname_make_wire_from_packet(email, packet, 1))) { 1096 1.1 christos log_msg(LOG_ERR, "ixfr_store: cannot parse soa maintname in packet"); 1097 1.1 christos return 0; 1098 1.1 christos } 1099 1.1 christos *sz += *email_len; 1100 1.1 christos *serial = buffer_read_u32(packet); 1101 1.1 christos *sz += 4; 1102 1.1 christos *refresh = buffer_read_u32(packet); 1103 1.1 christos *sz += 4; 1104 1.1 christos *retry = buffer_read_u32(packet); 1105 1.1 christos *sz += 4; 1106 1.1 christos *expire = buffer_read_u32(packet); 1107 1.1 christos *sz += 4; 1108 1.1 christos *minimum = buffer_read_u32(packet); 1109 1.1 christos *sz += 4; 1110 1.1 christos return 1; 1111 1.1 christos } 1112 1.1 christos 1113 1.1 christos /* store SOA record data in memory buffer */ 1114 1.1 christos static void store_soa(uint8_t* soa, struct zone* zone, uint32_t ttl, 1115 1.1 christos uint16_t rdlen_uncompressed, uint8_t* primns, int primns_len, 1116 1.1 christos uint8_t* email, int email_len, uint32_t serial, uint32_t refresh, 1117 1.1 christos uint32_t retry, uint32_t expire, uint32_t minimum) 1118 1.1 christos { 1119 1.1 christos uint8_t* sp = soa; 1120 1.1 christos memmove(sp, dname_name(domain_dname(zone->apex)), 1121 1.1 christos domain_dname(zone->apex)->name_size); 1122 1.1 christos sp += domain_dname(zone->apex)->name_size; 1123 1.1 christos write_uint16(sp, TYPE_SOA); 1124 1.1 christos sp += 2; 1125 1.1 christos write_uint16(sp, CLASS_IN); 1126 1.1 christos sp += 2; 1127 1.1 christos write_uint32(sp, ttl); 1128 1.1 christos sp += 4; 1129 1.1 christos write_uint16(sp, rdlen_uncompressed); 1130 1.1 christos sp += 2; 1131 1.1 christos memmove(sp, primns, primns_len); 1132 1.1 christos sp += primns_len; 1133 1.1 christos memmove(sp, email, email_len); 1134 1.1 christos sp += email_len; 1135 1.1 christos write_uint32(sp, serial); 1136 1.1 christos sp += 4; 1137 1.1 christos write_uint32(sp, refresh); 1138 1.1 christos sp += 4; 1139 1.1 christos write_uint32(sp, retry); 1140 1.1 christos sp += 4; 1141 1.1 christos write_uint32(sp, expire); 1142 1.1 christos sp += 4; 1143 1.1 christos write_uint32(sp, minimum); 1144 1.1 christos } 1145 1.1 christos 1146 1.1.1.2 christos void ixfr_store_add_newsoa(struct ixfr_store* ixfr_store, uint32_t ttl, 1147 1.1.1.2 christos struct buffer* packet, size_t rrlen) 1148 1.1 christos { 1149 1.1 christos size_t oldpos, sz = 0; 1150 1.1.1.2 christos uint32_t serial, refresh, retry, expire, minimum; 1151 1.1.1.2 christos uint16_t rdlen_uncompressed; 1152 1.1 christos int primns_len = 0, email_len = 0; 1153 1.1 christos uint8_t primns[MAXDOMAINLEN + 1], email[MAXDOMAINLEN + 1]; 1154 1.1 christos 1155 1.1 christos if(ixfr_store->cancelled) 1156 1.1 christos return; 1157 1.1 christos if(ixfr_store->data->newsoa) { 1158 1.1 christos free(ixfr_store->data->newsoa); 1159 1.1 christos ixfr_store->data->newsoa = NULL; 1160 1.1 christos ixfr_store->data->newsoa_len = 0; 1161 1.1 christos } 1162 1.1 christos oldpos = buffer_position(packet); 1163 1.1 christos 1164 1.1 christos /* calculate the length */ 1165 1.1 christos sz = domain_dname(ixfr_store->zone->apex)->name_size; 1166 1.1.1.2 christos sz += 2 /* type */ + 2 /* class */ + 4 /* ttl */ + 2 /* rdlen */; 1167 1.1.1.2 christos if(!buffer_available(packet, rrlen)) { 1168 1.1 christos /* not possible already parsed, but fail nicely anyway */ 1169 1.1 christos log_msg(LOG_ERR, "ixfr_store: not enough rdata space in packet"); 1170 1.1 christos ixfr_store_cancel(ixfr_store); 1171 1.1 christos buffer_set_position(packet, oldpos); 1172 1.1 christos return; 1173 1.1 christos } 1174 1.1.1.3 christos if(!read_soa_rdata_fields(packet, primns, &primns_len, email, &email_len, 1175 1.1 christos &serial, &refresh, &retry, &expire, &minimum, &sz)) { 1176 1.1 christos log_msg(LOG_ERR, "ixfr_store newsoa: cannot parse packet"); 1177 1.1 christos ixfr_store_cancel(ixfr_store); 1178 1.1 christos buffer_set_position(packet, oldpos); 1179 1.1 christos return; 1180 1.1 christos } 1181 1.1 christos rdlen_uncompressed = primns_len + email_len + 4 + 4 + 4 + 4 + 4; 1182 1.1 christos 1183 1.1.1.2 christos ixfr_store->data->newserial = serial; 1184 1.1.1.2 christos 1185 1.1 christos /* store the soa record */ 1186 1.1 christos ixfr_store->data->newsoa = xalloc(sz); 1187 1.1 christos ixfr_store->data->newsoa_len = sz; 1188 1.1 christos store_soa(ixfr_store->data->newsoa, ixfr_store->zone, ttl, 1189 1.1 christos rdlen_uncompressed, primns, primns_len, email, email_len, 1190 1.1 christos serial, refresh, retry, expire, minimum); 1191 1.1 christos 1192 1.1 christos buffer_set_position(packet, oldpos); 1193 1.1 christos } 1194 1.1 christos 1195 1.1 christos void ixfr_store_add_oldsoa(struct ixfr_store* ixfr_store, uint32_t ttl, 1196 1.1 christos struct buffer* packet, size_t rrlen) 1197 1.1 christos { 1198 1.1 christos size_t oldpos, sz = 0; 1199 1.1 christos uint32_t serial, refresh, retry, expire, minimum; 1200 1.1 christos uint16_t rdlen_uncompressed; 1201 1.1 christos int primns_len = 0, email_len = 0; 1202 1.1 christos uint8_t primns[MAXDOMAINLEN + 1], email[MAXDOMAINLEN + 1]; 1203 1.1 christos 1204 1.1 christos if(ixfr_store->cancelled) 1205 1.1 christos return; 1206 1.1 christos if(ixfr_store->data->oldsoa) { 1207 1.1 christos free(ixfr_store->data->oldsoa); 1208 1.1 christos ixfr_store->data->oldsoa = NULL; 1209 1.1 christos ixfr_store->data->oldsoa_len = 0; 1210 1.1 christos } 1211 1.1 christos /* we have the old SOA and thus we are sure it is an IXFR, make space*/ 1212 1.1 christos zone_ixfr_make_space(ixfr_store->zone->ixfr, ixfr_store->zone, 1213 1.1 christos ixfr_store->data, ixfr_store); 1214 1.1 christos if(ixfr_store->cancelled) 1215 1.1 christos return; 1216 1.1 christos oldpos = buffer_position(packet); 1217 1.1 christos 1218 1.1 christos /* calculate the length */ 1219 1.1 christos sz = domain_dname(ixfr_store->zone->apex)->name_size; 1220 1.1 christos sz += 2 /*type*/ + 2 /*class*/ + 4 /*ttl*/ + 2 /*rdlen*/; 1221 1.1 christos if(!buffer_available(packet, rrlen)) { 1222 1.1 christos /* not possible already parsed, but fail nicely anyway */ 1223 1.1 christos log_msg(LOG_ERR, "ixfr_store oldsoa: not enough rdata space in packet"); 1224 1.1 christos ixfr_store_cancel(ixfr_store); 1225 1.1 christos buffer_set_position(packet, oldpos); 1226 1.1 christos return; 1227 1.1 christos } 1228 1.1.1.3 christos if(!read_soa_rdata_fields(packet, primns, &primns_len, email, &email_len, 1229 1.1 christos &serial, &refresh, &retry, &expire, &minimum, &sz)) { 1230 1.1 christos log_msg(LOG_ERR, "ixfr_store oldsoa: cannot parse packet"); 1231 1.1 christos ixfr_store_cancel(ixfr_store); 1232 1.1 christos buffer_set_position(packet, oldpos); 1233 1.1 christos return; 1234 1.1 christos } 1235 1.1 christos rdlen_uncompressed = primns_len + email_len + 4 + 4 + 4 + 4 + 4; 1236 1.1 christos 1237 1.1.1.2 christos ixfr_store->data->oldserial = serial; 1238 1.1.1.2 christos 1239 1.1 christos /* store the soa record */ 1240 1.1 christos ixfr_store->data->oldsoa = xalloc(sz); 1241 1.1 christos ixfr_store->data->oldsoa_len = sz; 1242 1.1 christos store_soa(ixfr_store->data->oldsoa, ixfr_store->zone, ttl, 1243 1.1 christos rdlen_uncompressed, primns, primns_len, email, email_len, 1244 1.1 christos serial, refresh, retry, expire, minimum); 1245 1.1 christos 1246 1.1 christos buffer_set_position(packet, oldpos); 1247 1.1 christos } 1248 1.1 christos 1249 1.1.1.3 christos /* store RR in data segment. 1250 1.1.1.3 christos * return -1 on fail of wireformat, 0 on allocate failure, or 1 success. */ 1251 1.1.1.3 christos static int ixfr_putrr(const rr_type* rr, uint8_t** rrs, size_t* rrs_len, 1252 1.1.1.3 christos size_t* rrs_capacity) 1253 1.1 christos { 1254 1.1.1.3 christos int32_t rdlen_uncompressed; 1255 1.1.1.3 christos size_t sz; 1256 1.1 christos uint8_t* sp; 1257 1.1.1.3 christos const dname_type* dname; 1258 1.1 christos 1259 1.1.1.3 christos rdlen_uncompressed = rr_calculate_uncompressed_rdata_length(rr); 1260 1.1.1.3 christos if (rdlen_uncompressed < 0) 1261 1.1.1.3 christos return -1; /* malformed */ 1262 1.1.1.3 christos 1263 1.1.1.3 christos dname = domain_dname(rr->owner); 1264 1.1 christos sz = dname->name_size + 2 /*type*/ + 2 /*class*/ + 4 /*ttl*/ + 1265 1.1 christos 2 /*rdlen*/ + rdlen_uncompressed; 1266 1.1 christos 1267 1.1 christos /* store RR in IXFR data */ 1268 1.1 christos ixfr_rrs_make_space(rrs, rrs_len, rrs_capacity, sz); 1269 1.1 christos if(!*rrs || *rrs_len + sz > *rrs_capacity) { 1270 1.1 christos return 0; 1271 1.1 christos } 1272 1.1 christos /* copy data into add */ 1273 1.1 christos sp = *rrs + *rrs_len; 1274 1.1 christos *rrs_len += sz; 1275 1.1 christos memmove(sp, dname_name(dname), dname->name_size); 1276 1.1 christos sp += dname->name_size; 1277 1.1.1.3 christos write_uint16(sp, rr->type); 1278 1.1.1.3 christos write_uint16(sp + 2, rr->klass); 1279 1.1.1.3 christos write_uint32(sp + 4, rr->ttl); 1280 1.1.1.3 christos write_uint16(sp + 8, rdlen_uncompressed); 1281 1.1.1.3 christos rr_write_uncompressed_rdata(rr, sp+10, rdlen_uncompressed); 1282 1.1 christos return 1; 1283 1.1 christos } 1284 1.1 christos 1285 1.1.1.3 christos void ixfr_store_putrr(struct ixfr_store* ixfr_store, const rr_type* rr, 1286 1.1.1.3 christos uint8_t** rrs, size_t* rrs_len, size_t* rrs_capacity) 1287 1.1 christos { 1288 1.1.1.3 christos int code; 1289 1.1 christos 1290 1.1 christos if(ixfr_store->cancelled) 1291 1.1 christos return; 1292 1.1 christos 1293 1.1 christos /* The SOA data is stored with separate calls. And then appended 1294 1.1 christos * during the finish operation. We do not have to store it here 1295 1.1 christos * when called from difffile's IXFR processing with type SOA. */ 1296 1.1.1.3 christos if(rr->type == TYPE_SOA) 1297 1.1 christos return; 1298 1.1 christos /* make space for these RRs we have now; basically once we 1299 1.1 christos * grow beyond the current allowed amount an older IXFR is deleted. */ 1300 1.1 christos zone_ixfr_make_space(ixfr_store->zone->ixfr, ixfr_store->zone, 1301 1.1 christos ixfr_store->data, ixfr_store); 1302 1.1 christos if(ixfr_store->cancelled) 1303 1.1 christos return; 1304 1.1 christos 1305 1.1.1.3 christos /* store rdata */ 1306 1.1.1.3 christos code = ixfr_putrr(rr, rrs, rrs_len, rrs_capacity); 1307 1.1 christos 1308 1.1.1.3 christos if (code <= 0) { 1309 1.1.1.3 christos if (code == -1) 1310 1.1.1.3 christos log_msg(LOG_ERR, "ixfr_store addrr: cannot parse rdata format"); 1311 1.1.1.3 christos else 1312 1.1.1.3 christos log_msg(LOG_ERR, "ixfr_store addrr: cannot allocate space"); 1313 1.1 christos ixfr_store_cancel(ixfr_store); 1314 1.1 christos return; 1315 1.1 christos } 1316 1.1 christos } 1317 1.1 christos 1318 1.1.1.3 christos void ixfr_store_delrr(struct ixfr_store* ixfr_store, const rr_type* rr) 1319 1.1 christos { 1320 1.1.1.3 christos if(ixfr_store->cancelled) 1321 1.1.1.3 christos return; 1322 1.1.1.3 christos ixfr_store_putrr(ixfr_store, rr, &ixfr_store->data->del, 1323 1.1 christos &ixfr_store->data->del_len, &ixfr_store->del_capacity); 1324 1.1 christos } 1325 1.1 christos 1326 1.1.1.3 christos void ixfr_store_addrr(struct ixfr_store* ixfr_store, const rr_type* rr) 1327 1.1 christos { 1328 1.1.1.3 christos if(ixfr_store->cancelled) 1329 1.1.1.3 christos return; 1330 1.1.1.3 christos ixfr_store_putrr(ixfr_store, rr, &ixfr_store->data->add, 1331 1.1 christos &ixfr_store->data->add_len, &ixfr_store->add_capacity); 1332 1.1 christos } 1333 1.1 christos 1334 1.1.1.3 christos int ixfr_store_addrr_rdatas(struct ixfr_store* ixfr_store, const rr_type *rr) 1335 1.1 christos { 1336 1.1 christos if(ixfr_store->cancelled) 1337 1.1 christos return 1; 1338 1.1.1.3 christos if(rr->type == TYPE_SOA) 1339 1.1 christos return 1; 1340 1.1.1.3 christos if(ixfr_putrr(rr, &ixfr_store->data->add, &ixfr_store->data->add_len, 1341 1.1.1.3 christos &ixfr_store->add_capacity) <= 0) 1342 1.1.1.3 christos return 0; 1343 1.1.1.3 christos return 1; 1344 1.1 christos } 1345 1.1 christos 1346 1.1 christos int ixfr_store_add_newsoa_rdatas(struct ixfr_store* ixfr_store, 1347 1.1.1.3 christos const rr_type* rr) 1348 1.1 christos { 1349 1.1 christos size_t capacity = 0; 1350 1.1 christos if(ixfr_store->cancelled) 1351 1.1 christos return 1; 1352 1.1.1.3 christos if(!retrieve_soa_rdata_serial(rr, &ixfr_store->data->newserial)) 1353 1.1.1.2 christos return 0; 1354 1.1.1.3 christos if(ixfr_putrr(rr, &ixfr_store->data->newsoa, 1355 1.1.1.3 christos &ixfr_store->data->newsoa_len, &ixfr_store->add_capacity) <= 0) 1356 1.1 christos return 0; 1357 1.1 christos ixfr_trim_capacity(&ixfr_store->data->newsoa, 1358 1.1 christos &ixfr_store->data->newsoa_len, &capacity); 1359 1.1 christos return 1; 1360 1.1 christos } 1361 1.1 christos 1362 1.1 christos /* store rr uncompressed */ 1363 1.1 christos int ixfr_storerr_uncompressed(uint8_t* dname, size_t dname_len, uint16_t type, 1364 1.1 christos uint16_t klass, uint32_t ttl, uint8_t* rdata, size_t rdata_len, 1365 1.1 christos uint8_t** rrs, size_t* rrs_len, size_t* rrs_capacity) 1366 1.1 christos { 1367 1.1 christos size_t sz; 1368 1.1 christos uint8_t* sp; 1369 1.1 christos 1370 1.1 christos /* find rdatalen */ 1371 1.1 christos sz = dname_len + 2 /*type*/ + 2 /*class*/ + 4 /*ttl*/ + 1372 1.1 christos 2 /*rdlen*/ + rdata_len; 1373 1.1 christos 1374 1.1 christos /* store RR in IXFR data */ 1375 1.1 christos ixfr_rrs_make_space(rrs, rrs_len, rrs_capacity, sz); 1376 1.1 christos if(!*rrs || *rrs_len + sz > *rrs_capacity) { 1377 1.1 christos return 0; 1378 1.1 christos } 1379 1.1 christos /* copy data into add */ 1380 1.1 christos sp = *rrs + *rrs_len; 1381 1.1 christos *rrs_len += sz; 1382 1.1 christos memmove(sp, dname, dname_len); 1383 1.1 christos sp += dname_len; 1384 1.1 christos write_uint16(sp, type); 1385 1.1 christos sp += 2; 1386 1.1 christos write_uint16(sp, klass); 1387 1.1 christos sp += 2; 1388 1.1 christos write_uint32(sp, ttl); 1389 1.1 christos sp += 4; 1390 1.1 christos write_uint16(sp, rdata_len); 1391 1.1 christos sp += 2; 1392 1.1 christos memmove(sp, rdata, rdata_len); 1393 1.1 christos return 1; 1394 1.1 christos } 1395 1.1 christos 1396 1.1 christos int ixfr_store_delrr_uncompressed(struct ixfr_store* ixfr_store, 1397 1.1 christos uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass, 1398 1.1 christos uint32_t ttl, uint8_t* rdata, size_t rdata_len) 1399 1.1 christos { 1400 1.1 christos if(ixfr_store->cancelled) 1401 1.1 christos return 1; 1402 1.1 christos if(type == TYPE_SOA) 1403 1.1 christos return 1; 1404 1.1 christos return ixfr_storerr_uncompressed(dname, dname_len, type, klass, 1405 1.1 christos ttl, rdata, rdata_len, &ixfr_store->data->del, 1406 1.1 christos &ixfr_store->data->del_len, &ixfr_store->del_capacity); 1407 1.1 christos } 1408 1.1 christos 1409 1.1.1.2 christos static size_t skip_dname(uint8_t* rdata, size_t rdata_len) 1410 1.1.1.2 christos { 1411 1.1.1.2 christos for (size_t index=0; index < rdata_len; ) { 1412 1.1.1.2 christos uint8_t label_size = rdata[index]; 1413 1.1.1.2 christos if (label_size == 0) { 1414 1.1.1.2 christos return index + 1; 1415 1.1.1.2 christos } else if ((label_size & 0xc0) != 0) { 1416 1.1.1.2 christos return (index + 1 < rdata_len) ? index + 2 : 0; 1417 1.1.1.2 christos } else { 1418 1.1.1.2 christos /* loop breaks if index exceeds rdata_len */ 1419 1.1.1.2 christos index += label_size + 1; 1420 1.1.1.2 christos } 1421 1.1.1.2 christos } 1422 1.1.1.2 christos 1423 1.1.1.2 christos return 0; 1424 1.1.1.2 christos } 1425 1.1.1.2 christos 1426 1.1 christos int ixfr_store_oldsoa_uncompressed(struct ixfr_store* ixfr_store, 1427 1.1 christos uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass, 1428 1.1 christos uint32_t ttl, uint8_t* rdata, size_t rdata_len) 1429 1.1 christos { 1430 1.1.1.3 christos uint32_t serial; 1431 1.1.1.3 christos size_t capacity = 0, index, count; 1432 1.1 christos if(ixfr_store->cancelled) 1433 1.1 christos return 1; 1434 1.1 christos if(!ixfr_storerr_uncompressed(dname, dname_len, type, klass, 1435 1.1 christos ttl, rdata, rdata_len, &ixfr_store->data->oldsoa, 1436 1.1 christos &ixfr_store->data->oldsoa_len, &capacity)) 1437 1.1 christos return 0; 1438 1.1.1.3 christos 1439 1.1.1.3 christos if (!(count = skip_dname(rdata, rdata_len))) 1440 1.1.1.3 christos return 0; 1441 1.1.1.3 christos index = count; 1442 1.1.1.3 christos if (!(count = skip_dname(rdata+index, rdata_len-index))) 1443 1.1.1.3 christos return 0; 1444 1.1.1.3 christos index += count; 1445 1.1.1.3 christos if (rdata_len - index < 4) 1446 1.1.1.3 christos return 0; 1447 1.1.1.3 christos memcpy(&serial, rdata+index, sizeof(serial)); 1448 1.1.1.3 christos ixfr_store->data->oldserial = ntohl(serial); 1449 1.1.1.3 christos 1450 1.1 christos ixfr_trim_capacity(&ixfr_store->data->oldsoa, 1451 1.1 christos &ixfr_store->data->oldsoa_len, &capacity); 1452 1.1 christos return 1; 1453 1.1 christos } 1454 1.1 christos 1455 1.1 christos int zone_is_ixfr_enabled(struct zone* zone) 1456 1.1 christos { 1457 1.1 christos return zone->opts->pattern->store_ixfr; 1458 1.1 christos } 1459 1.1 christos 1460 1.1 christos /* compare ixfr elements */ 1461 1.1 christos static int ixfrcompare(const void* x, const void* y) 1462 1.1 christos { 1463 1.1 christos uint32_t* serial_x = (uint32_t*)x; 1464 1.1 christos uint32_t* serial_y = (uint32_t*)y; 1465 1.1 christos if(*serial_x < *serial_y) 1466 1.1 christos return -1; 1467 1.1 christos if(*serial_x > *serial_y) 1468 1.1 christos return 1; 1469 1.1 christos return 0; 1470 1.1 christos } 1471 1.1 christos 1472 1.1 christos struct zone_ixfr* zone_ixfr_create(struct nsd* nsd) 1473 1.1 christos { 1474 1.1 christos struct zone_ixfr* ixfr = xalloc_zero(sizeof(struct zone_ixfr)); 1475 1.1 christos ixfr->data = rbtree_create(nsd->region, &ixfrcompare); 1476 1.1 christos return ixfr; 1477 1.1 christos } 1478 1.1 christos 1479 1.1 christos /* traverse tree postorder */ 1480 1.1 christos static void ixfr_tree_del(struct rbnode* node) 1481 1.1 christos { 1482 1.1 christos if(node == NULL || node == RBTREE_NULL) 1483 1.1 christos return; 1484 1.1 christos ixfr_tree_del(node->left); 1485 1.1 christos ixfr_tree_del(node->right); 1486 1.1 christos ixfr_data_free((struct ixfr_data*)node); 1487 1.1 christos } 1488 1.1 christos 1489 1.1 christos /* clear the ixfr data elements */ 1490 1.1 christos static void zone_ixfr_clear(struct zone_ixfr* ixfr) 1491 1.1 christos { 1492 1.1 christos if(!ixfr) 1493 1.1 christos return; 1494 1.1 christos if(ixfr->data) { 1495 1.1 christos ixfr_tree_del(ixfr->data->root); 1496 1.1 christos ixfr->data->root = RBTREE_NULL; 1497 1.1 christos ixfr->data->count = 0; 1498 1.1 christos } 1499 1.1 christos ixfr->total_size = 0; 1500 1.1 christos ixfr->oldest_serial = 0; 1501 1.1 christos ixfr->newest_serial = 0; 1502 1.1 christos } 1503 1.1 christos 1504 1.1 christos void zone_ixfr_free(struct zone_ixfr* ixfr) 1505 1.1 christos { 1506 1.1 christos if(!ixfr) 1507 1.1 christos return; 1508 1.1 christos if(ixfr->data) { 1509 1.1 christos ixfr_tree_del(ixfr->data->root); 1510 1.1 christos ixfr->data = NULL; 1511 1.1 christos } 1512 1.1 christos free(ixfr); 1513 1.1 christos } 1514 1.1 christos 1515 1.1 christos void ixfr_store_delixfrs(struct zone* zone) 1516 1.1 christos { 1517 1.1 christos if(!zone) 1518 1.1 christos return; 1519 1.1 christos zone_ixfr_clear(zone->ixfr); 1520 1.1 christos } 1521 1.1 christos 1522 1.1 christos /* remove the oldest data entry from the ixfr versions */ 1523 1.1 christos static void zone_ixfr_remove_oldest(struct zone_ixfr* ixfr) 1524 1.1 christos { 1525 1.1 christos if(ixfr->data->count > 0) { 1526 1.1 christos struct ixfr_data* oldest = ixfr_data_first(ixfr); 1527 1.1 christos if(ixfr->oldest_serial == oldest->oldserial) { 1528 1.1 christos if(ixfr->data->count > 1) { 1529 1.1 christos struct ixfr_data* next = ixfr_data_next(ixfr, oldest); 1530 1.1 christos assert(next); 1531 1.1 christos if(next) 1532 1.1 christos ixfr->oldest_serial = next->oldserial; 1533 1.1 christos else ixfr->oldest_serial = oldest->newserial; 1534 1.1 christos } else { 1535 1.1 christos ixfr->oldest_serial = 0; 1536 1.1 christos } 1537 1.1 christos } 1538 1.1 christos if(ixfr->newest_serial == oldest->oldserial) { 1539 1.1 christos ixfr->newest_serial = 0; 1540 1.1 christos } 1541 1.1 christos zone_ixfr_remove(ixfr, oldest); 1542 1.1 christos } 1543 1.1 christos } 1544 1.1 christos 1545 1.1 christos void zone_ixfr_make_space(struct zone_ixfr* ixfr, struct zone* zone, 1546 1.1 christos struct ixfr_data* data, struct ixfr_store* ixfr_store) 1547 1.1 christos { 1548 1.1 christos size_t addsize; 1549 1.1 christos if(!ixfr || !data) 1550 1.1 christos return; 1551 1.1 christos if(zone->opts->pattern->ixfr_number == 0) { 1552 1.1 christos ixfr_store_cancel(ixfr_store); 1553 1.1 christos return; 1554 1.1 christos } 1555 1.1 christos 1556 1.1 christos /* Check the number of IXFRs allowed for this zone, if too many, 1557 1.1 christos * shorten the number to make space for another one */ 1558 1.1 christos while(ixfr->data->count >= zone->opts->pattern->ixfr_number) { 1559 1.1 christos zone_ixfr_remove_oldest(ixfr); 1560 1.1 christos } 1561 1.1 christos 1562 1.1 christos if(zone->opts->pattern->ixfr_size == 0) { 1563 1.1 christos /* no size limits imposed */ 1564 1.1 christos return; 1565 1.1 christos } 1566 1.1 christos 1567 1.1 christos /* Check the size of the current added data element 'data', and 1568 1.1 christos * see if that overflows the maximum storage size for IXFRs for 1569 1.1 christos * this zone, and if so, delete the oldest IXFR to make space */ 1570 1.1 christos addsize = ixfr_data_size(data); 1571 1.1 christos while(ixfr->data->count > 0 && ixfr->total_size + addsize > 1572 1.1 christos zone->opts->pattern->ixfr_size) { 1573 1.1 christos zone_ixfr_remove_oldest(ixfr); 1574 1.1 christos } 1575 1.1 christos 1576 1.1 christos /* if deleting the oldest elements does not work, then this 1577 1.1 christos * IXFR is too big to store and we cancel it */ 1578 1.1 christos if(ixfr->data->count == 0 && ixfr->total_size + addsize > 1579 1.1 christos zone->opts->pattern->ixfr_size) { 1580 1.1 christos ixfr_store_cancel(ixfr_store); 1581 1.1 christos return; 1582 1.1 christos } 1583 1.1 christos } 1584 1.1 christos 1585 1.1 christos void zone_ixfr_remove(struct zone_ixfr* ixfr, struct ixfr_data* data) 1586 1.1 christos { 1587 1.1 christos rbtree_delete(ixfr->data, data->node.key); 1588 1.1 christos ixfr->total_size -= ixfr_data_size(data); 1589 1.1 christos ixfr_data_free(data); 1590 1.1 christos } 1591 1.1 christos 1592 1.1 christos void zone_ixfr_add(struct zone_ixfr* ixfr, struct ixfr_data* data, int isnew) 1593 1.1 christos { 1594 1.1 christos memset(&data->node, 0, sizeof(data->node)); 1595 1.1 christos if(ixfr->data->count == 0) { 1596 1.1 christos ixfr->oldest_serial = data->oldserial; 1597 1.1 christos ixfr->newest_serial = data->oldserial; 1598 1.1 christos } else if(isnew) { 1599 1.1 christos /* newest entry is last there is */ 1600 1.1 christos ixfr->newest_serial = data->oldserial; 1601 1.1 christos } else { 1602 1.1 christos /* added older entry, before the others */ 1603 1.1 christos ixfr->oldest_serial = data->oldserial; 1604 1.1 christos } 1605 1.1 christos data->node.key = &data->oldserial; 1606 1.1 christos rbtree_insert(ixfr->data, &data->node); 1607 1.1 christos ixfr->total_size += ixfr_data_size(data); 1608 1.1 christos } 1609 1.1 christos 1610 1.1 christos struct ixfr_data* zone_ixfr_find_serial(struct zone_ixfr* ixfr, 1611 1.1 christos uint32_t qserial) 1612 1.1 christos { 1613 1.1 christos struct ixfr_data* data; 1614 1.1 christos if(!ixfr) 1615 1.1 christos return NULL; 1616 1.1 christos if(!ixfr->data) 1617 1.1 christos return NULL; 1618 1.1 christos data = (struct ixfr_data*)rbtree_search(ixfr->data, &qserial); 1619 1.1 christos if(data) { 1620 1.1 christos assert(data->oldserial == qserial); 1621 1.1 christos return data; 1622 1.1 christos } 1623 1.1 christos /* not found */ 1624 1.1 christos return NULL; 1625 1.1 christos } 1626 1.1 christos 1627 1.1 christos /* calculate the number of files we want */ 1628 1.1 christos static int ixfr_target_number_files(struct zone* zone) 1629 1.1 christos { 1630 1.1 christos int dest_num_files; 1631 1.1 christos if(!zone->ixfr || !zone->ixfr->data) 1632 1.1 christos return 0; 1633 1.1 christos if(!zone_is_ixfr_enabled(zone)) 1634 1.1 christos return 0; 1635 1.1 christos /* if we store ixfr, it is the configured number of files */ 1636 1.1 christos dest_num_files = (int)zone->opts->pattern->ixfr_number; 1637 1.1 christos /* but if the number of available transfers is smaller, store less */ 1638 1.1 christos if(dest_num_files > (int)zone->ixfr->data->count) 1639 1.1 christos dest_num_files = (int)zone->ixfr->data->count; 1640 1.1 christos return dest_num_files; 1641 1.1 christos } 1642 1.1 christos 1643 1.1 christos /* create ixfrfile name in buffer for file_num. The num is 1 .. number. */ 1644 1.1 christos static void make_ixfr_name(char* buf, size_t len, const char* zfile, 1645 1.1 christos int file_num) 1646 1.1 christos { 1647 1.1 christos if(file_num == 1) 1648 1.1 christos snprintf(buf, len, "%s.ixfr", zfile); 1649 1.1 christos else snprintf(buf, len, "%s.ixfr.%d", zfile, file_num); 1650 1.1 christos } 1651 1.1 christos 1652 1.1 christos /* create temp ixfrfile name in buffer for file_num. The num is 1 .. number. */ 1653 1.1 christos static void make_ixfr_name_temp(char* buf, size_t len, const char* zfile, 1654 1.1 christos int file_num, int temp) 1655 1.1 christos { 1656 1.1 christos if(file_num == 1) 1657 1.1 christos snprintf(buf, len, "%s.ixfr%s", zfile, (temp?".temp":"")); 1658 1.1 christos else snprintf(buf, len, "%s.ixfr.%d%s", zfile, file_num, 1659 1.1 christos (temp?".temp":"")); 1660 1.1 christos } 1661 1.1 christos 1662 1.1 christos /* see if ixfr file exists */ 1663 1.1 christos static int ixfr_file_exists_ctmp(const char* zfile, int file_num, int temp) 1664 1.1 christos { 1665 1.1 christos struct stat statbuf; 1666 1.1 christos char ixfrfile[1024+24]; 1667 1.1 christos make_ixfr_name_temp(ixfrfile, sizeof(ixfrfile), zfile, file_num, temp); 1668 1.1 christos memset(&statbuf, 0, sizeof(statbuf)); 1669 1.1 christos if(stat(ixfrfile, &statbuf) < 0) { 1670 1.1 christos if(errno == ENOENT) 1671 1.1 christos return 0; 1672 1.1 christos /* file is not usable */ 1673 1.1 christos return 0; 1674 1.1 christos } 1675 1.1 christos return 1; 1676 1.1 christos } 1677 1.1 christos 1678 1.1 christos int ixfr_file_exists(const char* zfile, int file_num) 1679 1.1 christos { 1680 1.1 christos return ixfr_file_exists_ctmp(zfile, file_num, 0); 1681 1.1 christos } 1682 1.1 christos 1683 1.1 christos /* see if ixfr file exists */ 1684 1.1 christos static int ixfr_file_exists_temp(const char* zfile, int file_num) 1685 1.1 christos { 1686 1.1 christos return ixfr_file_exists_ctmp(zfile, file_num, 1); 1687 1.1 christos } 1688 1.1 christos 1689 1.1 christos /* unlink an ixfr file */ 1690 1.1 christos static int ixfr_unlink_it_ctmp(const char* zname, const char* zfile, 1691 1.1 christos int file_num, int silent_enoent, int temp) 1692 1.1 christos { 1693 1.1 christos char ixfrfile[1024+24]; 1694 1.1 christos make_ixfr_name_temp(ixfrfile, sizeof(ixfrfile), zfile, file_num, temp); 1695 1.1 christos VERBOSITY(3, (LOG_INFO, "delete zone %s IXFR data file %s", 1696 1.1 christos zname, ixfrfile)); 1697 1.1 christos if(unlink(ixfrfile) < 0) { 1698 1.1 christos if(silent_enoent && errno == ENOENT) 1699 1.1 christos return 0; 1700 1.1 christos log_msg(LOG_ERR, "error to delete file %s: %s", ixfrfile, 1701 1.1 christos strerror(errno)); 1702 1.1 christos return 0; 1703 1.1 christos } 1704 1.1 christos return 1; 1705 1.1 christos } 1706 1.1 christos 1707 1.1 christos int ixfr_unlink_it(const char* zname, const char* zfile, int file_num, 1708 1.1 christos int silent_enoent) 1709 1.1 christos { 1710 1.1 christos return ixfr_unlink_it_ctmp(zname, zfile, file_num, silent_enoent, 0); 1711 1.1 christos } 1712 1.1 christos 1713 1.1 christos /* unlink an ixfr file */ 1714 1.1 christos static int ixfr_unlink_it_temp(const char* zname, const char* zfile, 1715 1.1 christos int file_num, int silent_enoent) 1716 1.1 christos { 1717 1.1 christos return ixfr_unlink_it_ctmp(zname, zfile, file_num, silent_enoent, 1); 1718 1.1 christos } 1719 1.1 christos 1720 1.1 christos /* read ixfr file header */ 1721 1.1 christos int ixfr_read_file_header(const char* zname, const char* zfile, 1722 1.1 christos int file_num, uint32_t* oldserial, uint32_t* newserial, 1723 1.1 christos size_t* data_size, int enoent_is_err) 1724 1.1 christos { 1725 1.1 christos char ixfrfile[1024+24]; 1726 1.1 christos char buf[1024]; 1727 1.1 christos FILE* in; 1728 1.1 christos int num_lines = 0, got_old = 0, got_new = 0, got_datasize = 0; 1729 1.1 christos make_ixfr_name(ixfrfile, sizeof(ixfrfile), zfile, file_num); 1730 1.1 christos in = fopen(ixfrfile, "r"); 1731 1.1 christos if(!in) { 1732 1.1 christos if((errno == ENOENT && enoent_is_err) || (errno != ENOENT)) 1733 1.1 christos log_msg(LOG_ERR, "could not open %s: %s", ixfrfile, 1734 1.1 christos strerror(errno)); 1735 1.1 christos return 0; 1736 1.1 christos } 1737 1.1 christos /* read about 10 lines, this is where the header is */ 1738 1.1 christos while(!(got_old && got_new && got_datasize) && num_lines < 10) { 1739 1.1 christos buf[0]=0; 1740 1.1 christos buf[sizeof(buf)-1]=0; 1741 1.1 christos if(!fgets(buf, sizeof(buf), in)) { 1742 1.1 christos log_msg(LOG_ERR, "could not read %s: %s", ixfrfile, 1743 1.1 christos strerror(errno)); 1744 1.1 christos fclose(in); 1745 1.1 christos return 0; 1746 1.1 christos } 1747 1.1 christos num_lines++; 1748 1.1 christos if(buf[0]!=0 && buf[strlen(buf)-1]=='\n') 1749 1.1 christos buf[strlen(buf)-1]=0; 1750 1.1 christos if(strncmp(buf, "; zone ", 7) == 0) { 1751 1.1 christos if(strcmp(buf+7, zname) != 0) { 1752 1.1 christos log_msg(LOG_ERR, "file has wrong zone, expected zone %s, but found %s in file %s", 1753 1.1 christos zname, buf+7, ixfrfile); 1754 1.1 christos fclose(in); 1755 1.1 christos return 0; 1756 1.1 christos } 1757 1.1 christos } else if(strncmp(buf, "; from_serial ", 14) == 0) { 1758 1.1 christos *oldserial = atoi(buf+14); 1759 1.1 christos got_old = 1; 1760 1.1 christos } else if(strncmp(buf, "; to_serial ", 12) == 0) { 1761 1.1 christos *newserial = atoi(buf+12); 1762 1.1 christos got_new = 1; 1763 1.1 christos } else if(strncmp(buf, "; data_size ", 12) == 0) { 1764 1.1 christos *data_size = (size_t)atoi(buf+12); 1765 1.1 christos got_datasize = 1; 1766 1.1 christos } 1767 1.1 christos } 1768 1.1 christos fclose(in); 1769 1.1 christos if(!got_old) 1770 1.1 christos return 0; 1771 1.1 christos if(!got_new) 1772 1.1 christos return 0; 1773 1.1 christos if(!got_datasize) 1774 1.1 christos return 0; 1775 1.1 christos return 1; 1776 1.1 christos } 1777 1.1 christos 1778 1.1 christos /* delete rest ixfr files, that are after the current item */ 1779 1.1 christos static void ixfr_delete_rest_files(struct zone* zone, struct ixfr_data* from, 1780 1.1 christos const char* zfile, int temp) 1781 1.1 christos { 1782 1.1 christos size_t prevcount = 0; 1783 1.1 christos struct ixfr_data* data = from; 1784 1.1 christos while(data) { 1785 1.1 christos if(data->file_num != 0) { 1786 1.1 christos (void)ixfr_unlink_it_ctmp(zone->opts->name, zfile, 1787 1.1 christos data->file_num, 0, temp); 1788 1.1 christos data->file_num = 0; 1789 1.1 christos } 1790 1.1 christos data = ixfr_data_prev(zone->ixfr, data, &prevcount); 1791 1.1 christos } 1792 1.1 christos } 1793 1.1 christos 1794 1.1 christos void ixfr_delete_superfluous_files(struct zone* zone, const char* zfile, 1795 1.1 christos int dest_num_files) 1796 1.1 christos { 1797 1.1 christos int i = dest_num_files + 1; 1798 1.1 christos if(!ixfr_file_exists(zfile, i)) 1799 1.1 christos return; 1800 1.1 christos while(ixfr_unlink_it(zone->opts->name, zfile, i, 1)) { 1801 1.1 christos i++; 1802 1.1 christos } 1803 1.1 christos } 1804 1.1 christos 1805 1.1 christos int ixfr_rename_it(const char* zname, const char* zfile, int oldnum, 1806 1.1 christos int oldtemp, int newnum, int newtemp) 1807 1.1 christos { 1808 1.1 christos char ixfrfile_old[1024+24]; 1809 1.1 christos char ixfrfile_new[1024+24]; 1810 1.1 christos make_ixfr_name_temp(ixfrfile_old, sizeof(ixfrfile_old), zfile, oldnum, 1811 1.1 christos oldtemp); 1812 1.1 christos make_ixfr_name_temp(ixfrfile_new, sizeof(ixfrfile_new), zfile, newnum, 1813 1.1 christos newtemp); 1814 1.1 christos VERBOSITY(3, (LOG_INFO, "rename zone %s IXFR data file %s to %s", 1815 1.1 christos zname, ixfrfile_old, ixfrfile_new)); 1816 1.1 christos if(rename(ixfrfile_old, ixfrfile_new) < 0) { 1817 1.1 christos log_msg(LOG_ERR, "error to rename file %s: %s", ixfrfile_old, 1818 1.1 christos strerror(errno)); 1819 1.1 christos return 0; 1820 1.1 christos } 1821 1.1 christos return 1; 1822 1.1 christos } 1823 1.1 christos 1824 1.1 christos /* delete if we have too many items in memory */ 1825 1.1 christos static void ixfr_delete_memory_items(struct zone* zone, int dest_num_files) 1826 1.1 christos { 1827 1.1 christos if(!zone->ixfr || !zone->ixfr->data) 1828 1.1 christos return; 1829 1.1 christos if(dest_num_files == (int)zone->ixfr->data->count) 1830 1.1 christos return; 1831 1.1 christos if(dest_num_files > (int)zone->ixfr->data->count) { 1832 1.1 christos /* impossible, dest_num_files should be smaller */ 1833 1.1 christos return; 1834 1.1 christos } 1835 1.1 christos 1836 1.1 christos /* delete oldest ixfr, until we have dest_num_files entries */ 1837 1.1 christos while(dest_num_files < (int)zone->ixfr->data->count) { 1838 1.1 christos zone_ixfr_remove_oldest(zone->ixfr); 1839 1.1 christos } 1840 1.1 christos } 1841 1.1 christos 1842 1.1 christos /* rename the ixfr files that need to change name */ 1843 1.1 christos static int ixfr_rename_files(struct zone* zone, const char* zfile, 1844 1.1 christos int dest_num_files) 1845 1.1 christos { 1846 1.1 christos struct ixfr_data* data, *startspot = NULL; 1847 1.1 christos size_t prevcount = 0; 1848 1.1 christos int destnum; 1849 1.1 christos if(!zone->ixfr || !zone->ixfr->data) 1850 1.1 christos return 1; 1851 1.1 christos 1852 1.1 christos /* the oldest file is at the largest number */ 1853 1.1 christos data = ixfr_data_first(zone->ixfr); 1854 1.1 christos destnum = dest_num_files; 1855 1.1 christos if(!data) 1856 1.1 christos return 1; /* nothing to do */ 1857 1.1 christos if(data->file_num == destnum) 1858 1.1 christos return 1; /* nothing to do for rename */ 1859 1.1 christos 1860 1.1 christos /* rename the files to temporary files, because otherwise the 1861 1.1 christos * items would overwrite each other when the list touches itself. 1862 1.1 christos * On fail, the temporary files are removed and we end up with 1863 1.1 christos * the newly written data plus the remaining files, in order. 1864 1.1 christos * Thus, start the temporary rename at the oldest, then rename 1865 1.1 christos * to the final names starting from the newest. */ 1866 1.1 christos while(data && data->file_num != 0) { 1867 1.1 christos /* if existing file at temporary name, delete that */ 1868 1.1 christos if(ixfr_file_exists_temp(zfile, data->file_num)) { 1869 1.1 christos (void)ixfr_unlink_it_temp(zone->opts->name, zfile, 1870 1.1 christos data->file_num, 0); 1871 1.1 christos } 1872 1.1 christos 1873 1.1 christos /* rename to temporary name */ 1874 1.1 christos if(!ixfr_rename_it(zone->opts->name, zfile, data->file_num, 0, 1875 1.1 christos data->file_num, 1)) { 1876 1.1 christos /* failure, we cannot store files */ 1877 1.1 christos /* delete the renamed files */ 1878 1.1 christos ixfr_delete_rest_files(zone, data, zfile, 1); 1879 1.1 christos return 0; 1880 1.1 christos } 1881 1.1 christos 1882 1.1 christos /* the next cycle should start at the newest file that 1883 1.1 christos * has been renamed to a temporary name */ 1884 1.1 christos startspot = data; 1885 1.1 christos data = ixfr_data_next(zone->ixfr, data); 1886 1.1 christos destnum--; 1887 1.1 christos } 1888 1.1 christos 1889 1.1 christos /* rename the files to their final name position */ 1890 1.1 christos data = startspot; 1891 1.1 christos while(data && data->file_num != 0) { 1892 1.1 christos destnum++; 1893 1.1 christos 1894 1.1 christos /* if there is an existing file, delete it */ 1895 1.1 christos if(ixfr_file_exists(zfile, destnum)) { 1896 1.1 christos (void)ixfr_unlink_it(zone->opts->name, zfile, 1897 1.1 christos destnum, 0); 1898 1.1 christos } 1899 1.1 christos 1900 1.1 christos if(!ixfr_rename_it(zone->opts->name, zfile, data->file_num, 1, destnum, 0)) { 1901 1.1 christos /* failure, we cannot store files */ 1902 1.1 christos ixfr_delete_rest_files(zone, data, zfile, 1); 1903 1.1 christos /* delete the previously renamed files, so in 1904 1.1 christos * memory stays as is, on disk we have the current 1905 1.1 christos * item (and newer transfers) okay. */ 1906 1.1 christos return 0; 1907 1.1 christos } 1908 1.1 christos data->file_num = destnum; 1909 1.1 christos 1910 1.1 christos data = ixfr_data_prev(zone->ixfr, data, &prevcount); 1911 1.1 christos } 1912 1.1 christos return 1; 1913 1.1 christos } 1914 1.1 christos 1915 1.1 christos /* write the ixfr data file header */ 1916 1.1 christos static int ixfr_write_file_header(struct zone* zone, struct ixfr_data* data, 1917 1.1 christos FILE* out) 1918 1.1 christos { 1919 1.1 christos if(!fprintf(out, "; IXFR data file\n")) 1920 1.1 christos return 0; 1921 1.1 christos if(!fprintf(out, "; zone %s\n", zone->opts->name)) 1922 1.1 christos return 0; 1923 1.1 christos if(!fprintf(out, "; from_serial %u\n", (unsigned)data->oldserial)) 1924 1.1 christos return 0; 1925 1.1 christos if(!fprintf(out, "; to_serial %u\n", (unsigned)data->newserial)) 1926 1.1 christos return 0; 1927 1.1 christos if(!fprintf(out, "; data_size %u\n", (unsigned)ixfr_data_size(data))) 1928 1.1 christos return 0; 1929 1.1 christos if(data->log_str) { 1930 1.1 christos if(!fprintf(out, "; %s\n", data->log_str)) 1931 1.1 christos return 0; 1932 1.1 christos } 1933 1.1 christos return 1; 1934 1.1 christos } 1935 1.1 christos 1936 1.1 christos /* parse wireformat RR into a struct RR in temp region */ 1937 1.1 christos static int parse_wirerr_into_temp(struct zone* zone, char* fname, 1938 1.1 christos struct region* temp, uint8_t* buf, size_t len, 1939 1.1.1.3 christos const dname_type** dname, struct rr** rr) 1940 1.1 christos { 1941 1.1 christos size_t bufpos = 0; 1942 1.1.1.3 christos uint16_t rdlen, tp, klass; 1943 1.1.1.3 christos uint32_t ttl; 1944 1.1.1.3 christos int32_t code; 1945 1.1.1.3 christos const struct nsd_type_descriptor *descriptor; 1946 1.1 christos buffer_type packet; 1947 1.1 christos domain_table_type* owners; 1948 1.1.1.3 christos struct domain *domain; 1949 1.1 christos owners = domain_table_create(temp); 1950 1.1 christos *dname = dname_make(temp, buf, 1); 1951 1.1 christos if(!*dname) { 1952 1.1 christos log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: failed to parse dname", zone->opts->name, fname); 1953 1.1 christos return 0; 1954 1.1 christos } 1955 1.1 christos bufpos = (*dname)->name_size; 1956 1.1 christos if(bufpos+10 > len) { 1957 1.1 christos log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: buffer too short", zone->opts->name, fname); 1958 1.1 christos return 0; 1959 1.1 christos } 1960 1.1.1.3 christos tp = read_uint16(buf+bufpos); 1961 1.1 christos bufpos += 2; 1962 1.1.1.3 christos klass = read_uint16(buf+bufpos); 1963 1.1 christos bufpos += 2; 1964 1.1.1.3 christos ttl = read_uint32(buf+bufpos); 1965 1.1 christos bufpos += 4; 1966 1.1 christos rdlen = read_uint16(buf+bufpos); 1967 1.1 christos bufpos += 2; 1968 1.1 christos if(bufpos + rdlen > len) { 1969 1.1 christos log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: buffer too short for rdatalen", zone->opts->name, fname); 1970 1.1 christos return 0; 1971 1.1 christos } 1972 1.1.1.3 christos domain = domain_table_insert(owners, *dname); 1973 1.1 christos buffer_create_from(&packet, buf+bufpos, rdlen); 1974 1.1.1.3 christos descriptor = nsd_type_descriptor(tp); 1975 1.1.1.3 christos code = descriptor->read_rdata(owners, rdlen, &packet, rr); 1976 1.1.1.3 christos if(code < 0) { 1977 1.1.1.3 christos log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: cannot parse rdata %s %s %s", zone->opts->name, fname, 1978 1.1.1.3 christos dname_to_string(*dname,0), rrtype_to_string(tp), 1979 1.1.1.3 christos read_rdata_fail_str(code)); 1980 1.1 christos return 0; 1981 1.1 christos } 1982 1.1.1.3 christos (*rr)->owner = domain; 1983 1.1.1.3 christos (*rr)->type = tp; 1984 1.1.1.3 christos (*rr)->klass = klass; 1985 1.1.1.3 christos (*rr)->ttl = ttl; 1986 1.1 christos return 1; 1987 1.1 christos } 1988 1.1 christos 1989 1.1 christos /* print RR on one line in output buffer. caller must zeroterminate, if 1990 1.1 christos * that is needed. */ 1991 1.1 christos static int print_rr_oneline(struct buffer* rr_buffer, const dname_type* dname, 1992 1.1 christos struct rr* rr) 1993 1.1 christos { 1994 1.1.1.3 christos const nsd_type_descriptor_type *descriptor = nsd_type_descriptor( 1995 1.1.1.3 christos rr->type); 1996 1.1 christos buffer_printf(rr_buffer, "%s", dname_to_string(dname, NULL)); 1997 1.1 christos buffer_printf(rr_buffer, "\t%lu\t%s\t%s", (unsigned long)rr->ttl, 1998 1.1 christos rrclass_to_string(rr->klass), rrtype_to_string(rr->type)); 1999 1.1.1.3 christos if (!print_rdata(rr_buffer, descriptor, rr)) { 2000 1.1.1.3 christos if(!print_unknown_rdata(rr_buffer, descriptor, rr)) 2001 1.1 christos return 0; 2002 1.1 christos } 2003 1.1 christos return 1; 2004 1.1 christos } 2005 1.1 christos 2006 1.1 christos /* write one RR to file, on one line */ 2007 1.1 christos static int ixfr_write_rr(struct zone* zone, FILE* out, char* fname, 2008 1.1 christos uint8_t* buf, size_t len, struct region* temp, buffer_type* rr_buffer) 2009 1.1 christos { 2010 1.1 christos const dname_type* dname; 2011 1.1.1.3 christos struct rr* rr; 2012 1.1 christos 2013 1.1 christos if(!parse_wirerr_into_temp(zone, fname, temp, buf, len, &dname, &rr)) { 2014 1.1 christos region_free_all(temp); 2015 1.1 christos return 0; 2016 1.1 christos } 2017 1.1 christos 2018 1.1 christos buffer_clear(rr_buffer); 2019 1.1.1.3 christos if(!print_rr_oneline(rr_buffer, dname, rr)) { 2020 1.1 christos log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: cannot spool RR string into buffer", zone->opts->name, fname); 2021 1.1 christos region_free_all(temp); 2022 1.1 christos return 0; 2023 1.1 christos } 2024 1.1 christos buffer_write_u8(rr_buffer, 0); 2025 1.1 christos buffer_flip(rr_buffer); 2026 1.1 christos 2027 1.1 christos if(!fprintf(out, "%s\n", buffer_begin(rr_buffer))) { 2028 1.1 christos log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: cannot print RR string to file: %s", zone->opts->name, fname, strerror(errno)); 2029 1.1 christos region_free_all(temp); 2030 1.1 christos return 0; 2031 1.1 christos } 2032 1.1 christos region_free_all(temp); 2033 1.1 christos return 1; 2034 1.1 christos } 2035 1.1 christos 2036 1.1 christos /* write ixfr RRs to file */ 2037 1.1 christos static int ixfr_write_rrs(struct zone* zone, FILE* out, char* fname, 2038 1.1 christos uint8_t* buf, size_t len, struct region* temp, buffer_type* rr_buffer) 2039 1.1 christos { 2040 1.1 christos size_t current = 0; 2041 1.1 christos if(!buf || len == 0) 2042 1.1 christos return 1; 2043 1.1 christos while(current < len) { 2044 1.1 christos size_t rrlen = count_rr_length(buf, len, current); 2045 1.1 christos if(rrlen == 0) 2046 1.1 christos return 0; 2047 1.1 christos if(current + rrlen > len) 2048 1.1 christos return 0; 2049 1.1 christos if(!ixfr_write_rr(zone, out, fname, buf+current, rrlen, 2050 1.1 christos temp, rr_buffer)) 2051 1.1 christos return 0; 2052 1.1 christos current += rrlen; 2053 1.1 christos } 2054 1.1 christos return 1; 2055 1.1 christos } 2056 1.1 christos 2057 1.1 christos /* write the ixfr data file data */ 2058 1.1 christos static int ixfr_write_file_data(struct zone* zone, struct ixfr_data* data, 2059 1.1 christos FILE* out, char* fname) 2060 1.1 christos { 2061 1.1 christos struct region* temp, *rrtemp; 2062 1.1 christos buffer_type* rr_buffer; 2063 1.1 christos temp = region_create(xalloc, free); 2064 1.1 christos rrtemp = region_create(xalloc, free); 2065 1.1 christos rr_buffer = buffer_create(rrtemp, MAX_RDLENGTH); 2066 1.1 christos 2067 1.1 christos if(!ixfr_write_rrs(zone, out, fname, data->newsoa, data->newsoa_len, 2068 1.1 christos temp, rr_buffer)) { 2069 1.1 christos region_destroy(temp); 2070 1.1 christos region_destroy(rrtemp); 2071 1.1 christos return 0; 2072 1.1 christos } 2073 1.1 christos if(!ixfr_write_rrs(zone, out, fname, data->oldsoa, data->oldsoa_len, 2074 1.1 christos temp, rr_buffer)) { 2075 1.1 christos region_destroy(temp); 2076 1.1 christos region_destroy(rrtemp); 2077 1.1 christos return 0; 2078 1.1 christos } 2079 1.1 christos if(!ixfr_write_rrs(zone, out, fname, data->del, data->del_len, 2080 1.1 christos temp, rr_buffer)) { 2081 1.1 christos region_destroy(temp); 2082 1.1 christos region_destroy(rrtemp); 2083 1.1 christos return 0; 2084 1.1 christos } 2085 1.1 christos if(!ixfr_write_rrs(zone, out, fname, data->add, data->add_len, 2086 1.1 christos temp, rr_buffer)) { 2087 1.1 christos region_destroy(temp); 2088 1.1 christos region_destroy(rrtemp); 2089 1.1 christos return 0; 2090 1.1 christos } 2091 1.1 christos region_destroy(temp); 2092 1.1 christos region_destroy(rrtemp); 2093 1.1 christos return 1; 2094 1.1 christos } 2095 1.1 christos 2096 1.1 christos int ixfr_write_file(struct zone* zone, struct ixfr_data* data, 2097 1.1 christos const char* zfile, int file_num) 2098 1.1 christos { 2099 1.1 christos char ixfrfile[1024+24]; 2100 1.1 christos FILE* out; 2101 1.1 christos make_ixfr_name(ixfrfile, sizeof(ixfrfile), zfile, file_num); 2102 1.1 christos VERBOSITY(1, (LOG_INFO, "writing zone %s IXFR data to file %s", 2103 1.1 christos zone->opts->name, ixfrfile)); 2104 1.1 christos out = fopen(ixfrfile, "w"); 2105 1.1 christos if(!out) { 2106 1.1 christos log_msg(LOG_ERR, "could not open for writing zone %s IXFR file %s: %s", 2107 1.1 christos zone->opts->name, ixfrfile, strerror(errno)); 2108 1.1 christos return 0; 2109 1.1 christos } 2110 1.1 christos 2111 1.1 christos if(!ixfr_write_file_header(zone, data, out)) { 2112 1.1 christos log_msg(LOG_ERR, "could not write file header for zone %s IXFR file %s: %s", 2113 1.1 christos zone->opts->name, ixfrfile, strerror(errno)); 2114 1.1 christos fclose(out); 2115 1.1 christos return 0; 2116 1.1 christos } 2117 1.1 christos if(!ixfr_write_file_data(zone, data, out, ixfrfile)) { 2118 1.1 christos fclose(out); 2119 1.1 christos return 0; 2120 1.1 christos } 2121 1.1 christos 2122 1.1 christos fclose(out); 2123 1.1 christos data->file_num = file_num; 2124 1.1 christos return 1; 2125 1.1 christos } 2126 1.1 christos 2127 1.1 christos /* write the ixfr files that need to be stored on disk */ 2128 1.1 christos static void ixfr_write_files(struct zone* zone, const char* zfile) 2129 1.1 christos { 2130 1.1 christos size_t prevcount = 0; 2131 1.1 christos int num; 2132 1.1 christos struct ixfr_data* data; 2133 1.1 christos if(!zone->ixfr || !zone->ixfr->data) 2134 1.1 christos return; /* nothing to write */ 2135 1.1 christos 2136 1.1 christos /* write unwritten files to disk */ 2137 1.1 christos data = ixfr_data_last(zone->ixfr); 2138 1.1 christos num=1; 2139 1.1 christos while(data && data->file_num == 0) { 2140 1.1 christos if(!ixfr_write_file(zone, data, zfile, num)) { 2141 1.1 christos /* There could be more files that are sitting on the 2142 1.1 christos * disk, remove them, they are not used without 2143 1.1 christos * this ixfr file. 2144 1.1 christos * 2145 1.1 christos * Give this element a file num, so it can be 2146 1.1 christos * deleted, it failed to write. It may be partial, 2147 1.1 christos * and we do not want to read that back in. 2148 1.1 christos * We are left with the newer transfers, that form 2149 1.1 christos * a correct list of transfers, that are wholly 2150 1.1 christos * written. */ 2151 1.1 christos data->file_num = num; 2152 1.1 christos ixfr_delete_rest_files(zone, data, zfile, 0); 2153 1.1 christos return; 2154 1.1 christos } 2155 1.1 christos num++; 2156 1.1 christos data = ixfr_data_prev(zone->ixfr, data, &prevcount); 2157 1.1 christos } 2158 1.1 christos } 2159 1.1 christos 2160 1.1 christos void ixfr_write_to_file(struct zone* zone, const char* zfile) 2161 1.1 christos { 2162 1.1 christos int dest_num_files = 0; 2163 1.1 christos /* we just wrote the zonefile zfile, and it is time to write 2164 1.1 christos * the IXFR contents to the disk too. */ 2165 1.1 christos /* find out what the target number of files is that we want on 2166 1.1 christos * the disk */ 2167 1.1 christos dest_num_files = ixfr_target_number_files(zone); 2168 1.1 christos 2169 1.1 christos /* delete if we have more than we need */ 2170 1.1 christos ixfr_delete_superfluous_files(zone, zfile, dest_num_files); 2171 1.1 christos 2172 1.1 christos /* delete if we have too much in memory */ 2173 1.1 christos ixfr_delete_memory_items(zone, dest_num_files); 2174 1.1 christos 2175 1.1 christos /* rename the transfers that we have that already have a file */ 2176 1.1 christos if(!ixfr_rename_files(zone, zfile, dest_num_files)) 2177 1.1 christos return; 2178 1.1 christos 2179 1.1 christos /* write the transfers that are not written yet */ 2180 1.1 christos ixfr_write_files(zone, zfile); 2181 1.1 christos } 2182 1.1 christos 2183 1.1 christos /* delete from domain table */ 2184 1.1 christos static void domain_table_delete(struct domain_table* table, 2185 1.1 christos struct domain* domain) 2186 1.1 christos { 2187 1.1.1.3 christos /* first adjust the number list so that domain is the last one */ 2188 1.1.1.3 christos numlist_make_last(table, domain); 2189 1.1.1.3 christos /* pop off the domain from the number list */ 2190 1.1.1.3 christos (void)numlist_pop_last(table); 2191 1.1.1.3 christos 2192 1.1 christos #ifdef USE_RADIX_TREE 2193 1.1 christos radix_delete(table->nametree, domain->rnode); 2194 1.1 christos #else 2195 1.1 christos rbtree_delete(table->names_to_domains, domain->node.key); 2196 1.1 christos #endif 2197 1.1 christos } 2198 1.1 christos 2199 1.1 christos /* can we delete temp domain */ 2200 1.1 christos static int can_del_temp_domain(struct domain* domain) 2201 1.1 christos { 2202 1.1 christos struct domain* n; 2203 1.1 christos /* we want to keep the zone apex */ 2204 1.1 christos if(domain->is_apex) 2205 1.1 christos return 0; 2206 1.1 christos if(domain->rrsets) 2207 1.1 christos return 0; 2208 1.1 christos if(domain->usage) 2209 1.1 christos return 0; 2210 1.1 christos /* check if there are domains under it */ 2211 1.1 christos n = domain_next(domain); 2212 1.1 christos if(n && domain_is_subdomain(n, domain)) 2213 1.1 christos return 0; 2214 1.1 christos return 1; 2215 1.1 christos } 2216 1.1 christos 2217 1.1 christos /* delete temporary domain */ 2218 1.1 christos static void ixfr_temp_deldomain(struct domain_table* temptable, 2219 1.1.1.3 christos struct domain* domain, struct domain* avoid) 2220 1.1 christos { 2221 1.1 christos struct domain* p; 2222 1.1.1.3 christos if(domain == avoid || !can_del_temp_domain(domain)) 2223 1.1 christos return; 2224 1.1 christos p = domain->parent; 2225 1.1 christos /* see if this domain is someones wildcard-child-closest-match, 2226 1.1 christos * which can only be the parent, and then it should use the 2227 1.1 christos * one-smaller than this domain as closest-match. */ 2228 1.1 christos if(domain->parent && 2229 1.1 christos domain->parent->wildcard_child_closest_match == domain) 2230 1.1 christos domain->parent->wildcard_child_closest_match = 2231 1.1 christos domain_previous_existing_child(domain); 2232 1.1 christos domain_table_delete(temptable, domain); 2233 1.1 christos while(p) { 2234 1.1 christos struct domain* up = p->parent; 2235 1.1.1.3 christos if(p == avoid || !can_del_temp_domain(p)) 2236 1.1 christos break; 2237 1.1 christos if(p->parent && p->parent->wildcard_child_closest_match == p) 2238 1.1 christos p->parent->wildcard_child_closest_match = 2239 1.1 christos domain_previous_existing_child(p); 2240 1.1 christos domain_table_delete(temptable, p); 2241 1.1 christos p = up; 2242 1.1 christos } 2243 1.1 christos } 2244 1.1 christos 2245 1.1 christos /* clear out the just read RR from the temp table */ 2246 1.1 christos static void clear_temp_table_of_rr(struct domain_table* temptable, 2247 1.1 christos struct zone* tempzone, struct rr* rr) 2248 1.1 christos { 2249 1.1.1.3 christos const nsd_type_descriptor_type* descriptor = 2250 1.1.1.3 christos nsd_type_descriptor(rr->type); 2251 1.1 christos 2252 1.1 christos /* clear domains in the rdata */ 2253 1.1.1.3 christos if(descriptor->has_references) { 2254 1.1.1.3 christos uint16_t offset = 0; 2255 1.1.1.3 christos size_t i; 2256 1.1.1.3 christos for(i=0; i < descriptor->rdata.length; i++) { 2257 1.1.1.3 christos uint16_t field_len; 2258 1.1.1.3 christos struct domain* domain; 2259 1.1.1.3 christos if(rr->rdlength == offset && 2260 1.1.1.3 christos descriptor->rdata.fields[i].is_optional) 2261 1.1.1.3 christos break; /* There are no more rdata fields. */ 2262 1.1.1.3 christos if(!lookup_rdata_field_entry(descriptor, i, rr, offset, 2263 1.1.1.3 christos &field_len, &domain)) 2264 1.1.1.3 christos break; /* malformed */ 2265 1.1.1.3 christos if(domain != NULL) { 2266 1.1.1.3 christos /* The field is a domain reference. */ 2267 1.1.1.3 christos /* clear out that dname */ 2268 1.1.1.3 christos domain->usage --; 2269 1.1.1.3 christos if(domain != tempzone->apex && 2270 1.1.1.3 christos domain->usage == 0) 2271 1.1.1.3 christos ixfr_temp_deldomain(temptable, domain, 2272 1.1.1.3 christos rr->owner); 2273 1.1.1.3 christos } 2274 1.1.1.3 christos offset += field_len; 2275 1.1 christos } 2276 1.1 christos } 2277 1.1 christos 2278 1.1 christos /* clear domain_parsed */ 2279 1.1 christos if(rr->owner == tempzone->apex) { 2280 1.1 christos tempzone->apex->rrsets = NULL; 2281 1.1 christos tempzone->soa_rrset = NULL; 2282 1.1 christos tempzone->soa_nx_rrset = NULL; 2283 1.1 christos tempzone->ns_rrset = NULL; 2284 1.1 christos } else { 2285 1.1 christos rr->owner->rrsets = NULL; 2286 1.1 christos if(rr->owner->usage == 0) { 2287 1.1.1.3 christos ixfr_temp_deldomain(temptable, rr->owner, NULL); 2288 1.1 christos } 2289 1.1 christos } 2290 1.1 christos } 2291 1.1 christos 2292 1.1 christos /* read ixfr data new SOA */ 2293 1.1 christos static int ixfr_data_readnewsoa(struct ixfr_data* data, struct zone* zone, 2294 1.1.1.3 christos struct rr *rr, zone_parser_t *parser, struct region* tempregion, 2295 1.1 christos struct domain_table* temptable, struct zone* tempzone, 2296 1.1 christos uint32_t dest_serial) 2297 1.1 christos { 2298 1.1 christos size_t capacity = 0; 2299 1.1.1.3 christos int code; 2300 1.1 christos if(rr->type != TYPE_SOA) { 2301 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: IXFR data does not start with SOA", 2302 1.1.1.3 christos zone->opts->name); 2303 1.1 christos return 0; 2304 1.1 christos } 2305 1.1 christos if(rr->klass != CLASS_IN) { 2306 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: IXFR data is not class IN", 2307 1.1.1.3 christos zone->opts->name); 2308 1.1 christos return 0; 2309 1.1 christos } 2310 1.1 christos if(!zone->apex) { 2311 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: zone has no apex, no zone data", 2312 1.1.1.3 christos zone->opts->name); 2313 1.1 christos return 0; 2314 1.1 christos } 2315 1.1 christos if(dname_compare(domain_dname(zone->apex), domain_dname(rr->owner)) != 0) { 2316 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: IXFR data wrong SOA for zone %s", 2317 1.1.1.3 christos zone->opts->name, domain_to_string(rr->owner)); 2318 1.1 christos return 0; 2319 1.1 christos } 2320 1.1 christos data->newserial = soa_rr_get_serial(rr); 2321 1.1 christos if(data->newserial != dest_serial) { 2322 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: IXFR data contains the wrong version, serial %u but want destination serial %u", 2323 1.1.1.3 christos zone->opts->name, data->newserial, 2324 1.1 christos dest_serial); 2325 1.1 christos return 0; 2326 1.1 christos } 2327 1.1.1.3 christos if((code=ixfr_putrr(rr, &data->newsoa, &data->newsoa_len, &capacity)) 2328 1.1.1.3 christos <= 0) { 2329 1.1.1.3 christos if(code == -1) 2330 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: cannot parse rdata format", 2331 1.1.1.3 christos zone->opts->name); 2332 1.1.1.3 christos else zone_error(parser, "zone %s ixfr data: cannot allocate space", 2333 1.1.1.3 christos zone->opts->name); 2334 1.1 christos return 0; 2335 1.1 christos } 2336 1.1 christos clear_temp_table_of_rr(temptable, tempzone, rr); 2337 1.1 christos region_free_all(tempregion); 2338 1.1 christos ixfr_trim_capacity(&data->newsoa, &data->newsoa_len, &capacity); 2339 1.1 christos return 1; 2340 1.1 christos } 2341 1.1 christos 2342 1.1 christos /* read ixfr data old SOA */ 2343 1.1 christos static int ixfr_data_readoldsoa(struct ixfr_data* data, struct zone* zone, 2344 1.1.1.3 christos struct rr *rr, zone_parser_t *parser, struct region* tempregion, 2345 1.1 christos struct domain_table* temptable, struct zone* tempzone, 2346 1.1 christos uint32_t* dest_serial) 2347 1.1 christos { 2348 1.1 christos size_t capacity = 0; 2349 1.1 christos if(rr->type != TYPE_SOA) { 2350 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: IXFR data 2nd RR is not SOA", 2351 1.1.1.3 christos zone->opts->name); 2352 1.1 christos return 0; 2353 1.1 christos } 2354 1.1 christos if(rr->klass != CLASS_IN) { 2355 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: IXFR data 2ndSOA is not class IN", 2356 1.1.1.3 christos zone->opts->name); 2357 1.1 christos return 0; 2358 1.1 christos } 2359 1.1 christos if(!zone->apex) { 2360 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: zone has no apex, no zone data", 2361 1.1.1.3 christos zone->opts->name); 2362 1.1 christos return 0; 2363 1.1 christos } 2364 1.1 christos if(dname_compare(domain_dname(zone->apex), domain_dname(rr->owner)) != 0) { 2365 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: IXFR data wrong 2nd SOA for zone %s", 2366 1.1.1.3 christos zone->opts->name, domain_to_string(rr->owner)); 2367 1.1 christos return 0; 2368 1.1 christos } 2369 1.1 christos data->oldserial = soa_rr_get_serial(rr); 2370 1.1.1.3 christos if(!ixfr_putrr(rr, &data->oldsoa, &data->oldsoa_len, &capacity)) { 2371 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: cannot allocate space", 2372 1.1.1.3 christos zone->opts->name); 2373 1.1 christos return 0; 2374 1.1 christos } 2375 1.1 christos clear_temp_table_of_rr(temptable, tempzone, rr); 2376 1.1 christos region_free_all(tempregion); 2377 1.1 christos ixfr_trim_capacity(&data->oldsoa, &data->oldsoa_len, &capacity); 2378 1.1 christos *dest_serial = data->oldserial; 2379 1.1 christos return 1; 2380 1.1 christos } 2381 1.1 christos 2382 1.1 christos /* read ixfr data del section */ 2383 1.1 christos static int ixfr_data_readdel(struct ixfr_data* data, struct zone* zone, 2384 1.1.1.3 christos struct rr *rr, zone_parser_t *parser, struct region* tempregion, 2385 1.1 christos struct domain_table* temptable, struct zone* tempzone) 2386 1.1 christos { 2387 1.1 christos size_t capacity = 0; 2388 1.1.1.3 christos if(!ixfr_putrr(rr, &data->del, &data->del_len, &capacity)) { 2389 1.1.1.3 christos zone_error(parser, "zone %s ixdr data: cannot allocate space", 2390 1.1.1.3 christos zone->opts->name); 2391 1.1.1.3 christos return 0; 2392 1.1.1.3 christos } 2393 1.1.1.3 christos clear_temp_table_of_rr(temptable, tempzone, rr); 2394 1.1.1.3 christos /* check SOA and also serial, because there could be other 2395 1.1.1.3 christos * add and del sections from older versions collated, we can 2396 1.1.1.3 christos * see this del section end when it has the serial */ 2397 1.1.1.3 christos if(rr->type != TYPE_SOA && soa_rr_get_serial(rr) != data->newserial) { 2398 1.1 christos region_free_all(tempregion); 2399 1.1.1.3 christos return 1; 2400 1.1 christos } 2401 1.1.1.3 christos region_free_all(tempregion); 2402 1.1 christos ixfr_trim_capacity(&data->del, &data->del_len, &capacity); 2403 1.1.1.3 christos return 2; 2404 1.1 christos } 2405 1.1 christos 2406 1.1 christos /* read ixfr data add section */ 2407 1.1 christos static int ixfr_data_readadd(struct ixfr_data* data, struct zone* zone, 2408 1.1.1.3 christos struct rr *rr, zone_parser_t *parser, struct region* tempregion, 2409 1.1 christos struct domain_table* temptable, struct zone* tempzone) 2410 1.1 christos { 2411 1.1 christos size_t capacity = 0; 2412 1.1.1.3 christos if(!ixfr_putrr(rr, &data->add, &data->add_len, &capacity)) { 2413 1.1.1.3 christos zone_error(parser, "zone %s ixfr data: cannot allocate space", 2414 1.1.1.3 christos zone->opts->name); 2415 1.1.1.3 christos return 0; 2416 1.1.1.3 christos } 2417 1.1.1.3 christos clear_temp_table_of_rr(temptable, tempzone, rr); 2418 1.1.1.3 christos if(rr->type != TYPE_SOA || soa_rr_get_serial(rr) != data->newserial) { 2419 1.1 christos region_free_all(tempregion); 2420 1.1.1.3 christos return 1; 2421 1.1 christos } 2422 1.1.1.3 christos region_free_all(tempregion); 2423 1.1 christos ixfr_trim_capacity(&data->add, &data->add_len, &capacity); 2424 1.1.1.3 christos return 2; 2425 1.1.1.3 christos } 2426 1.1.1.3 christos 2427 1.1.1.3 christos struct ixfr_data_state { 2428 1.1.1.3 christos struct zone *zone; 2429 1.1.1.3 christos struct ixfr_data *data; 2430 1.1.1.3 christos struct region *stayregion; 2431 1.1.1.3 christos struct region *tempregion; 2432 1.1.1.3 christos struct domain_table *temptable; 2433 1.1.1.3 christos struct zone *tempzone; 2434 1.1.1.3 christos uint32_t *dest_serial; 2435 1.1.1.3 christos size_t rr_count, soa_rr_count; 2436 1.1.1.3 christos }; 2437 1.1.1.3 christos 2438 1.1.1.3 christos /* read one RR from file */ 2439 1.1.1.3 christos static int32_t ixfr_data_accept( 2440 1.1.1.3 christos zone_parser_t *parser, 2441 1.1.1.3 christos const zone_name_t *name, 2442 1.1.1.3 christos uint16_t type, 2443 1.1.1.3 christos uint16_t class, 2444 1.1.1.3 christos uint32_t ttl, 2445 1.1.1.3 christos uint16_t rdlength, 2446 1.1.1.3 christos const uint8_t *rdata, 2447 1.1.1.3 christos void *user_data) 2448 1.1.1.3 christos { 2449 1.1.1.3 christos struct rr *rr; 2450 1.1.1.3 christos const struct dname *dname; 2451 1.1.1.3 christos struct domain *domain; 2452 1.1.1.3 christos struct buffer buffer; 2453 1.1.1.3 christos struct ixfr_data_state *state = (struct ixfr_data_state *)user_data; 2454 1.1.1.3 christos const struct nsd_type_descriptor *descriptor; 2455 1.1.1.3 christos int32_t code; 2456 1.1.1.3 christos 2457 1.1.1.3 christos assert(parser); 2458 1.1.1.3 christos 2459 1.1.1.3 christos buffer_create_from(&buffer, rdata, rdlength); 2460 1.1.1.3 christos 2461 1.1.1.3 christos dname = dname_make(state->tempregion, name->octets, 1); 2462 1.1.1.3 christos assert(dname); 2463 1.1.1.3 christos domain = domain_table_insert(state->temptable, dname); 2464 1.1.1.3 christos assert(domain); 2465 1.1.1.3 christos 2466 1.1.1.3 christos descriptor = nsd_type_descriptor(type); 2467 1.1.1.3 christos code = descriptor->read_rdata(state->temptable, rdlength, &buffer, &rr); 2468 1.1.1.3 christos /* This has validated the fields on the rdata. The content can be 2469 1.1.1.3 christos * dealt with, if this is successful, later on by iterating over the 2470 1.1.1.3 christos * rdata fields. For compression, and for printout, the rdata field 2471 1.1.1.3 christos * format is known to be good. 2472 1.1.1.3 christos * If the field validation is not needed, the wireformat in the 2473 1.1.1.3 christos * rdata, rdlength could have been used to add to the ixfr store. 2474 1.1.1.3 christos * But it is more prudent to validate the rdata fields. */ 2475 1.1.1.3 christos if(code < 0) { 2476 1.1.1.3 christos if(verbosity >= 3) { 2477 1.1.1.3 christos zone_log(parser, ZONE_ERROR, "the RR rdata fields are wrong for the type"); 2478 1.1.1.3 christos } 2479 1.1.1.3 christos VERBOSITY(3, (LOG_INFO, "zone %s IXFR bad RR, cannot parse " 2480 1.1.1.3 christos "rdata of %s %s %s", state->zone->opts->name, 2481 1.1.1.3 christos dname_to_string(dname, NULL), rrtype_to_string(type), 2482 1.1.1.3 christos read_rdata_fail_str(code))); 2483 1.1.1.3 christos if(code == TRUNCATED) 2484 1.1.1.3 christos return ZONE_OUT_OF_MEMORY; 2485 1.1.1.3 christos return ZONE_BAD_PARAMETER; 2486 1.1.1.3 christos } 2487 1.1.1.3 christos assert(rr); 2488 1.1.1.3 christos rr->owner = domain; 2489 1.1.1.3 christos rr->ttl = ttl; 2490 1.1.1.3 christos rr->type = type; 2491 1.1.1.3 christos rr->klass = class; 2492 1.1.1.3 christos 2493 1.1.1.3 christos if (state->rr_count == 0) { 2494 1.1.1.3 christos if (!ixfr_data_readnewsoa(state->data, state->zone, rr, parser, 2495 1.1.1.3 christos state->tempregion, state->temptable, 2496 1.1.1.3 christos state->tempzone, *state->dest_serial)) 2497 1.1.1.3 christos return ZONE_SEMANTIC_ERROR; 2498 1.1.1.3 christos } else if (state->rr_count == 1) { 2499 1.1.1.3 christos if(!ixfr_data_readoldsoa(state->data, state->zone, rr, parser, 2500 1.1.1.3 christos state->tempregion, state->temptable, 2501 1.1.1.3 christos state->tempzone, state->dest_serial)) 2502 1.1.1.3 christos return ZONE_SEMANTIC_ERROR; 2503 1.1.1.3 christos } else if (state->soa_rr_count == 0) { 2504 1.1.1.3 christos switch (ixfr_data_readdel(state->data, state->zone, rr, parser, 2505 1.1.1.3 christos state->tempregion, state->temptable, 2506 1.1.1.3 christos state->tempzone)) 2507 1.1.1.3 christos { 2508 1.1.1.3 christos case 0: 2509 1.1.1.3 christos return ZONE_SEMANTIC_ERROR; 2510 1.1.1.3 christos case 1: 2511 1.1.1.3 christos break; 2512 1.1.1.3 christos case 2: 2513 1.1.1.3 christos state->soa_rr_count++; 2514 1.1.1.3 christos break; 2515 1.1.1.3 christos } 2516 1.1.1.3 christos } else if (state->soa_rr_count == 1) { 2517 1.1.1.3 christos switch (ixfr_data_readadd(state->data, state->zone, rr, parser, 2518 1.1.1.3 christos state->tempregion, state->temptable, 2519 1.1.1.3 christos state->tempzone)) 2520 1.1.1.3 christos { 2521 1.1.1.3 christos case 0: 2522 1.1.1.3 christos return ZONE_SEMANTIC_ERROR; 2523 1.1.1.3 christos case 1: 2524 1.1.1.3 christos break; 2525 1.1.1.3 christos case 2: 2526 1.1.1.3 christos state->soa_rr_count++; 2527 1.1.1.3 christos break; 2528 1.1.1.3 christos } 2529 1.1.1.3 christos } 2530 1.1.1.3 christos 2531 1.1.1.3 christos state->rr_count++; 2532 1.1.1.3 christos return 0; 2533 1.1.1.3 christos } 2534 1.1.1.3 christos 2535 1.1.1.3 christos static void ixfr_data_log( 2536 1.1.1.3 christos zone_parser_t *parser, 2537 1.1.1.3 christos uint32_t category, 2538 1.1.1.3 christos const char *file, 2539 1.1.1.3 christos size_t line, 2540 1.1.1.3 christos const char *message, 2541 1.1.1.3 christos void *user_data) 2542 1.1.1.3 christos { 2543 1.1.1.3 christos int priority = LOG_ERR; 2544 1.1.1.3 christos (void)parser; 2545 1.1.1.3 christos (void)file; 2546 1.1.1.3 christos (void)line; 2547 1.1.1.3 christos (void)user_data; 2548 1.1.1.3 christos if (category == ZONE_WARNING) 2549 1.1.1.3 christos priority = LOG_WARNING; 2550 1.1.1.3 christos log_msg(priority, "%s", message); 2551 1.1 christos } 2552 1.1 christos 2553 1.1 christos /* read ixfr data from file */ 2554 1.1.1.3 christos static int ixfr_data_read(struct nsd* nsd, struct zone* zone, 2555 1.1 christos const char* ixfrfile, uint32_t* dest_serial, int file_num) 2556 1.1 christos { 2557 1.1.1.3 christos struct ixfr_data_state state = { 0 }; 2558 1.1 christos 2559 1.1.1.3 christos if(!zone->apex) { 2560 1.1.1.3 christos return 0; 2561 1.1.1.3 christos } 2562 1.1 christos if(zone->ixfr && 2563 1.1 christos zone->ixfr->data->count == zone->opts->pattern->ixfr_number) { 2564 1.1 christos VERBOSITY(3, (LOG_INFO, "zone %s skip %s IXFR data because only %d ixfr-number configured", 2565 1.1 christos zone->opts->name, ixfrfile, (int)zone->opts->pattern->ixfr_number)); 2566 1.1 christos return 0; 2567 1.1 christos } 2568 1.1 christos 2569 1.1 christos /* the file has header comments, new soa, old soa, delsection, 2570 1.1 christos * addsection. The delsection and addsection end in a SOA of oldver 2571 1.1 christos * and newver respectively. */ 2572 1.1.1.3 christos state.zone = zone; 2573 1.1.1.3 christos state.data = xalloc_zero(sizeof(*state.data)); 2574 1.1.1.3 christos state.data->file_num = file_num; 2575 1.1 christos 2576 1.1.1.3 christos state.dest_serial = dest_serial; 2577 1.1 christos /* the temp region is cleared after every RR */ 2578 1.1.1.3 christos state.tempregion = region_create(xalloc, free); 2579 1.1 christos /* the stay region holds the temporary data that stays between RRs */ 2580 1.1.1.3 christos state.stayregion = region_create(xalloc, free); 2581 1.1.1.3 christos state.temptable = domain_table_create(state.stayregion); 2582 1.1.1.3 christos state.tempzone = region_alloc_zero(state.stayregion, sizeof(*state.tempzone)); 2583 1.1 christos if(!zone->apex) { 2584 1.1.1.3 christos ixfr_data_free(state.data); 2585 1.1.1.3 christos region_destroy(state.tempregion); 2586 1.1.1.3 christos region_destroy(state.stayregion); 2587 1.1 christos return 0; 2588 1.1 christos } 2589 1.1.1.3 christos state.tempzone->apex = domain_table_insert(state.temptable, 2590 1.1 christos domain_dname(zone->apex)); 2591 1.1.1.3 christos state.temptable->root->usage++; 2592 1.1.1.3 christos state.tempzone->apex->usage++; 2593 1.1.1.3 christos state.tempzone->opts = zone->opts; 2594 1.1 christos /* switch to per RR region for new allocations in temp domain table */ 2595 1.1.1.3 christos state.temptable->region = state.tempregion; 2596 1.1 christos 2597 1.1.1.3 christos { 2598 1.1.1.3 christos const struct dname *origin; 2599 1.1.1.3 christos zone_parser_t parser; 2600 1.1.1.3 christos zone_options_t options; 2601 1.1.1.3 christos zone_name_buffer_t name_buffer; 2602 1.1.1.3 christos zone_rdata_buffer_t rdata_buffer; 2603 1.1.1.3 christos zone_buffers_t buffers = { 1, &name_buffer, &rdata_buffer }; 2604 1.1.1.3 christos memset(&options, 0, sizeof(options)); 2605 1.1.1.3 christos 2606 1.1.1.3 christos origin = domain_dname(zone->apex); 2607 1.1.1.3 christos options.origin.octets = dname_name(origin); 2608 1.1.1.3 christos options.origin.length = origin->name_size; 2609 1.1.1.3 christos options.no_includes = true; 2610 1.1.1.3 christos options.pretty_ttls = false; 2611 1.1.1.3 christos options.default_ttl = DEFAULT_TTL; 2612 1.1.1.3 christos options.default_class = CLASS_IN; 2613 1.1.1.3 christos options.log.callback = &ixfr_data_log; 2614 1.1.1.3 christos options.accept.callback = &ixfr_data_accept; 2615 1.1.1.3 christos 2616 1.1.1.3 christos if(zone_parse(&parser, &options, &buffers, ixfrfile, &state) != 0) { 2617 1.1.1.3 christos ixfr_data_free(state.data); 2618 1.1.1.3 christos region_destroy(state.tempregion); 2619 1.1.1.3 christos region_destroy(state.stayregion); 2620 1.1.1.3 christos return 0; 2621 1.1.1.3 christos } 2622 1.1 christos } 2623 1.1 christos 2624 1.1.1.3 christos region_destroy(state.tempregion); 2625 1.1.1.3 christos region_destroy(state.stayregion); 2626 1.1 christos 2627 1.1 christos if(!zone->ixfr) 2628 1.1 christos zone->ixfr = zone_ixfr_create(nsd); 2629 1.1 christos if(zone->opts->pattern->ixfr_size != 0 && 2630 1.1.1.3 christos zone->ixfr->total_size + ixfr_data_size(state.data) > 2631 1.1 christos zone->opts->pattern->ixfr_size) { 2632 1.1 christos VERBOSITY(3, (LOG_INFO, "zone %s skip %s IXFR data because only ixfr-size: %u configured, and it is %u size", 2633 1.1.1.3 christos zone->opts->name, ixfrfile, (unsigned)zone->opts->pattern->ixfr_size, (unsigned)ixfr_data_size(state.data))); 2634 1.1.1.3 christos ixfr_data_free(state.data); 2635 1.1 christos return 0; 2636 1.1 christos } 2637 1.1.1.3 christos zone_ixfr_add(zone->ixfr, state.data, 0); 2638 1.1 christos VERBOSITY(3, (LOG_INFO, "zone %s read %s IXFR data of %u bytes", 2639 1.1.1.3 christos zone->opts->name, ixfrfile, (unsigned)ixfr_data_size(state.data))); 2640 1.1 christos return 1; 2641 1.1 christos } 2642 1.1 christos 2643 1.1 christos /* try to read the next ixfr file. returns false if it fails or if it 2644 1.1 christos * does not fit in the configured sizes */ 2645 1.1 christos static int ixfr_read_one_more_file(struct nsd* nsd, struct zone* zone, 2646 1.1 christos const char* zfile, int num_files, uint32_t *dest_serial) 2647 1.1 christos { 2648 1.1 christos char ixfrfile[1024+24]; 2649 1.1.1.3 christos struct stat statbuf; 2650 1.1 christos int file_num = num_files+1; 2651 1.1 christos make_ixfr_name(ixfrfile, sizeof(ixfrfile), zfile, file_num); 2652 1.1.1.3 christos /* if the file does not exist, all transfers have been read */ 2653 1.1.1.3 christos if (stat(ixfrfile, &statbuf) != 0 && errno == ENOENT) 2654 1.1 christos return 0; 2655 1.1.1.3 christos return ixfr_data_read(nsd, zone, ixfrfile, dest_serial, file_num); 2656 1.1 christos } 2657 1.1 christos 2658 1.1 christos void ixfr_read_from_file(struct nsd* nsd, struct zone* zone, const char* zfile) 2659 1.1 christos { 2660 1.1 christos uint32_t serial; 2661 1.1 christos int num_files = 0; 2662 1.1 christos /* delete the existing data, the zone data in memory has likely 2663 1.1 christos * changed, eg. due to reading a new zonefile. So that needs new 2664 1.1 christos * IXFRs */ 2665 1.1 christos zone_ixfr_clear(zone->ixfr); 2666 1.1 christos 2667 1.1 christos /* track the serial number that we need to end up with, and check 2668 1.1 christos * that the IXFRs match up and result in the required version */ 2669 1.1 christos serial = zone_get_current_serial(zone); 2670 1.1 christos 2671 1.1 christos while(ixfr_read_one_more_file(nsd, zone, zfile, num_files, &serial)) { 2672 1.1 christos num_files++; 2673 1.1 christos } 2674 1.1 christos if(num_files > 0) { 2675 1.1 christos VERBOSITY(1, (LOG_INFO, "zone %s read %d IXFR transfers with success", 2676 1.1 christos zone->opts->name, num_files)); 2677 1.1 christos } 2678 1.1 christos } 2679