1/*
2 * Copyright (C) 2004-2010  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: diff.h,v 1.19 2010/06/04 23:51:14 tbox Exp $ */
19
20#ifndef DNS_DIFF_H
21#define DNS_DIFF_H 1
22
23/*****
24 ***** Module Info
25 *****/
26
27/*! \file dns/diff.h
28 * \brief
29 * A diff is a convenience type representing a list of changes to be
30 * made to a database.
31 */
32
33/***
34 *** Imports
35 ***/
36
37#include <isc/lang.h>
38#include <isc/magic.h>
39
40#include <dns/name.h>
41#include <dns/rdata.h>
42#include <dns/types.h>
43
44/***
45 *** Types
46 ***/
47
48/*%
49 * A dns_difftuple_t represents a single RR being added or deleted.
50 * The RR type and class are in the 'rdata' member; the class is always
51 * the real one, not a DynDNS meta-class, so that the rdatas can be
52 * compared using dns_rdata_compare().  The TTL is significant
53 * even for deletions, because a deletion/addition pair cannot
54 * be canceled out if the TTL differs (it might be an explicit
55 * TTL update).
56 *
57 * Tuples are also used to represent complete RRs with owner
58 * names for a couple of other purposes, such as the
59 * individual RRs of a "RRset exists (value dependent)"
60 * prerequisite set.  In this case, op==DNS_DIFFOP_EXISTS,
61 * and the TTL is ignored.
62 *
63 * DNS_DIFFOP_*RESIGN will cause the 'resign' attribute of the resulting
64 * RRset to be recomputed to be 'resign' seconds before the earliest RRSIG
65 * timeexpire.
66 */
67
68typedef enum {
69	DNS_DIFFOP_ADD = 0,		/*%< Add an RR. */
70	DNS_DIFFOP_DEL = 1,		/*%< Delete an RR. */
71	DNS_DIFFOP_EXISTS = 2,		/*%< Assert RR existence. */
72	DNS_DIFFOP_ADDRESIGN = 4,	/*%< ADD + RESIGN. */
73	DNS_DIFFOP_DELRESIGN = 5	/*%< DEL + RESIGN. */
74} dns_diffop_t;
75
76typedef struct dns_difftuple dns_difftuple_t;
77
78#define DNS_DIFFTUPLE_MAGIC	ISC_MAGIC('D','I','F','T')
79#define DNS_DIFFTUPLE_VALID(t)	ISC_MAGIC_VALID(t, DNS_DIFFTUPLE_MAGIC)
80
81struct dns_difftuple {
82	unsigned int			magic;
83	isc_mem_t			*mctx;
84	dns_diffop_t			op;
85	dns_name_t			name;
86	dns_ttl_t			ttl;
87	dns_rdata_t			rdata;
88	ISC_LINK(dns_difftuple_t)	link;
89	/* Variable-size name data and rdata follows. */
90};
91
92/*%
93 * A dns_diff_t represents a set of changes being applied to
94 * a zone.  Diffs are also used to represent "RRset exists
95 * (value dependent)" prerequisites.
96 */
97typedef struct dns_diff dns_diff_t;
98
99#define DNS_DIFF_MAGIC		ISC_MAGIC('D','I','F','F')
100#define DNS_DIFF_VALID(t)	ISC_MAGIC_VALID(t, DNS_DIFF_MAGIC)
101
102struct dns_diff {
103	unsigned int			magic;
104	isc_mem_t *			mctx;
105	/*
106	 * Set the 'resign' attribute to this many second before the
107	 * earliest RRSIG timeexpire.
108	 */
109	isc_uint32_t			resign;
110	ISC_LIST(dns_difftuple_t)	tuples;
111};
112
113/* Type of comparison function for sorting diffs. */
114typedef int dns_diff_compare_func(const void *, const void *);
115
116/***
117 *** Functions
118 ***/
119
120ISC_LANG_BEGINDECLS
121
122/**************************************************************************/
123/*
124 * Manipulation of diffs and tuples.
125 */
126
127isc_result_t
128dns_difftuple_create(isc_mem_t *mctx,
129		     dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
130		     dns_rdata_t *rdata, dns_difftuple_t **tp);
131/*%<
132 * Create a tuple.  Deep copies are made of the name and rdata, so
133 * they need not remain valid after the call.
134 *
135 * Requires:
136 *\li	*tp != NULL && *tp == NULL.
137 *
138 * Returns:
139 *\li	ISC_R_SUCCESS
140 *  \li    ISC_R_NOMEMORY
141 */
142
143void
144dns_difftuple_free(dns_difftuple_t **tp);
145/*%<
146 * Free a tuple.
147 *
148 * Requires:
149 *    \li   **tp is a valid tuple.
150 *
151 * Ensures:
152 *     \li  *tp == NULL
153 *      \li All memory used by the tuple is freed.
154 */
155
156isc_result_t
157dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp);
158/*%<
159 * Copy a tuple.
160 *
161 * Requires:
162 * \li	'orig' points to a valid tuple
163 *\li	copyp != NULL && *copyp == NULL
164 */
165
166void
167dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff);
168/*%<
169 * Initialize a diff.
170 *
171 * Requires:
172 * \li   'diff' points to an uninitialized dns_diff_t
173 *  \li  allocated by the caller.
174 *
175 * Ensures:
176 * \li   '*diff' is a valid, empty diff.
177 */
178
179void
180dns_diff_clear(dns_diff_t *diff);
181/*%<
182 * Clear a diff, destroying all its tuples.
183 *
184 * Requires:
185 * \li   'diff' points to a valid dns_diff_t.
186 *
187 * Ensures:
188 * \li    Any tuples in the diff are destroyed.
189 *     The diff now empty, but it is still valid
190 *     and may be reused without calling dns_diff_init
191 *     again.  The only memory used is that of the
192 *     dns_diff_t structure itself.
193 *
194 * Notes:
195 * \li    Managing the memory of the dns_diff_t structure itself
196 *     is the caller's responsibility.
197 */
198
199void
200dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuple);
201/*%<
202 * Append a single tuple to a diff.
203 *
204 *\li	'diff' is a valid diff.
205 * \li	'*tuple' is a valid tuple.
206 *
207 * Ensures:
208 *\li	*tuple is NULL.
209 *\li	The tuple has been freed, or will be freed when the diff is cleared.
210 */
211
212void
213dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuple);
214/*%<
215 * Append 'tuple' to 'diff', removing any duplicate
216 * or conflicting updates as needed to create a minimal diff.
217 *
218 * Requires:
219 *\li	'diff' is a minimal diff.
220 *
221 * Ensures:
222 *\li	'diff' is still a minimal diff.
223 *  \li 	*tuple is NULL.
224 *   \li	The tuple has been freed, or will be freed when the diff is cleared.
225 *
226 */
227
228isc_result_t
229dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare);
230/*%<
231 * Sort 'diff' in-place according to the comparison function 'compare'.
232 */
233
234isc_result_t
235dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
236isc_result_t
237dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
238/*%<
239 * Apply 'diff' to the database 'db'.
240 *
241 * dns_diff_apply() logs warnings about updates with no effect or
242 * with inconsistent TTLs; dns_diff_applysilently() does not.
243 *
244 * For efficiency, the diff should be sorted by owner name.
245 * If it is not sorted, operation will still be correct,
246 * but less efficient.
247 *
248 * Requires:
249 *\li	*diff is a valid diff (possibly empty), containing
250 *   	tuples of type #DNS_DIFFOP_ADD and/or
251 *  	For #DNS_DIFFOP_DEL tuples, the TTL is ignored.
252 *
253 */
254
255isc_result_t
256dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc,
257	      void *add_private);
258/*%<
259 * Like dns_diff_apply, but for use when loading a new database
260 * instead of modifying an existing one.  This bypasses the
261 * database transaction mechanisms.
262 *
263 * Requires:
264 *\li 	'addfunc' is a valid dns_addradatasetfunc_t obtained from
265 * 	dns_db_beginload()
266 *
267 *\li	'add_private' points to a corresponding dns_dbload_t *
268 *      (XXX why is it a void pointer, then?)
269 */
270
271isc_result_t
272dns_diff_print(dns_diff_t *diff, FILE *file);
273
274/*%<
275 * Print the differences to 'file' or if 'file' is NULL via the
276 * logging system.
277 *
278 * Require:
279 *\li	'diff' to be valid.
280 *\li	'file' to refer to a open file or NULL.
281 *
282 * Returns:
283 *\li	#ISC_R_SUCCESS
284 *\li	#ISC_R_NOMEMORY
285 *\li	#ISC_R_UNEXPECTED
286 *\li	any error from dns_rdataset_totext()
287 */
288
289ISC_LANG_ENDDECLS
290
291#endif /* DNS_DIFF_H */
292