xref: /netbsd/external/bsd/nsd/dist/ixfr.h (revision 66a1527d)
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, uint32_t old_serial,
137 	uint32_t new_serial);
138 
139 /*
140  * Cancel the ixfr store in progress. The pointer remains valid, no store done.
141  * ixfr_store: this is set to cancel.
142  */
143 void ixfr_store_cancel(struct ixfr_store* ixfr_store);
144 
145 /*
146  * Free ixfr store structure, it is no longer used.
147  * ixfr_store: deleted
148  */
149 void ixfr_store_free(struct ixfr_store* ixfr_store);
150 
151 /*
152  * Finish ixfr store processing. Links the data into the zone ixfr data.
153  * ixfr_store: Data is linked into the zone struct. The ixfr_store is freed.
154  * nsd: nsd structure for allocation region and global options.
155  * log_buf: log string for the update.
156  */
157 void ixfr_store_finish(struct ixfr_store* ixfr_store, struct nsd* nsd,
158 	char* log_buf);
159 
160 /* finish just the data activities, trim up the storage and append newsoa */
161 void ixfr_store_finish_data(struct ixfr_store* ixfr_store);
162 
163 /*
164  * Add the new SOA record to the ixfr store.
165  * ixfr_store: stores ixfr data that is collected.
166  * packet: DNS packet that contains the SOA. position restored on function
167  * 	exit.
168  * ttlpos: position, just before the ttl, rdatalen, rdata of the SOA record.
169  * 	we do not need to pass the name, because that is the zone name, or
170  * 	the type or class of the record, because we already know.
171  */
172 void ixfr_store_add_newsoa(struct ixfr_store* ixfr_store,
173 	struct buffer* packet, size_t ttlpos);
174 
175 /*
176  * Add the old SOA record to the ixfr store.
177  * ixfr_store: stores ixfr data that is collected.
178  * ttl: the TTL of the SOA record
179  * packet: DNS packet that contains the SOA. position restored on function
180  * 	exit.
181  * rrlen: wire rdata length of the SOA.
182  */
183 void ixfr_store_add_oldsoa(struct ixfr_store* ixfr_store, uint32_t ttl,
184 	struct buffer* packet, size_t rrlen);
185 
186 void ixfr_store_delrr(struct ixfr_store* ixfr_store, const struct dname* dname,
187 	uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
188 	uint16_t rrlen, struct region* temp_region);
189 void ixfr_store_addrr(struct ixfr_store* ixfr_store, const struct dname* dname,
190 	uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
191 	uint16_t rrlen, struct region* temp_region);
192 int ixfr_store_addrr_rdatas(struct ixfr_store* ixfr_store,
193 	const struct dname* dname, uint16_t type, uint16_t klass,
194 	uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num);
195 int ixfr_store_delrr_uncompressed(struct ixfr_store* ixfr_store,
196 	uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass,
197 	uint32_t ttl, uint8_t* rdata, size_t rdata_len);
198 int ixfr_store_add_newsoa_rdatas(struct ixfr_store* ixfr_store,
199 	const struct dname* dname, uint16_t type, uint16_t klass,
200 	uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num);
201 int ixfr_store_oldsoa_uncompressed(struct ixfr_store* ixfr_store,
202 	uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass,
203 	uint32_t ttl, uint8_t* rdata, size_t rdata_len);
204 
205 /* an AXFR has been received, the IXFRs do not connect in version number.
206  * Delete the unconnected IXFRs from memory */
207 void ixfr_store_delixfrs(struct zone* zone);
208 
209 /* return if the zone has ixfr storage enabled for it */
210 int zone_is_ixfr_enabled(struct zone* zone);
211 
212 /* create new zone_ixfr structure */
213 struct zone_ixfr* zone_ixfr_create(struct nsd* nsd);
214 
215 /* free the zone_ixfr */
216 void zone_ixfr_free(struct zone_ixfr* ixfr);
217 
218 /* make space to fit in the data */
219 void zone_ixfr_make_space(struct zone_ixfr* ixfr, struct zone* zone,
220 	struct ixfr_data* data, struct ixfr_store* ixfr_store);
221 
222 /* remove ixfr data from the zone_ixfr */
223 void zone_ixfr_remove(struct zone_ixfr* ixfr, struct ixfr_data* data);
224 
225 /* add ixfr data to the zone_ixfr */
226 void zone_ixfr_add(struct zone_ixfr* ixfr, struct ixfr_data* data, int isnew);
227 
228 /* find serial number in ixfr list, or NULL if not found */
229 struct ixfr_data* zone_ixfr_find_serial(struct zone_ixfr* ixfr,
230 	uint32_t qserial);
231 
232 /* size of the ixfr data */
233 size_t ixfr_data_size(struct ixfr_data* data);
234 
235 /* write ixfr contents to file for the zone */
236 void ixfr_write_to_file(struct zone* zone, const char* zfile);
237 
238 /* read ixfr contents from file for the zone */
239 void ixfr_read_from_file(struct nsd* nsd, struct zone* zone, const char* zfile);
240 
241 /* get the current serial from the zone */
242 uint32_t zone_get_current_serial(struct zone* zone);
243 
244 /* write the ixfr data to file */
245 int ixfr_write_file(struct zone* zone, struct ixfr_data* data,
246 	const char* zfile, int file_num);
247 
248 /* see if ixfr file exists */
249 int ixfr_file_exists(const char* zfile, int file_num);
250 
251 /* rename the ixfr file */
252 int ixfr_rename_it(const char* zname, const char* zfile, int oldnum,
253 	int oldtemp, int newnum, int newtemp);
254 
255 /* read the file header of an ixfr file and return serial numbers. */
256 int ixfr_read_file_header(const char* zname, const char* zfile,
257 	int file_num, uint32_t* oldserial, uint32_t* newserial,
258 	size_t* data_size, int enoent_is_err);
259 
260 /* unlink an ixfr file */
261 int ixfr_unlink_it(const char* zname, const char* zfile, int file_num,
262 	int silent_enoent);
263 
264 /* delete the ixfr files that are too many */
265 void ixfr_delete_superfluous_files(struct zone* zone, const char* zfile,
266 	int dest_num_files);
267 
268 #endif /* _IXFR_H_ */
269