changesets.h 8.58 KB
Newer Older
1
/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
Lubos Slovak's avatar
Lubos Slovak committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
16

17
#pragma once
18

Daniel Salzman's avatar
Daniel Salzman committed
19 20
#include <stdio.h>

21
#include "libknot/rrset.h"
22
#include "knot/zone/contents.h"
23
#include "contrib/ucw/lists.h"
24

25
/*! \brief Changeset addition/removal flags */
26
typedef enum {
27 28
	CHANGESET_NONE = 0,
	CHANGESET_CHECK = 1 << 0, /*! Perform redundancy check on additions/removals */
29
	CHANGESET_CHECK_CANCELOUT = 1 << 1, /*! Do the complete cancelout on addition/removal/merge (depends on CHANGESET_CHECK */
30
} changeset_flag_t;
31

Jan Kadlec's avatar
Jan Kadlec committed
32
/*! \brief One zone change, from 'soa_from' to 'soa_to'. */
33 34 35 36 37 38
typedef struct {
	node_t n;                 /*!< List node. */
	knot_rrset_t *soa_from;   /*!< Start SOA. */
	knot_rrset_t *soa_to;     /*!< Destination SOA. */
	zone_contents_t *add;     /*!< Change additions. */
	zone_contents_t *remove;  /*!< Change removals. */
39
	size_t size;              /*!< Size of serialized changeset. \todo Remove after old_journal removal! */
40
	uint8_t *data;            /*!< Serialized changeset. */
41
} changeset_t;
42

43
/*! \brief Changeset iteration structure. */
44
typedef struct {
45 46 47
	list_t iters;             /*!< List of pending zone iterators. */
	const zone_node_t *node;  /*!< Current zone node. */
	uint16_t node_pos;        /*!< Position in node. */
48 49
} changeset_iter_t;

50
/*!
51
 * \brief Inits changeset structure.
52
 *
53 54
 * \param ch    Changeset to init.
 * \param apex  Zone apex DNAME.
55
 *
56
 * \return KNOT_E*
57
 */
58
int changeset_init(changeset_t *ch, const knot_dname_t *apex);
59

60
/*!
61
 * \brief Creates new changeset structure and inits it.
62
 *
63 64 65 66 67 68 69 70
 * \param apex  Zone apex DNAME.
 *
 * \return Changeset structure on success, NULL on errors.
 */
changeset_t *changeset_new(const knot_dname_t *apex);

/*!
 * \brief Checks whether changeset is empty, i.e. no change will happen after its application.
71
 *
72
 * \param ch  Changeset to be checked.
73
 *
74 75
 * \retval true if changeset is empty.
 * \retval false if changeset is not empty.
76
 */
77
bool changeset_empty(const changeset_t *ch);
78

79 80 81
/*!
 * \brief Get number of changes (additions and removals) in the changeset.
 *
82
 * \param ch  Changeset to be checked.
83 84 85
 *
 * \return Number of changes in the changeset.
 */
86
size_t changeset_size(const changeset_t *ch);
87

88 89 90
/*!
 * \brief Add RRSet to 'add' part of changeset.
 *
91 92 93
 * \param ch     Changeset to add RRSet into.
 * \param rrset  RRSet to be added.
 * \param flags  Changeset flags.
94 95 96
 *
 * \return KNOT_E*
 */
97
int changeset_add_addition(changeset_t *ch, const knot_rrset_t *rrset, changeset_flag_t flags);
98 99 100 101

/*!
 * \brief Add RRSet to 'remove' part of changeset.
 *
102 103 104
 * \param ch     Changeset to add RRSet into.
 * \param rrset  RRSet to be added.
 * \param flags  Changeset flags.
105 106 107
 *
 * \return KNOT_E*
 */
108
int changeset_add_removal(changeset_t *ch, const knot_rrset_t *rrset, changeset_flag_t flags);
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129


/*!
 * \brief Remove an RRSet from the 'add' part of changeset.
 *
 * \param ch                Changeset to add RRSet into.
 * \param rrset             RRSet to be added.
 *
 * \return KNOT_E*
 */
int changeset_remove_addition(changeset_t *ch, const knot_rrset_t *rrset);

/*!
 * \brief Remove an RRSet from the 'remove' part of changeset.
 *
 * \param ch                Changeset to add RRSet into.
 * \param rrset             RRSet to be added.
 *
 * \return KNOT_E*
 */
int changeset_remove_removal(changeset_t *ch, const knot_rrset_t *rrset);
130 131

/*!
132
 * \brief Merges two changesets together.
133 134 135
 *
 * \param ch1  Merge into this changeset.
 * \param ch2  Merge this changeset.
136
 * \param flags  Flags how to handle rendundancies.
137 138 139
 *
 * \return KNOT_E*
 */
140
int changeset_merge(changeset_t *ch1, const changeset_t *ch2, int flags);
141

142 143 144
/*!
 * \brief Remove from changeset those rdata which won't be added/removed from zone.
 *
145 146
 * \param zone  The zone the changeset is going to be applied on.
 * \param ch    The cheangeset to be fixed.
147 148 149
 *
 * \return KNOT_E*
 */
150
int changeset_preapply_fix(const zone_contents_t *zone, changeset_t *ch);
151 152 153 154

/*!
 * \brief Remove from changeset records which are removed and added the same.
 *
155
 * \param ch  Changeset to be fixed.
156 157 158
 *
 * \return KNOT_E*
 */
159
int changeset_cancelout(changeset_t *ch);
160

161 162 163
/*!
 * \brief Check the changes and SOA, ignoring possibly updated SOA serial.
 *
164 165
 * \note Also tolerates changed RRSIG of SOA.
 *
166 167
 * \param ch  Changeset in question.
 *
168 169 170
 * \retval false  If the changeset changes other records than SOA, or some SOA field
 *                other than serial changed.
 * \retval true   Otherwise.
171 172 173
 */
bool changeset_differs_just_serial(const changeset_t *ch);

174 175 176 177
/*!
 * \brief Loads zone contents from botstrap changeset.
 *
 * \param ch  Changeset to load from, will be freed!
178
 * \param out Zone contents.
179
 *
180
 * \return KNOT_E*
181
 */
182
int changeset_to_contents(changeset_t *ch, zone_contents_t **out);
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199

/*!
 * \brief Creates a bootstrap changeset from zone.
 *
 * \param contents  Contents to include, will be freed!
 *
 * \return Changeset, which shall be freed with changeset_from_contents_free()
 */
changeset_t *changeset_from_contents(const zone_contents_t *contents);

/*!
 * \brief Frees single changeset.
 *
 * \param ch  Changeset from changeset_from_contents() to free.
 */
void changeset_from_contents_free(changeset_t *ch);

200 201 202 203 204
/*!
 * \brief Clears changesets in list. Changesets are not free'd. Legacy.
 *
 * \param chgs  Changeset list to clear.
 */
205
void changesets_clear(list_t *chgs);
206 207 208 209 210 211

/*!
 * \brief Free changesets in list. Legacy.
 *
 * \param chgs  Changeset list to free.
 */
212
void changesets_free(list_t *chgs);
213 214 215 216 217 218

/*!
 * \brief Clear single changeset.
 *
 * \param ch  Changeset to clear.
 */
219
void changeset_clear(changeset_t *ch);
220

221 222 223 224 225 226 227 228 229
/*!
 * \brief Copy changeset to newly allocated space, all rrsigs are copied.
 *
 * \param ch  Changeset to be copied.
 *
 * \return a copy, or NULL if error.
 */
changeset_t *changeset_clone(const changeset_t *ch);

230 231 232 233 234
/*!
 * \brief Frees single changeset.
 *
 * \param ch  Changeset to free.
 */
235
void changeset_free(changeset_t *ch);
236

237 238 239
/*!
 * \brief Inits changeset iteration structure with changeset additions.
 *
240 241
 * \param itt  Iterator to init.
 * \param ch   Changeset to use.
242 243 244
 *
 * \return KNOT_E*
 */
245
int changeset_iter_add(changeset_iter_t *itt, const changeset_t *ch);
246 247 248 249

/*!
 * \brief Inits changeset iteration structure with changeset removals.
 *
250 251
 * \param itt  Iterator to init.
 * \param ch   Changeset to use.
252 253 254
 *
 * \return KNOT_E*
 */
255
int changeset_iter_rem(changeset_iter_t *itt, const changeset_t *ch);
256 257 258 259

/*!
 * \brief Inits changeset iteration structure with changeset additions and removals.
 *
260 261
 * \param itt  Iterator to init.
 * \param ch   Changeset to use.
262 263 264
 *
 * \return KNOT_E*
 */
265
int changeset_iter_all(changeset_iter_t *itt, const changeset_t *ch);
266 267 268 269 270 271 272 273

/*!
 * \brief Gets next RRSet from changeset iterator.
 *
 * \param it  Changeset iterator.
 *
 * \return Next RRSet in iterator, empty RRSet if iteration done.
 */
274
knot_rrset_t changeset_iter_next(changeset_iter_t *it);
275 276 277 278 279 280

/*!
 * \brief Free resources allocated by changeset iterator.
 *
 * \param it  Iterator to clear.
 */
281
void changeset_iter_clear(changeset_iter_t *it);
282

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
/*!
 * \brief A pointer type for callback for changeset_walk() function.
 *
 * \param rrset    An actual removal/addition inside the changeset.
 * \param addition Indicates addition against removal.
 * \param ctx      A context passed to the changeset_walk() function.
 *
 * \retval KNOT_EOK if all ok, iteration will continue
 * \return KNOT_E*  if error, iteration will stop immediately and changeset_walk() returns this error.
 */
typedef int (*changeset_walk_callback)(const knot_rrset_t *rrset, bool addition, void *ctx);

/*!
 * \brief Calls a callback for each removal/addition in the changeset.
 *
 * \param changeset Changeset.
 * \param callback  Callback.
 * \param ctx       Arbitrary context passed to the callback.
 *
 * \return KNOT_E*
 */
int changeset_walk(const changeset_t *changeset, changeset_walk_callback callback, void *ctx);
305 306 307 308 309 310 311 312 313 314

/*!
 *
 * \brief Dumps the changeset into text file.
 *
 * \param changeset Changeset.
 * \param outfile   File to write into.
 * \param color     Use unix tty color metacharacters.
 */
void changeset_print(const changeset_t *changeset, FILE *outfile, bool color);