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
12struct nsd;
13#include "query.h"
14#include "rbtree.h"
15struct ixfr_data;
16struct zone;
17struct buffer;
18struct 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. */
26struct 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 */
57struct 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 */
93query_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 */
103struct 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 */
135struct 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 */
142void 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 */
148void 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 */
156void 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 */
160void 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 */
170void 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 */
181void ixfr_store_add_oldsoa(struct ixfr_store* ixfr_store, uint32_t ttl,
182	struct buffer* packet, size_t rrlen);
183
184void ixfr_store_delrr(struct ixfr_store* ixfr_store, const struct dname* dname,
185	uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
186	uint16_t rrlen, struct region* temp_region);
187void ixfr_store_addrr(struct ixfr_store* ixfr_store, const struct dname* dname,
188	uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
189	uint16_t rrlen, struct region* temp_region);
190int ixfr_store_addrr_rdatas(struct ixfr_store* ixfr_store,
191	const struct dname* dname, uint16_t type, uint16_t klass,
192	uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num);
193int ixfr_store_delrr_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);
196int ixfr_store_add_newsoa_rdatas(struct ixfr_store* ixfr_store,
197	const struct dname* dname, uint16_t type, uint16_t klass,
198	uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num);
199int ixfr_store_oldsoa_uncompressed(struct ixfr_store* ixfr_store,
200	uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass,
201	uint32_t ttl, uint8_t* rdata, size_t rdata_len);
202
203/* an AXFR has been received, the IXFRs do not connect in version number.
204 * Delete the unconnected IXFRs from memory */
205void ixfr_store_delixfrs(struct zone* zone);
206
207/* return if the zone has ixfr storage enabled for it */
208int zone_is_ixfr_enabled(struct zone* zone);
209
210/* create new zone_ixfr structure */
211struct zone_ixfr* zone_ixfr_create(struct nsd* nsd);
212
213/* free the zone_ixfr */
214void zone_ixfr_free(struct zone_ixfr* ixfr);
215
216/* make space to fit in the data */
217void zone_ixfr_make_space(struct zone_ixfr* ixfr, struct zone* zone,
218	struct ixfr_data* data, struct ixfr_store* ixfr_store);
219
220/* remove ixfr data from the zone_ixfr */
221void zone_ixfr_remove(struct zone_ixfr* ixfr, struct ixfr_data* data);
222
223/* add ixfr data to the zone_ixfr */
224void zone_ixfr_add(struct zone_ixfr* ixfr, struct ixfr_data* data, int isnew);
225
226/* find serial number in ixfr list, or NULL if not found */
227struct ixfr_data* zone_ixfr_find_serial(struct zone_ixfr* ixfr,
228	uint32_t qserial);
229
230/* size of the ixfr data */
231size_t ixfr_data_size(struct ixfr_data* data);
232
233/* write ixfr contents to file for the zone */
234void ixfr_write_to_file(struct zone* zone, const char* zfile);
235
236/* read ixfr contents from file for the zone */
237void ixfr_read_from_file(struct nsd* nsd, struct zone* zone, const char* zfile);
238
239/* get the current serial from the zone */
240uint32_t zone_get_current_serial(struct zone* zone);
241
242/* write the ixfr data to file */
243int ixfr_write_file(struct zone* zone, struct ixfr_data* data,
244	const char* zfile, int file_num);
245
246/* see if ixfr file exists */
247int ixfr_file_exists(const char* zfile, int file_num);
248
249/* rename the ixfr file */
250int ixfr_rename_it(const char* zname, const char* zfile, int oldnum,
251	int oldtemp, int newnum, int newtemp);
252
253/* read the file header of an ixfr file and return serial numbers. */
254int ixfr_read_file_header(const char* zname, const char* zfile,
255	int file_num, uint32_t* oldserial, uint32_t* newserial,
256	size_t* data_size, int enoent_is_err);
257
258/* unlink an ixfr file */
259int ixfr_unlink_it(const char* zname, const char* zfile, int file_num,
260	int silent_enoent);
261
262/* delete the ixfr files that are too many */
263void ixfr_delete_superfluous_files(struct zone* zone, const char* zfile,
264	int dest_num_files);
265
266#endif /* IXFR_H */
267