1 /* Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 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/>.
15 */
16
17 /*!
18 * \file
19 *
20 * \brief RRSet structure and API for manipulating it.
21 *
22 * \addtogroup rr
23 * @{
24 */
25
26 #pragma once
27
28 #include <stdint.h>
29 #include <stdbool.h>
30
31 #include "libknot/dname.h"
32 #include "libknot/descriptor.h"
33 #include "libknot/mm_ctx.h"
34 #include "libknot/rdataset.h"
35
36 /*!
37 * \brief Structure for representing RRSet.
38 *
39 * For RRSet definition see RFC2181, Section 5.
40 */
41 typedef struct {
42 knot_dname_t *owner; /*!< Domain name being the owner of the RRSet. */
43 uint32_t ttl; /*!< TTL of the RRset. */
44 uint16_t type; /*!< TYPE of the RRset. */
45 uint16_t rclass; /*!< CLASS of the RRSet. */
46 knot_rdataset_t rrs; /*!< RRSet's RRs */
47 /* Optional fields. */
48 void *additional; /*!< Additional records. */
49 } knot_rrset_t;
50
51 /*!
52 * \brief Creates a new RRSet with the given properties.
53 *
54 * The created RRSet contains no RDATAs (i.e. is actually empty).
55 *
56 * \param owner OWNER of the RRSet.
57 * \param type TYPE of the RRSet.
58 * \param rclass CLASS of the RRSet.
59 * \param ttl TTL of the RRSet.
60 * \param mm Memory context.
61 *
62 * \return New RRSet structure or NULL if an error occurred.
63 */
64 knot_rrset_t *knot_rrset_new(const knot_dname_t *owner, uint16_t type,
65 uint16_t rclass, uint32_t ttl, knot_mm_t *mm);
66
67 /*!
68 * \brief Initializes RRSet structure with given data.
69 *
70 * \param rrset RRSet to init.
71 * \param owner RRSet owner to use.
72 * \param type RR type to use.
73 * \param rclass Class to use.
74 * \param ttl TTL to use.
75 */
knot_rrset_init(knot_rrset_t * rrset,knot_dname_t * owner,uint16_t type,uint16_t rclass,uint32_t ttl)76 inline static void knot_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner,
77 uint16_t type, uint16_t rclass, uint32_t ttl)
78 {
79 if (rrset != NULL) {
80 rrset->owner = owner;
81 rrset->type = type;
82 rrset->rclass = rclass;
83 rrset->ttl = ttl;
84 knot_rdataset_init(&rrset->rrs);
85 rrset->additional = NULL;
86 }
87 }
88
89 /*!
90 * \brief Initializes given RRSet structure.
91 *
92 * \param rrset RRSet to init.
93 */
knot_rrset_init_empty(knot_rrset_t * rrset)94 inline static void knot_rrset_init_empty(knot_rrset_t *rrset)
95 {
96 knot_rrset_init(rrset, NULL, 0, KNOT_CLASS_IN, 0);
97 }
98
99 /*!
100 * \brief Creates new RRSet from \a src RRSet.
101 *
102 * \param src Source RRSet.
103 * \param mm Memory context.
104 *
105 * \retval Pointer to new RRSet if all went OK.
106 * \retval NULL on error.
107 */
108 knot_rrset_t *knot_rrset_copy(const knot_rrset_t *src, knot_mm_t *mm);
109
110 /*!
111 * \brief Destroys the RRSet structure and all its substructures.
112 *
113 * \param rrset RRset to be destroyed.
114 * \param mm Memory context.
115 */
116 void knot_rrset_free(knot_rrset_t *rrset, knot_mm_t *mm);
117
118 /*!
119 * \brief Frees structures inside RRSet, but not the RRSet itself.
120 *
121 * \param rrset RRSet to be cleared.
122 * \param mm Memory context used for allocations.
123 */
124 void knot_rrset_clear(knot_rrset_t *rrset, knot_mm_t *mm);
125
126 /*!
127 * \brief Adds the given RDATA to the RRSet.
128 *
129 * \param rrset RRSet to add the RDATA to.
130 * \param data RDATA to add to the RRSet.
131 * \param len Length of RDATA.
132 * \param mm Memory context.
133 *
134 * \return KNOT_E*
135 */
136 int knot_rrset_add_rdata(knot_rrset_t *rrset, const uint8_t *data, uint16_t len,
137 knot_mm_t *mm);
138
139 /*!
140 * \brief Compares two RRSets for equality.
141 *
142 * \param r1 First RRSet.
143 * \param r2 Second RRSet.
144 * \param incl_ttl Compare also TTLs for equality.
145 *
146 * \retval True if RRSets are equal.
147 * \retval False if RRSets are not equal.
148 */
149 bool knot_rrset_equal(const knot_rrset_t *r1, const knot_rrset_t *r2,
150 bool incl_ttl);
151
152 /*!
153 * \brief Checks whether RRSet is empty.
154 *
155 * \param rrset RRSet to check.
156 *
157 * \retval True if RRSet is empty.
158 * \retval False if RRSet is not empty.
159 */
knot_rrset_empty(const knot_rrset_t * rrset)160 inline static bool knot_rrset_empty(const knot_rrset_t *rrset)
161 {
162 return rrset == NULL || rrset->rrs.count == 0;
163 }
164
165 /*!
166 * \brief Return whether the RR type is NSEC3 related (NSEC3 or RRSIG).
167 */
168 bool knot_rrset_is_nsec3rel(const knot_rrset_t *rr);
169
170 /*!
171 * \brief Convert one RR into canonical format.
172 *
173 * Owner is always converted to lowercase. RDATA domain names are converted only
174 * for types listed in RFC 4034, Section 6.2, except for NSEC (updated by
175 * RFC 6840, Section 5.1) and A6 (not supported).
176 *
177 * \note If RRSet with more RRs is given to this function, only the first RR
178 * will be converted.
179 * \warning This function expects either empty RDATA or full, not malformed
180 * RDATA. If malformed RRSet is passed to this function, memory errors
181 * may occur.
182 *
183 * \param rrset RR to convert.
184 */
185 int knot_rrset_rr_to_canonical(knot_rrset_t *rrset);
186
187 /*!
188 * \brief Size of rrset in wire format.
189 *
190 * \retval size in bytes
191 */
192 size_t knot_rrset_size(const knot_rrset_t *rrset);
193
194 /*! @} */
195