changesets.h 8.47 KB
Newer Older
1
/*  Copyright (C) 2019 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

    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
14
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
Lubos Slovak's avatar
Lubos Slovak committed
15
 */
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
	list_t iters;             /*!< List of pending zone iterators. */
46 47 48
	zone_tree_t *trees[4];    /*!< Poiters to zone trees to iterate over. */
	size_t n_trees;           /*!< Their count. */
	zone_tree_it_t it;        /*!< Zone tree iterator. */
49 50
	const zone_node_t *node;  /*!< Current zone node. */
	uint16_t node_pos;        /*!< Position in node. */
51 52
} changeset_iter_t;

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

63
/*!
64
 * \brief Creates new changeset structure and inits it.
65
 *
66 67 68 69 70 71 72 73
 * \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.
74
 *
75
 * \param ch  Changeset to be checked.
76
 *
77 78
 * \retval true if changeset is empty.
 * \retval false if changeset is not empty.
79
 */
80
bool changeset_empty(const changeset_t *ch);
81

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

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

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


/*!
 * \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);
133 134

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

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
/*!
 * \brief Get serial "from" of the changeset.
 *
 * \param ch   Changeset in question.
 *
 * \return Its serial "from", or 0 if none.
 */
uint32_t changeset_from(const changeset_t *ch);

/*!
 * \brief Get serial "to" of the changeset.
 *
 * \param ch   Changeset in question.
 *
 * \return Its serial "to", or 0 if none.
 */
uint32_t changeset_to(const changeset_t *ch);

163 164 165
/*!
 * \brief Remove from changeset those rdata which won't be added/removed from zone.
 *
166 167
 * \param zone  The zone the changeset is going to be applied on.
 * \param ch    The cheangeset to be fixed.
168 169 170
 *
 * \return KNOT_E*
 */
171
int changeset_preapply_fix(const zone_contents_t *zone, changeset_t *ch);
172 173 174 175

/*!
 * \brief Remove from changeset records which are removed and added the same.
 *
176
 * \param ch  Changeset to be fixed.
177 178 179
 *
 * \return KNOT_E*
 */
180
int changeset_cancelout(changeset_t *ch);
181

182 183 184
/*!
 * \brief Check the changes and SOA, ignoring possibly updated SOA serial.
 *
185 186
 * \note Also tolerates changed RRSIG of SOA.
 *
187 188
 * \param ch  Changeset in question.
 *
189 190 191
 * \retval false  If the changeset changes other records than SOA, or some SOA field
 *                other than serial changed.
 * \retval true   Otherwise.
192 193 194
 */
bool changeset_differs_just_serial(const changeset_t *ch);

195 196 197 198 199
/*!
 * \brief Clears changesets in list. Changesets are not free'd. Legacy.
 *
 * \param chgs  Changeset list to clear.
 */
200
void changesets_clear(list_t *chgs);
201 202 203 204 205 206

/*!
 * \brief Free changesets in list. Legacy.
 *
 * \param chgs  Changeset list to free.
 */
207
void changesets_free(list_t *chgs);
208 209 210 211 212 213

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

216 217 218 219 220 221 222 223 224
/*!
 * \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);

225 226 227 228 229
/*!
 * \brief Frees single changeset.
 *
 * \param ch  Changeset to free.
 */
230
void changeset_free(changeset_t *ch);
231

232 233 234
/*!
 * \brief Inits changeset iteration structure with changeset additions.
 *
235 236
 * \param itt  Iterator to init.
 * \param ch   Changeset to use.
237 238 239
 *
 * \return KNOT_E*
 */
240
int changeset_iter_add(changeset_iter_t *itt, const changeset_t *ch);
241 242 243 244

/*!
 * \brief Inits changeset iteration structure with changeset removals.
 *
245 246
 * \param itt  Iterator to init.
 * \param ch   Changeset to use.
247 248 249
 *
 * \return KNOT_E*
 */
250
int changeset_iter_rem(changeset_iter_t *itt, const changeset_t *ch);
251 252 253 254

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

/*!
 * \brief Gets next RRSet from changeset iterator.
 *
 * \param it  Changeset iterator.
 *
 * \return Next RRSet in iterator, empty RRSet if iteration done.
 */
269
knot_rrset_t changeset_iter_next(changeset_iter_t *it);
270 271 272 273 274 275

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

278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
/*!
 * \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);
300 301 302 303 304 305 306 307 308 309

/*!
 *
 * \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);