contents.h 9.81 KB
Newer Older
1
/*  Copyright (C) 2011 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
 * \file
18
 *
19
 * Zone contents structure and API for manipulating it.
20
 *
21
 * \addtogroup knot
22 23 24
 *
 * @{
 */
25

26
#pragma once
27

28
#include "libknot/rrtype/nsec3param.h"
29 30
#include "knot/zone/node.h"
#include "knot/zone/zone-tree.h"
31

32
enum zone_contents_find_dname_result {
33 34
	ZONE_NAME_NOT_FOUND = 0,
	ZONE_NAME_FOUND     = 1
35
};
36

37
typedef struct zone_contents {
38
	zone_node_t *apex;       /*!< Apex node of the zone (holding SOA) */
39

40 41
	zone_tree_t *nodes;
	zone_tree_t *nsec3_nodes;
42

43
	knot_nsec3_params_t nsec3_params;
44
} zone_contents_t;
45

46 47 48
/*!
 * \brief Signature of callback for zone contents apply functions.
 */
49
typedef int (*zone_contents_apply_cb_t)(zone_node_t *node, void *data);
50

51
zone_contents_t *zone_contents_new(const knot_dname_t *apex_name);
52

53
int zone_contents_add_rr(zone_contents_t *z, const knot_rrset_t *rr, zone_node_t **n);
54 55 56 57

/*!
 * \brief Tries to find a node with the specified name in the zone.
 *
58
 * \note This function is identical to zone_contents_get_node(), only it returns
59 60 61 62 63 64 65
 *       constant reference.
 *
 * \param zone Zone where the name should be searched for.
 * \param name Name to find.
 *
 * \return Corresponding node if found, NULL otherwise.
 */
66 67
const zone_node_t *zone_contents_find_node(const zone_contents_t *contents,
                                           const knot_dname_t *name);
68 69

/*!
70
 * \brief Tries to find a node by owner in the zone contents.
71 72 73 74 75 76 77 78
 *
 * \param[in] zone Zone to search for the name.
 * \param[in] name Domain name to search for.
 * \param[out] node The found node (if it was found, otherwise it may contain
 *                  arbitrary node).
 * \param[out] closest_encloser Closest encloser of the given name in the zone.
 * \param[out] previous Previous domain name in canonical order.
 *
79 80
 * \retval ZONE_NAME_FOUND if node with owner \a name was found.
 * \retval ZONE_NAME_NOT_FOUND if it was not found.
Marek Vavrusa's avatar
Marek Vavrusa committed
81
 * \retval KNOT_EINVAL
82
 * \retval KNOT_EOUTOFZONE
83
 */
84
int zone_contents_find_dname(const zone_contents_t *contents,
85 86 87 88
                             const knot_dname_t *name,
                             const zone_node_t **node,
                             const zone_node_t **closest_encloser,
                             const zone_node_t **previous);
89 90 91 92 93 94

/*!
 * \brief Finds previous name in canonical order to the given name in the zone.
 *
 * \param zone Zone to search for the name.
 * \param name Domain name to find the previous domain name of.
Marek Vavrusa's avatar
Marek Vavrusa committed
95
 *
96 97
 * \return Previous node in canonical order, or NULL if some parameter is wrong.
 */
98 99
const zone_node_t *zone_contents_find_previous(const zone_contents_t *contents,
                                               const knot_dname_t *name);
100 101 102 103 104

/*!
 * \brief Tries to find a node with the specified name among the NSEC3 nodes
 *        of the zone.
 *
105
 * \note This function is identical to zone_contents_get_nsec3_node(), only it
106 107 108 109 110 111 112
 *       returns constant reference.
 *
 * \param zone Zone where the name should be searched for.
 * \param name Name to find.
 *
 * \return Corresponding node if found, NULL otherwise.
 */
113 114
const zone_node_t *zone_contents_find_nsec3_node(const zone_contents_t *contents,
                                                 const knot_dname_t *name);
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

/*!
 * \brief Finds NSEC3 node and previous NSEC3 node in canonical order,
 *        corresponding to the given domain name.
 *
 * This functions creates a NSEC3 hash of \a name and tries to find NSEC3 node
 * with the hashed domain name as owner.
 *
 * \param[in] zone Zone to search in.
 * \param[in] name Domain name to get the corresponding NSEC3 nodes for.
 * \param[out] nsec3_node NSEC3 node corresponding to \a name (if found,
 *                        otherwise this may be an arbitrary NSEC3 node).
 * \param[out] nsec3_previous The NSEC3 node immediately preceding hashed domain
 *                            name corresponding to \a name in canonical order.
 *
130 131
 * \retval ZONE_NAME_FOUND if the corresponding NSEC3 node was found.
 * \retval ZONE_NAME_NOT_FOUND if it was not found.
Marek Vavrusa's avatar
Marek Vavrusa committed
132
 * \retval KNOT_EINVAL
Lubos Slovak's avatar
Lubos Slovak committed
133 134 135
 * \retval KNOT_ENSEC3PAR
 * \retval KNOT_ECRYPTO
 * \retval KNOT_ERROR
136
 */
137 138 139 140
int zone_contents_find_nsec3_for_name(const zone_contents_t *contents,
                                      const knot_dname_t *name,
                                      const zone_node_t **nsec3_node,
                                      const zone_node_t **nsec3_previous);
141

142 143
const zone_node_t *zone_contents_find_wildcard_child(const zone_contents_t *contents,
                                                     const zone_node_t *parent);
144 145

/*!
146
 * \brief Sets parent and previous pointers and node flags. (cheap operation)
147
 *        For both normal and NSEC3 tree
148
 */
149
int zone_contents_adjust_pointers(zone_contents_t *contents);
150 151 152 153 154

/*!
 * \brief Sets parent and previous pointers, sets node flags and NSEC3 links.
 *        This has to be called before the zone can be served.
 *
155 156 157 158
 * \param first_nsec3_node First node in NSEC3 tree - needed in sem. checks.
 *        Will not be saved if set to NULL.
 * \param last_nsec3_node Last node in NSEC3 tree - needed in sem. checks.
 *        Will not be saved if set to NULL.
159 160
 * \param zone Zone to adjust domain names in.
 */
161
int zone_contents_adjust_full(zone_contents_t *contents,
162 163
                              zone_node_t **first_nsec3_node,
                              zone_node_t **last_nsec3_node);
164

165 166 167 168 169 170
/*!
 * \brief Parses the NSEC3PARAM record stored in the zone.
 *
 * This function properly fills in the nsec3_params field of the zone structure
 * according to data stored in the NSEC3PARAM record. This is necessary to do
 * before any NSEC3 operations on the zone are requested, otherwise they will
Lubos Slovak's avatar
Lubos Slovak committed
171
 * fail (error KNOT_ENSEC3PAR).
172 173 174 175 176 177
 *
 * \note If there is no NSEC3PARAM record in the zone, this function clears
 *       the nsec3_params field of the zone structure (fills it with zeros).
 *
 * \param zone Zone to get the NSEC3PARAM record from.
 */
178
int zone_contents_load_nsec3param(zone_contents_t *contents);
179 180 181 182 183

/*!
 * \brief Returns the parsed NSEC3PARAM record of the zone.
 *
 * \note You must parse the NSEC3PARAM record prior to calling this function
184
 *       (zone_contents_load_nsec3param()).
185 186 187 188 189 190
 *
 * \param zone Zone to get the NSEC3PARAM record from.
 *
 * \return Parsed NSEC3PARAM from the zone or NULL if the zone does not use
 *         NSEC3 or the record was not parsed before.
 *
191
 * \see zone_contents_load_nsec3param()
192
 */
193
const knot_nsec3_params_t *zone_contents_nsec3params(const zone_contents_t *contents);
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208

/*!
 * \brief Applies the given function to each regular node in the zone.
 *
 * This function uses in-order depth-first forward traversal, i.e. the function
 * is first recursively applied to left subtree, then to the root and then to
 * the right subtree.
 *
 * \note This implies that the zone is stored in a binary tree. Is there a way
 *       to make this traversal independent on the underlying structure?
 *
 * \param zone Nodes of this zone will be used as parameters for the function.
 * \param function Function to be applied to each node of the zone.
 * \param data Arbitrary data to be passed to the function.
 */
209
int zone_contents_tree_apply_inorder(zone_contents_t *zone,
210
                                     zone_contents_apply_cb_t function, void *data);
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226

/*!
 * \brief Applies the given function to each NSEC3 node in the zone.
 *
 * This function uses in-order depth-first forward traversal, i.e. the function
 * is first recursively applied to left subtree, then to the root and then to
 * the right subtree.
 *
 * \note This implies that the zone is stored in a binary tree. Is there a way
 *       to make this traversal independent on the underlying structure?
 *
 * \param zone NSEC3 nodes of this zone will be used as parameters for the
 *             function.
 * \param function Function to be applied to each node of the zone.
 * \param data Arbitrary data to be passed to the function.
 */
227
int zone_contents_nsec3_apply_inorder(zone_contents_t *zone,
228
                                      zone_contents_apply_cb_t function, void *data);
229 230 231 232 233 234 235 236 237 238 239 240 241

/*!
 * \brief Creates a shallow copy of the zone (no stored data are copied).
 *
 * This function creates a new zone structure in \a to, creates new trees for
 * regular nodes and for NSEC3 nodes, creates new hash table and a new domain
 * table. It also fills these structures with the exact same data as the
 * original zone is - no copying of stored data is done, just pointers are
 * copied.
 *
 * \param from Original zone.
 * \param to Copy of the zone.
 *
Lubos Slovak's avatar
Lubos Slovak committed
242
 * \retval KNOT_EOK
Marek Vavrusa's avatar
Marek Vavrusa committed
243
 * \retval KNOT_EINVAL
Lubos Slovak's avatar
Lubos Slovak committed
244
 * \retval KNOT_ENOMEM
245
 */
246
int zone_contents_shallow_copy(const zone_contents_t *from, zone_contents_t **to);
247

248
void zone_contents_free(zone_contents_t **contents);
249

250
void zone_contents_deep_free(zone_contents_t **contents);
251

252 253
/*!
 * \brief Fetch zone serial.
Jan Včelák's avatar
Jan Včelák committed
254
 *
255
 * \param zone Zone.
Jan Včelák's avatar
Jan Včelák committed
256
 *
257 258
 * \return serial or 0
 */
259
uint32_t zone_contents_serial(const zone_contents_t *zone);
260 261 262 263

/*!
 * \brief Return true if zone is signed.
 */
264
bool zone_contents_is_signed(const zone_contents_t *zone);
265

266 267 268
/*!
 * \brief Return true if zone is empty.
 */
269 270
bool zone_contents_is_empty(const zone_contents_t *zone);

271
zone_node_t *zone_contents_get_node_for_rr(zone_contents_t *zone, const knot_rrset_t *rrset);
272

273
zone_node_t *zone_contents_find_node_for_rr(zone_contents_t *zone, const knot_rrset_t *rrset);
274

275
/*! @} */