rrset.h 13.6 KB
Newer Older
1 2
/*!
 * \file rrset.h
Jan Kadlec's avatar
Jan Kadlec committed
3
 *
4
 * \author Lubos Slovak <lubos.slovak@nic.cz>
5
 * \author Jan Kadlec <jan.kadlec@nic.cz>
6 7 8
 *
 * \brief RRSet structure and API for manipulating it.
 *
Ondřej Surý's avatar
Ondřej Surý committed
9
 * \addtogroup libknot
10 11
 * @{
 */
12
/*  Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
Lubos Slovak's avatar
Lubos Slovak committed
13 14 15 16 17 18 19 20 21 22 23 24 25 26

    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/>.
 */
27

Lubos Slovak's avatar
Lubos Slovak committed
28 29
#ifndef _KNOT_RRSET_H_
#define _KNOT_RRSET_H_
Lubos Slovak's avatar
Lubos Slovak committed
30 31

#include <stdint.h>
Marek Vavrusa's avatar
Marek Vavrusa committed
32
#include <stdbool.h>
Lubos Slovak's avatar
Lubos Slovak committed
33

34
#include "libknot/dname.h"
Lubos Slovak's avatar
Lubos Slovak committed
35

Marek Vavrusa's avatar
Marek Vavrusa committed
36 37
struct knot_compr;

38 39 40 41 42 43 44 45 46 47 48
/*----------------------------------------------------------------------------*/
/*!
 * \brief Structure for representing an RRSet.
 *
 * For definition of a RRSet see RFC2181, Section 5.
 *
 * As all RRs within a RRSet share the same OWNER, TYPE, CLASS and TTL (see
 * Section 5.2 of RFC2181), there is no need to duplicate these data in the
 * program. Distinct Resource Records are thus represented only as distinct
 * RDATA sections of corresponding RRs.
 */
49

50
struct knot_rrset {
Jan Kadlec's avatar
Jan Kadlec committed
51
	/*! \brief Domain name being the owner of the RRSet. */
52
	knot_dname_t *owner;
Jan Kadlec's avatar
Jan Kadlec committed
53 54 55
	uint16_t type; /*!< TYPE of the RRset. */
	uint16_t rclass; /*!< CLASS of the RRSet. */
	uint32_t ttl; /*!< TTL of the RRSet. */
56 57
	/*! \brief RDATA array (for all RRs). DNAMEs stored as full,
	 *         uncompressed wire. Binary data stored in wireformat order.
Lubos Slovak's avatar
Lubos Slovak committed
58
	 */
59
	uint8_t *rdata; /*!< RDATA array (All RRs). DNAMEs stored as full wire. */
60 61 62
	/*! \brief Beginnings of RRs - first one does not contain 0, last
	 *         last one holds total length of all RRs together
	 */
63
	uint32_t *rdata_indices; /*!< Indices to beginnings of RRs (without 0)*/
64
	uint16_t rdata_count; /*!< Count of RRs in this RRSet. */
65
	struct knot_rrset *rrsigs; /*!< Set of RRSIGs covering this RRSet. */
Lubos Slovak's avatar
Lubos Slovak committed
66 67
};

68
typedef struct knot_rrset knot_rrset_t;
Lubos Slovak's avatar
Lubos Slovak committed
69

70 71 72
/*----------------------------------------------------------------------------*/

typedef enum {
Lubos Slovak's avatar
Lubos Slovak committed
73 74 75
	KNOT_RRSET_COMPARE_PTR,
	KNOT_RRSET_COMPARE_HEADER,
	KNOT_RRSET_COMPARE_WHOLE
76
} knot_rrset_compare_type_t;
77

78
typedef enum  {
Lubos Slovak's avatar
Lubos Slovak committed
79 80 81
	KNOT_RRSET_DUPL_MERGE,
	KNOT_RRSET_DUPL_REPLACE,
	KNOT_RRSET_DUPL_SKIP
82
} knot_rrset_dupl_handling_t;
83

84
/*----------------------------------------------------------------------------*/
Jan Kadlec's avatar
Jan Kadlec committed
85 86 87

uint32_t rrset_rdata_size_total(const knot_rrset_t *rrset);

88 89 90
/*!
 * \brief Creates a new RRSet with the given properties.
 *
Lubos Slovak's avatar
Lubos Slovak committed
91 92
 * The created RRSet contains no RDATAs (i.e. is actually empty).
 *
93 94 95 96 97 98 99 100
 * \param owner OWNER of the RRSet.
 * \param type TYPE of the RRSet.
 * \param rclass CLASS of the RRSet.
 * \param ttl TTL of the RRset.
 *
 * \return New RRSet structure with the given OWNER, TYPE, CLASS and TTL or NULL
 *         if an error occured.
 */
101
knot_rrset_t *knot_rrset_new(knot_dname_t *owner, uint16_t type,
Jan Kadlec's avatar
Jan Kadlec committed
102
                                 uint16_t rclass, uint32_t ttl);
103

104 105 106 107 108 109 110 111 112 113 114
/*!
 * \brief Creates a new RRSet according to given template RRSet.
 *
 * OWNER, TYPE, CLASS, and TTL values from template RRSet are used.
 *
 * \param tmp  RRSet template.
 *
 * \return New RRSet, NULL if an error occured.
 */
knot_rrset_t *knot_rrset_new_from(const knot_rrset_t *tpl);

115 116 117 118 119
/*!
 * \brief Adds the given RDATA to the RRSet.
 *
 * \param rrset RRSet to add the RDATA to.
 * \param rdata RDATA to add to the RRSet.
120
 * \param size Size of RDATA.
121
 *
122 123
 * \retval KNOT_EINVAL on wrong arguments.
 * \retval KNOT_EOK on success.
124
 */
Lubos Slovak's avatar
Lubos Slovak committed
125
int knot_rrset_add_rdata(knot_rrset_t *rrset, const uint8_t *rdata,
126
                         uint16_t size);
127

Jan Kadlec's avatar
Jan Kadlec committed
128
/*!
129
 * \brief Creates RDATA memory and returns a pointer to it.
Jan Včelák's avatar
Jan Včelák committed
130
 *        If the RRSet is not empty, function will return a memory
131
 *        pointing to a beginning of a new RR. (Indices will be handled as well)
Jan Kadlec's avatar
Jan Kadlec committed
132 133
 *
 * \param rrset RRSet to add the RDATA to.
134
 * \param size Size of RR RDATA (Size in internal representation)
Jan Kadlec's avatar
Jan Kadlec committed
135
 *
136 137
 * \return Pointer to memory to be written to.
 * \retval NULL if arguments are invalid
Jan Kadlec's avatar
Jan Kadlec committed
138
 */
Lubos Slovak's avatar
Lubos Slovak committed
139
uint8_t* knot_rrset_create_rdata(knot_rrset_t *rrset, const uint16_t size);
140

141 142 143 144 145 146 147 148 149
/*!
 * \brief Returns size of an RR RDATA on a given position.
 *
 * \param rrset RRSet holding RR RDATA.
 * \param pos RR position.
 *
 * \retval 0 on error.
 * \return Item size on success.
 */
150
/* [code-review] Misleading name, maybe remove the word 'item'. And add knot. */
151
uint16_t rrset_rdata_item_size(const knot_rrset_t *rrset,
152 153
                               size_t pos);

154
/*!
155
 * \brief Adds RRSIG signatures to this RRSet.
156
 *
157 158
 * \param rrset RRSet to add the signatures into.
 * \param rrsigs Set of RRSIGs covering this RRSet.
159
 *
Lubos Slovak's avatar
Lubos Slovak committed
160
 * \retval KNOT_EOK
Marek Vavrusa's avatar
Marek Vavrusa committed
161
 * \retval KNOT_EINVAL
162
 */
163
int knot_rrset_set_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs);
164

165 166 167 168 169 170 171 172 173 174 175 176
/*!
 * \brief Adds RRSIG signatures to this RRSet.
 *
 * \param rrset RRSet to add the signatures into.
 * \param rrsigs Set of RRSIGs covering this RRSet.
 * \param dupl Merging strategy.
 *
 * \retval KNOT_EOK if no merge was needed.
 * \retval 1 if merge was needed.
 * \retval 2 if rrsig was not first, but is was skipped.
 * \retval KNOT_EINVAL on faulty arguments or rrsig does not belong to this rrset.
 */
177
//TODO test
178
int knot_rrset_add_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs,
179
                          knot_rrset_dupl_handling_t dupl);
180

181 182 183 184 185 186 187
/*!
 * \brief Returns the Owner of the RRSet.
 *
 * \param rrset RRSet to get the Owner of.
 *
 * \return Owner of the given RRSet.
 */
188
const knot_dname_t *knot_rrset_owner(const knot_rrset_t *rrset);
189

190
/*!
191 192 193 194 195
 * \brief Returns the Owner of the RRSet.
 *
 * \param rrset RRSet to get the Owner of.
 *
 * \return Owner of the given RRSet.
196
 */
197
knot_dname_t *knot_rrset_get_owner(const knot_rrset_t *rrset);
Lubos Slovak's avatar
Lubos Slovak committed
198

199 200 201 202 203 204 205 206
/*!
 * \brief Set rrset owner to specified dname.
 *
 * Previous owner will be replaced if exist.
 *
 * \param rrset Specified RRSet.
 * \param owner New owner dname.
 */
207
int knot_rrset_set_owner(knot_rrset_t *rrset, const knot_dname_t *owner);
208

209 210 211 212 213 214
/*!
 * \brief Sets rrset TTL to given TTL.
 *
 * \param rrset Specified RRSet.
 * \param ttl New TTL.
 */
Lubos Slovak's avatar
Lubos Slovak committed
215 216
void knot_rrset_set_ttl(knot_rrset_t *rrset, uint32_t ttl);

217 218
void knot_rrset_set_class(knot_rrset_t *rrset, uint16_t rclass);

219 220 221 222 223 224 225
/*!
 * \brief Returns the TYPE of the RRSet.
 *
 * \param rrset RRSet to get the TYPE of.
 *
 * \return TYPE of the given RRSet.
 */
226
uint16_t knot_rrset_type(const knot_rrset_t *rrset);
227 228 229 230 231 232 233 234

/*!
 * \brief Returns the CLASS of the RRSet.
 *
 * \param rrset RRSet to get the CLASS of.
 *
 * \return CLASS of the given RRSet.
 */
235
uint16_t knot_rrset_class(const knot_rrset_t *rrset);
236 237 238 239 240 241 242 243

/*!
 * \brief Returns the TTL of the RRSet.
 *
 * \param rrset RRSet to get the TTL of.
 *
 * \return TTL of the given RRSet.
 */
244
uint32_t knot_rrset_ttl(const knot_rrset_t *rrset);
245

246
/*!
247
 * \brief Returns RDATA of RR on given position.
248 249
 *
 * \param rrset RRSet to get the RDATA from.
250
 * \param rdata_pos Position of RR to get.
251
 *
252 253
 * \retval NULL if no RDATA on rdata_pos exist.
 * \return Pointer to RDATA on given position if successfull.
254
 */
255
uint8_t *knot_rrset_get_rdata(const knot_rrset_t *rrset, size_t rdata_pos);
256

257
/*!
258
 * \brief Returns the count of RRs in a given RRSet.
259
 *
260
 * \param rrset RRSet to get the RRs count from.
261
 *
262
 * \return Count of the RRs in a given RRSet.
263 264
 */
uint16_t knot_rrset_rdata_rr_count(const knot_rrset_t *rrset);
265

266
/*!
267
 * \brief Returns the set of RRSIGs covering the given RRSet.
268 269 270
 *
 * \param rrset RRSet to get the signatures for.
 *
271 272
 * \return Set of RRSIGs which cover the given RRSet or NULL if there is none or
 *         if no rrset was provided (\a rrset is NULL).
273
 */
274
const knot_rrset_t *knot_rrset_rrsigs(const knot_rrset_t *rrset);
275

276
knot_rrset_t *knot_rrset_get_rrsigs(knot_rrset_t *rrset);
277

Jan Kadlec's avatar
Jan Kadlec committed
278
int knot_rrset_rdata_equal(const knot_rrset_t *r1, const knot_rrset_t *r2);
279

280
/*!
281
 * \brief Compares two RRSets for equality.
282 283 284 285 286
 *
 * \param r1 First RRSet.
 * \param r2 Second RRSet.
 * \param cmp Type of comparison to perform.
 *
287
 * \retval 1 if RRSets are equal.
288
 * \retval 0 if RRSets are not equal.
289
 * \retval < 0 if error occured.
290
 */
Jan Kadlec's avatar
Jan Kadlec committed
291 292 293 294
int knot_rrset_equal(const knot_rrset_t *r1,
                     const knot_rrset_t *r2,
                     knot_rrset_compare_type_t cmp);

295
int knot_rrset_deep_copy(const knot_rrset_t *from, knot_rrset_t **to);
296

297
int knot_rrset_deep_copy_no_sig(const knot_rrset_t *from, knot_rrset_t **to);
298

299
int knot_rrset_shallow_copy(const knot_rrset_t *from, knot_rrset_t **to);
300

301 302 303 304 305 306
/*! \brief Does round-robin rotation of the RRSet.
 *
 * \note This is not thread-safe. If two threads call this function, the RRSet
 *       may rotate twice, or not rotate at all. This is not a big issue though.
 *       In future we may replace this with some per-thread counter.
 */
307
void knot_rrset_rotate(knot_rrset_t *rrset);
308

309 310 311 312
/*!
 * \brief Destroys the RRSet structure.
 *
 * Does not destroy the OWNER domain name structure, nor the signatures, as
313
 * these may be used elsewhere.
314
 *
315
 * Does not destroy RDATA structures neither, as they need special processing.
316
 *
Lubos Slovak's avatar
Lubos Slovak committed
317 318 319
 * Also sets the given pointer to NULL.
 *
 * \param rrset RRset to be destroyed.
320
 */
321
void knot_rrset_free(knot_rrset_t **rrset);
322

323 324 325 326 327 328 329 330
/*!
 * \brief Destroys the RRSet structure and all its substructures.
 *
 * Also sets the given pointer to NULL.
 *
 * \param rrset RRset to be destroyed.
 * \param free_owner Set to 0 if you do not want the owner domain name to be
 *                   destroyed also. Set to <> 0 otherwise.
331 332
 * \param free_rdata_dnames Set to <> 0 if you want to delete ALL domain names
 *                          present in RDATA. Set to 0 otherwise. (See
333
 *                          knot_rdata_deep_free().)
334
 */
335
void knot_rrset_deep_free(knot_rrset_t **rrset, int free_owner);
336

337
void knot_rrset_deep_free_no_sig(knot_rrset_t **rrset, int free_owner);
338

339
int knot_rrset_to_wire(const knot_rrset_t *rrset, uint8_t *wire, size_t *size,
Marek Vavrusa's avatar
Marek Vavrusa committed
340
                       size_t max_size, uint16_t *rr_count, struct knot_compr *compr);
341

342 343 344 345 346
/*!
 * \brief Write one RR from RRSet.
 */
int knot_rrset_to_wire_one(const knot_rrset_t *rrset, uint16_t rr_number,
                           uint8_t *wire, size_t max_size, size_t *outsize,
Marek Vavrusa's avatar
Marek Vavrusa committed
347
                           struct knot_compr *compr);
348

349 350 351 352
/*!
 * \brief Merges two RRSets.
 *
 * Merges \a r1 into \a r2 by concatenating the list of RDATAs in \a r2 after
Jan Kadlec's avatar
Jan Kadlec committed
353 354 355
 * the list of RDATAs in \a r1. You must not
 * destroy the RDATAs in \a r2 as they are now identical to RDATAs in \a r1.
 * (You may use function knot_rrset_free() though, as it does not touch RDATAs).
356
 *
Lubos Slovak's avatar
Lubos Slovak committed
357
 * \note Member \a rrsigs is preserved from the first RRSet.
358 359 360 361
 *
 * \param r1 Pointer to RRSet to be merged into.
 * \param r2 Poitner to RRSet to be merged.
 *
Lubos Slovak's avatar
Lubos Slovak committed
362
 * \retval KNOT_EOK
Marek Vavrusa's avatar
Marek Vavrusa committed
363
 * \retval KNOT_EINVAL if the RRSets could not be merged, because their
364
 *         Owner, Type, Class or TTL does not match.
365
 */
366
int knot_rrset_merge(knot_rrset_t *rrset1, const knot_rrset_t *rrset2);
367
/*! \brief Merges without with duplicate check, with sort. */
368 369
int knot_rrset_merge_sort(knot_rrset_t *rrset1, const knot_rrset_t *rrset2,
                          int *merged, int *deleted_rrs);
370

371 372 373 374 375 376 377 378 379
/*!
 * \brief Sort RDATA in RRSet to be in caonical order.
 * \todo Not optimal, rewrite!
 *
 * \param rrset  RRSet to be sorted.
 * \return Error code, KNOT_EOK when successful.
 */
int knot_rrset_sort_rdata(knot_rrset_t *rrset);

Marek Vavrusa's avatar
Marek Vavrusa committed
380 381 382 383 384 385 386
/*!
 * \brief Return true if the RRSet is an NSEC3 related type.
 *
 * \param rr RRSet.
 */
bool knot_rrset_is_nsec3rel(const knot_rrset_t *rr);

387
void knot_rrset_dump(const knot_rrset_t *rrset);
388

389 390
//TODO test
int rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream, size_t *size);
391
uint64_t rrset_binary_size(const knot_rrset_t *rrset);
392 393 394 395 396 397

//TODO test
int rrset_serialize_alloc(const knot_rrset_t *rrset, uint8_t **stream,
                          size_t *size);

//TODO test
Jan Kadlec's avatar
Jan Kadlec committed
398
int rrset_deserialize(uint8_t *stream, size_t *stream_size,
399
                      knot_rrset_t **rrset);
400

401
/* \brief Adds RR on 'pos' position from 'source' to 'dest' */
402 403
int knot_rrset_add_rr_from_rrset(knot_rrset_t *dest, const knot_rrset_t *source,
                                 size_t rdata_pos);
404 405
/* \brief Removes RRs contained in 'what' RRSet from 'from' RRSet.
 *        Deleted RRs are returned in 'rr_deleted' */
Jan Kadlec's avatar
Jan Kadlec committed
406 407
int knot_rrset_remove_rr_using_rrset(knot_rrset_t *from,
                                     const knot_rrset_t *what,
408
                                     knot_rrset_t **rr_deleted);
409
/* \brief Removes RRs contained in 'what' RRSet from 'from' RRSet. */
Jan Kadlec's avatar
Jan Kadlec committed
410 411
int knot_rrset_remove_rr_using_rrset_del(knot_rrset_t *from,
                                         const knot_rrset_t *what);
412 413
/* \brief Finds RR at 'pos' position in 'rr_reference' RRSet in 
         'rr_search_in' RRSet. Position returned in 'pos_out'. */
Jan Kadlec's avatar
Jan Kadlec committed
414 415
int knot_rrset_find_rr_pos(const knot_rrset_t *rr_search_in,
                           const knot_rrset_t *rr_reference, size_t pos,
416
                           size_t *pos_out);
417
/* \brief Creates one RR from wire, stores it into 'rrset'. */
Jan Včelák's avatar
Jan Včelák committed
418
int knot_rrset_rdata_from_wire_one(knot_rrset_t *rrset,
419 420 421
                                   const uint8_t *wire, size_t *pos,
                                   size_t total_size, size_t rdlength);

422
int knot_rrset_ds_check(const knot_rrset_t *rrset);
423 424 425

uint8_t *rrset_rdata_pointer(const knot_rrset_t *rrset, size_t pos);

426 427 428
int rrset_rdata_compare_one(const knot_rrset_t *rrset1,
                            const knot_rrset_t *rrset2,
                            size_t pos1, size_t pos2);
Lubos Slovak's avatar
Lubos Slovak committed
429
#endif /* _KNOT_RRSET_H_ */
430 431

/*! @} */