Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  * ixfr.h -- generating IXFR responses.
      3  *
      4  * Copyright (c) 2021, NLnet Labs. All rights reserved.
      5  *
      6  * See LICENSE for the license.
      7  *
      8  */
      9 
     10 #ifndef IXFR_H
     11 #define IXFR_H
     12 struct nsd;
     13 #include "query.h"
     14 #include "rbtree.h"
     15 struct ixfr_data;
     16 struct zone;
     17 struct buffer;
     18 struct region;
     19 
     20 /* default for number of ixfr versions in files */
     21 #define IXFR_NUMBER_DEFAULT 5 /* number of versions */
     22 /* default for IXFR storage */
     23 #define IXFR_SIZE_DEFAULT 1048576 /* in bytes, 1M */
     24 
     25 /* data structure that stores IXFR contents for a zone. */
     26 struct zone_ixfr {
     27 	/* Items are of type ixfr_data. The key is old_serial.
     28 	 * So it can be looked up on an incoming IXFR. They are sorted
     29 	 * by old_serial, so the looked up and next are the versions needed.
     30 	 * Tree of ixfr data for versions */
     31 	struct rbtree* data;
     32 	/* total size stored at this time, in bytes,
     33 	 * sum of sizes of the ixfr data elements */
     34 	size_t total_size;
     35 	/* the oldest serial number in the tree, searchable by old_serial */
     36 	uint32_t oldest_serial;
     37 	/* the newest serial number in the tree, that is searchable in the
     38 	 * tree, so it is the old_serial of the newest data entry, that
     39 	 * has an even newer new_serial of that entry */
     40 	uint32_t newest_serial;
     41 };
     42 
     43 /* Data structure that stores one IXFR.
     44  * The RRs are stored in uncompressed wireformat, that means
     45  * an uncompressed domain name, type, class, TTL, rdatalen,
     46  * uncompressed rdata in wireformat.
     47  *
     48  * The data structure is formatted like this so that making an IXFR
     49  * that moves across several versions can be done by collating the
     50  * pieces precisely from the versions involved. In particular, for
     51  * an IXFR from olddata to newdata, for a combined output:
     52  * newdata.newsoa olddata.oldsoa olddata.del olddata.add
     53  * newdata.del newdata.add
     54  * in sequence should produce a valid, non-condensed, IXFR with multiple
     55  * versions inside.
     56  */
     57 struct ixfr_data {
     58 	/* Node in the rbtree. Key is oldserial */
     59 	struct rbnode node;
     60 	/* from what serial the IXFR starts from, the 'old' serial */
     61 	uint32_t oldserial;
     62 	/* where to IXFR goes to, the 'new' serial */
     63 	uint32_t newserial;
     64 	/* the new SOA record, with newserial */
     65 	uint8_t* newsoa;
     66 	/* byte length of the uncompressed wireformat RR in newsoa */
     67 	size_t newsoa_len;
     68 	/* the old SOA record, with oldserial */
     69 	uint8_t* oldsoa;
     70 	/* byte length of the uncompressed wireformat RR in oldsoa*/
     71 	size_t oldsoa_len;
     72 	/* the deleted RRs, ends with the newserial SOA record.
     73 	 * if the ixfr is collated out multiple versions, then
     74 	 * this deleted RRs section contains several add and del sections
     75 	 * for the older versions, and ends with the last del section,
     76 	 * and the SOA record with the newserial.
     77 	 * That is everything except the final add section for newserial. */
     78 	uint8_t* del;
     79 	/* byte length of the uncompressed wireformat RRs in del */
     80 	size_t del_len;
     81 	/* the added RRs, ends with the newserial SOA record. */
     82 	uint8_t* add;
     83 	/* byte length of the uncompressed wireformat RRs in add */
     84 	size_t add_len;
     85 	/* log string (if not NULL) about where data is from */
     86 	char* log_str;
     87 	/* the number of the ixfr.<num> file on disk. If 0, there is no
     88 	 * file. If 1, it is file ixfr<nothingafterit>. */
     89 	int file_num;
     90 };
     91 
     92 /* process queries in IXFR state */
     93 query_state_type query_ixfr(struct nsd *nsd, struct query *query);
     94 
     95 /*
     96  * While an IXFR is processed, in incoming IXFR that is downloaded by NSD,
     97  * this structure keeps track of how to store the data from it. That data
     98  * can then be used to answer IXFR queries.
     99  *
    100  * The structure keeps track of allocation data for the IXFR records.
    101  * If it is cancelled, that is flagged so storage stops.
    102  */
    103 struct ixfr_store {
    104 	/* the zone info, with options and zone ixfr reference */
    105 	struct zone* zone;
    106 	/* are we cancelled, it is not an IXFR, no need to store information
    107 	 * any more. */
    108 	int cancelled;
    109 	/* data has been trimmed and newsoa added */
    110 	int data_trimmed;
    111 	/* the ixfr data that we are storing into */
    112 	struct ixfr_data* data;
    113 	/* capacity for the delrrs storage, size of ixfr del allocation */
    114 	size_t del_capacity;
    115 	/* capacity for the addrrs storage, size of ixfr add allocation */
    116 	size_t add_capacity;
    117 };
    118 
    119 /*
    120  * Start the storage of the IXFR data from this IXFR.
    121  * If it returns NULL, the IXFR storage stops. On malloc failure, the
    122  * storage is returned NULL, or cancelled if failures happen later on.
    123  *
    124  * When done, the finish routine links the data into the memory for the zone.
    125  * If it turns out to not be used, use the cancel routine. Or the free
    126  * routine if the ixfr_store itself needs to be deleted too, like on error.
    127  *
    128  * zone: the zone structure
    129  * ixfr_store_mem: preallocated by caller, used to allocate the store struct.
    130  * old_serial: the start serial of the IXFR.
    131  * new_serial: the end serial of the IXFR.
    132  * return NULL or a fresh ixfr_store structure for adding records to the
    133  * 	IXFR with this serial number. The NULL is on error.
    134  */
    135 struct ixfr_store* ixfr_store_start(struct zone* zone,
    136 	struct ixfr_store* ixfr_store_mem);
    137 
    138 /*
    139  * Cancel the ixfr store in progress. The pointer remains valid, no store done.
    140  * ixfr_store: this is set to cancel.
    141  */
    142 void ixfr_store_cancel(struct ixfr_store* ixfr_store);
    143 
    144 /*
    145  * Free ixfr store structure, it is no longer used.
    146  * ixfr_store: deleted
    147  */
    148 void ixfr_store_free(struct ixfr_store* ixfr_store);
    149 
    150 /*
    151  * Finish ixfr store processing. Links the data into the zone ixfr data.
    152  * ixfr_store: Data is linked into the zone struct. The ixfr_store is freed.
    153  * nsd: nsd structure for allocation region and global options.
    154  * log_buf: log string for the update.
    155  */
    156 void ixfr_store_finish(struct ixfr_store* ixfr_store, struct nsd* nsd,
    157 	char* log_buf);
    158 
    159 /* finish just the data activities, trim up the storage and append newsoa */
    160 void ixfr_store_finish_data(struct ixfr_store* ixfr_store);
    161 
    162 /*
    163  * Add the new SOA record to the ixfr store.
    164  * ixfr_store: stores ixfr data that is collected.
    165  * ttl: the TTL of the SOA record
    166  * packet: DNS packet that contains the SOA. position restored on function
    167  * 	exit.
    168  * rrlen: wire rdata length of the SOA.
    169  */
    170 void ixfr_store_add_newsoa(struct ixfr_store* ixfr_store, uint32_t ttl,
    171 	struct buffer* packet, size_t rrlen);
    172 
    173 /*
    174  * Add the old SOA record to the ixfr store.
    175  * ixfr_store: stores ixfr data that is collected.
    176  * ttl: the TTL of the SOA record
    177  * packet: DNS packet that contains the SOA. position restored on function
    178  * 	exit.
    179  * rrlen: wire rdata length of the SOA.
    180  */
    181 void ixfr_store_add_oldsoa(struct ixfr_store* ixfr_store, uint32_t ttl,
    182 	struct buffer* packet, size_t rrlen);
    183 
    184 void ixfr_store_delrr(struct ixfr_store* ixfr_store,
    185 	const rr_type *rr);
    186 void ixfr_store_addrr(struct ixfr_store* ixfr_store, const rr_type *rr);
    187 int ixfr_store_addrr_rdatas(struct ixfr_store* ixfr_store, const rr_type *rr);
    188 int ixfr_store_delrr_uncompressed(struct ixfr_store* ixfr_store,
    189 	uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass,
    190 	uint32_t ttl, uint8_t* rdata, size_t rdata_len);
    191 int ixfr_store_add_newsoa_rdatas(struct ixfr_store* ixfr_store,
    192 	const rr_type* rr);
    193 int ixfr_store_oldsoa_uncompressed(struct ixfr_store* ixfr_store,
    194 	uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass,
    195 	uint32_t ttl, uint8_t* rdata, size_t rdata_len);
    196 
    197 /* an AXFR has been received, the IXFRs do not connect in version number.
    198  * Delete the unconnected IXFRs from memory */
    199 void ixfr_store_delixfrs(struct zone* zone);
    200 
    201 /* return if the zone has ixfr storage enabled for it */
    202 int zone_is_ixfr_enabled(struct zone* zone);
    203 
    204 /* create new zone_ixfr structure */
    205 struct zone_ixfr* zone_ixfr_create(struct nsd* nsd);
    206 
    207 /* free the zone_ixfr */
    208 void zone_ixfr_free(struct zone_ixfr* ixfr);
    209 
    210 /* make space to fit in the data */
    211 void zone_ixfr_make_space(struct zone_ixfr* ixfr, struct zone* zone,
    212 	struct ixfr_data* data, struct ixfr_store* ixfr_store);
    213 
    214 /* remove ixfr data from the zone_ixfr */
    215 void zone_ixfr_remove(struct zone_ixfr* ixfr, struct ixfr_data* data);
    216 
    217 /* add ixfr data to the zone_ixfr */
    218 void zone_ixfr_add(struct zone_ixfr* ixfr, struct ixfr_data* data, int isnew);
    219 
    220 /* find serial number in ixfr list, or NULL if not found */
    221 struct ixfr_data* zone_ixfr_find_serial(struct zone_ixfr* ixfr,
    222 	uint32_t qserial);
    223 
    224 /* size of the ixfr data */
    225 size_t ixfr_data_size(struct ixfr_data* data);
    226 
    227 /* write ixfr contents to file for the zone */
    228 void ixfr_write_to_file(struct zone* zone, const char* zfile);
    229 
    230 /* read ixfr contents from file for the zone */
    231 void ixfr_read_from_file(struct nsd* nsd, struct zone* zone, const char* zfile);
    232 
    233 /* get the current serial from the zone */
    234 uint32_t zone_get_current_serial(struct zone* zone);
    235 
    236 /* write the ixfr data to file */
    237 int ixfr_write_file(struct zone* zone, struct ixfr_data* data,
    238 	const char* zfile, int file_num);
    239 
    240 /* see if ixfr file exists */
    241 int ixfr_file_exists(const char* zfile, int file_num);
    242 
    243 /* rename the ixfr file */
    244 int ixfr_rename_it(const char* zname, const char* zfile, int oldnum,
    245 	int oldtemp, int newnum, int newtemp);
    246 
    247 /* read the file header of an ixfr file and return serial numbers. */
    248 int ixfr_read_file_header(const char* zname, const char* zfile,
    249 	int file_num, uint32_t* oldserial, uint32_t* newserial,
    250 	size_t* data_size, int enoent_is_err);
    251 
    252 /* unlink an ixfr file */
    253 int ixfr_unlink_it(const char* zname, const char* zfile, int file_num,
    254 	int silent_enoent);
    255 
    256 /* delete the ixfr files that are too many */
    257 void ixfr_delete_superfluous_files(struct zone* zone, const char* zfile,
    258 	int dest_num_files);
    259 
    260 #endif /* IXFR_H */
    261