]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-rr.h
fundamental: rework IN_SET() to require at least three arguments
[thirdparty/systemd.git] / src / resolve / resolved-dns-rr.h
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
74b2466e
LP
2#pragma once
3
74b2466e
LP
4#include <netinet/in.h>
5
50f1e641 6#include "bitmap.h"
98e80bf9 7#include "dns-def.h"
71d35b6b 8#include "dns-type.h"
322345fd 9#include "hashmap.h"
623a4c97 10#include "in-addr-util.h"
1482c86a 11#include "json.h"
2001c805 12#include "list.h"
1c02e7ba 13#include "string-util.h"
ca78ad1d 14#include "time-util.h"
74b2466e
LP
15
16typedef struct DnsResourceKey DnsResourceKey;
17typedef struct DnsResourceRecord DnsResourceRecord;
2001c805 18typedef struct DnsTxtItem DnsTxtItem;
74b2466e 19
8730bccf 20/* DNSKEY RR flags */
82d39576
SB
21#define DNSKEY_FLAG_SEP (UINT16_C(1) << 0)
22#define DNSKEY_FLAG_REVOKE (UINT16_C(1) << 7)
23#define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8)
8730bccf 24
23502de3 25/* mDNS RR flags */
82d39576 26#define MDNS_RR_CACHE_FLUSH_OR_QU (UINT16_C(1) << 15)
23502de3 27
8730bccf
LP
28/* DNSSEC algorithm identifiers, see
29 * http://tools.ietf.org/html/rfc4034#appendix-A.1 and
30 * https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
31enum {
32 DNSSEC_ALGORITHM_RSAMD5 = 1,
33 DNSSEC_ALGORITHM_DH,
34 DNSSEC_ALGORITHM_DSA,
35 DNSSEC_ALGORITHM_ECC,
36 DNSSEC_ALGORITHM_RSASHA1,
37 DNSSEC_ALGORITHM_DSA_NSEC3_SHA1,
38 DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
6f717d08
LP
39 DNSSEC_ALGORITHM_RSASHA256 = 8, /* RFC 5702 */
40 DNSSEC_ALGORITHM_RSASHA512 = 10, /* RFC 5702 */
41 DNSSEC_ALGORITHM_ECC_GOST = 12, /* RFC 5933 */
e0240c64
LP
42 DNSSEC_ALGORITHM_ECDSAP256SHA256 = 13, /* RFC 6605 */
43 DNSSEC_ALGORITHM_ECDSAP384SHA384 = 14, /* RFC 6605 */
cb9eeb06
MCO
44 DNSSEC_ALGORITHM_ED25519 = 15, /* RFC 8080 */
45 DNSSEC_ALGORITHM_ED448 = 16, /* RFC 8080 */
8730bccf
LP
46 DNSSEC_ALGORITHM_INDIRECT = 252,
47 DNSSEC_ALGORITHM_PRIVATEDNS,
48 DNSSEC_ALGORITHM_PRIVATEOID,
49 _DNSSEC_ALGORITHM_MAX_DEFINED
50};
51
52/* DNSSEC digest identifiers, see
53 * https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
54enum {
55 DNSSEC_DIGEST_SHA1 = 1,
6f717d08
LP
56 DNSSEC_DIGEST_SHA256 = 2, /* RFC 4509 */
57 DNSSEC_DIGEST_GOST_R_34_11_94 = 3, /* RFC 5933 */
58 DNSSEC_DIGEST_SHA384 = 4, /* RFC 6605 */
8730bccf
LP
59 _DNSSEC_DIGEST_MAX_DEFINED
60};
61
d15ad742
LP
62/* DNSSEC NSEC3 hash algorithms, see
63 * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */
64enum {
65 NSEC3_ALGORITHM_SHA1 = 1,
66 _NSEC3_ALGORITHM_MAX_DEFINED
67};
68
74b2466e 69struct DnsResourceKey {
f57e3cd5 70 unsigned n_ref; /* (unsigned -1) for const keys, see below */
faa133f3 71 uint16_t class, type;
96d49011 72 char *_name; /* don't access directly, use dns_resource_key_name()! */
74b2466e
LP
73};
74
1b4f6e79
LP
75/* Creates a temporary resource key. This is only useful to quickly
76 * look up something, without allocating a full DnsResourceKey object
77 * for it. Note that it is not OK to take references to this kind of
78 * resource key object. */
79#define DNS_RESOURCE_KEY_CONST(c, t, n) \
80 ((DnsResourceKey) { \
f5fbe71d 81 .n_ref = UINT_MAX, \
1b4f6e79
LP
82 .class = c, \
83 .type = t, \
84 ._name = (char*) n, \
85 })
86
2001c805
LP
87struct DnsTxtItem {
88 size_t length;
89 LIST_FIELDS(DnsTxtItem, items);
90 uint8_t data[];
91};
92
74b2466e
LP
93struct DnsResourceRecord {
94 unsigned n_ref;
a6e890d4
ZJS
95 uint32_t ttl;
96 usec_t expiry; /* RRSIG signature expiry */
97
faa133f3 98 DnsResourceKey *key;
97c67192 99
7b50eb2e 100 char *to_string;
97c67192 101
97c67192 102 /* How many labels to strip to determine "signer" of the RRSIG (aka, the zone). -1 if not signed. */
98e80bf9 103 uint8_t n_skip_labels_signer;
97c67192 104 /* How many labels to strip to determine "synthesizing source" of this RR, i.e. the wildcard's immediate parent. -1 if not signed. */
98e80bf9 105 uint8_t n_skip_labels_source;
97c67192 106
a6e890d4
ZJS
107 bool unparsable;
108 bool wire_format_canonical;
97c67192 109
a8812dd7
LP
110 void *wire_format;
111 size_t wire_format_size;
112 size_t wire_format_rdata_offset;
97c67192 113
74b2466e
LP
114 union {
115 struct {
116 void *data;
a43a068a 117 size_t data_size;
d75acfb0 118 } generic, opt;
74b2466e 119
9c92ce6d 120 struct {
a6e890d4 121 char *name;
9c92ce6d
LP
122 uint16_t priority;
123 uint16_t weight;
124 uint16_t port;
9c92ce6d 125 } srv;
74b2466e
LP
126
127 struct {
128 char *name;
8ac4e9e1 129 } ptr, ns, cname, dname;
74b2466e
LP
130
131 struct {
132 char *cpu;
133 char *os;
134 } hinfo;
135
2e276efc 136 struct {
2001c805 137 DnsTxtItem *items;
c0eb11cf 138 } txt, spf;
74b2466e
LP
139
140 struct {
141 struct in_addr in_addr;
142 } a;
143
144 struct {
145 struct in6_addr in6_addr;
146 } aaaa;
7e8e0422
LP
147
148 struct {
149 char *mname;
150 char *rname;
151 uint32_t serial;
152 uint32_t refresh;
153 uint32_t retry;
154 uint32_t expire;
155 uint32_t minimum;
156 } soa;
946c7094
ZJS
157
158 struct {
946c7094 159 char *exchange;
a6e890d4 160 uint16_t priority;
946c7094 161 } mx;
0dae31d4 162
6af47493 163 /* https://tools.ietf.org/html/rfc1876 */
0dae31d4
ZJS
164 struct {
165 uint8_t version;
166 uint8_t size;
167 uint8_t horiz_pre;
168 uint8_t vert_pre;
169 uint32_t latitude;
170 uint32_t longitude;
171 uint32_t altitude;
172 } loc;
42cc2eeb 173
549c1a25 174 /* https://tools.ietf.org/html/rfc4255#section-3.1 */
42cc2eeb 175 struct {
549c1a25
TG
176 void *fingerprint;
177 size_t fingerprint_size;
a6e890d4
ZJS
178
179 uint8_t algorithm;
180 uint8_t fptype;
42cc2eeb 181 } sshfp;
8db0d2f5
ZJS
182
183 /* http://tools.ietf.org/html/rfc4034#section-2.1 */
184 struct {
a6e890d4
ZJS
185 void* key;
186 size_t key_size;
187
f91dc240
LP
188 uint16_t flags;
189 uint8_t protocol;
8db0d2f5 190 uint8_t algorithm;
8db0d2f5 191 } dnskey;
151226ab
ZJS
192
193 /* http://tools.ietf.org/html/rfc4034#section-3.1 */
194 struct {
a6e890d4
ZJS
195 char *signer;
196 void *signature;
197 size_t signature_size;
198
151226ab
ZJS
199 uint16_t type_covered;
200 uint8_t algorithm;
201 uint8_t labels;
202 uint32_t original_ttl;
203 uint32_t expiration;
204 uint32_t inception;
205 uint16_t key_tag;
151226ab 206 } rrsig;
50f1e641 207
9ead3519 208 /* https://tools.ietf.org/html/rfc4034#section-4.1 */
50f1e641
TG
209 struct {
210 char *next_domain_name;
211 Bitmap *types;
212 } nsec;
5d45a880 213
6af47493
LP
214 /* https://tools.ietf.org/html/rfc4034#section-5.1 */
215 struct {
a6e890d4
ZJS
216 void *digest;
217 size_t digest_size;
218
6af47493
LP
219 uint16_t key_tag;
220 uint8_t algorithm;
221 uint8_t digest_type;
6af47493
LP
222 } ds;
223
5d45a880 224 struct {
a6e890d4 225 Bitmap *types;
5d45a880
TG
226 void *salt;
227 size_t salt_size;
228 void *next_hashed_name;
229 size_t next_hashed_name_size;
a6e890d4
ZJS
230
231 uint8_t algorithm;
232 uint8_t flags;
233 uint16_t iterations;
5d45a880 234 } nsec3;
48d45d2b
ZJS
235
236 /* https://tools.ietf.org/html/draft-ietf-dane-protocol-23 */
237 struct {
a6e890d4
ZJS
238 void *data;
239 size_t data_size;
240
48d45d2b
ZJS
241 uint8_t cert_usage;
242 uint8_t selector;
243 uint8_t matching_type;
48d45d2b 244 } tlsa;
95052df3
ZJS
245
246 /* https://tools.ietf.org/html/rfc6844 */
247 struct {
95052df3
ZJS
248 char *tag;
249 void *value;
250 size_t value_size;
a6e890d4
ZJS
251
252 uint8_t flags;
95052df3 253 } caa;
74b2466e 254 };
a6e890d4
ZJS
255
256 /* Note: fields should be ordered to minimize alignment gaps. Use pahole! */
74b2466e
LP
257};
258
98e80bf9
ZJS
259/* We use uint8_t for label counts above, and UINT8_MAX/-1 has special meaning. */
260assert_cc(DNS_N_LABELS_MAX < UINT8_MAX);
261
93bab288 262static inline const void* DNS_RESOURCE_RECORD_RDATA(const DnsResourceRecord *rr) {
85aeaccc
LP
263 if (!rr)
264 return NULL;
265
266 if (!rr->wire_format)
267 return NULL;
268
269 assert(rr->wire_format_rdata_offset <= rr->wire_format_size);
270 return (uint8_t*) rr->wire_format + rr->wire_format_rdata_offset;
271}
272
93bab288 273static inline size_t DNS_RESOURCE_RECORD_RDATA_SIZE(const DnsResourceRecord *rr) {
85aeaccc
LP
274 if (!rr)
275 return 0;
276 if (!rr->wire_format)
277 return 0;
278
279 assert(rr->wire_format_rdata_offset <= rr->wire_format_size);
280 return rr->wire_format_size - rr->wire_format_rdata_offset;
281}
282
93bab288 283static inline uint8_t DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(const DnsResourceRecord *rr) {
b30bf55d
LP
284 assert(rr);
285 assert(rr->key->type == DNS_TYPE_OPT);
286
287 return ((rr->ttl >> 16) & 0xFF) == 0;
288}
289
faa133f3 290DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name);
36d9205d 291DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname);
801ad6a6 292int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key, char *name);
faa133f3
LP
293DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name);
294DnsResourceKey* dns_resource_key_ref(DnsResourceKey *key);
295DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
57318441
ZJS
296
297#define DNS_RESOURCE_KEY_REPLACE(a, b) \
298 do { \
299 typeof(a)* _a = &(a); \
300 typeof(b) _b = (b); \
301 dns_resource_key_unref(*_a); \
302 *_a = _b; \
303 } while(0)
304
1c02e7ba 305const char* dns_resource_key_name(const DnsResourceKey *key);
28b9b764 306bool dns_resource_key_is_address(const DnsResourceKey *key);
a2bf8a19 307bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key);
faa133f3 308int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b);
105e1512 309int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain);
5d27351f 310int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain);
547973de 311int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *soa);
202b76ae
ZJS
312
313/* _DNS_{CLASS,TYPE}_STRING_MAX include one byte for NUL, which we use for space instead below.
314 * DNS_HOSTNAME_MAX does not include the NUL byte, so we need to add 1. */
315#define DNS_RESOURCE_KEY_STRING_MAX (_DNS_CLASS_STRING_MAX + _DNS_TYPE_STRING_MAX + DNS_HOSTNAME_MAX + 1)
316
317char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t buf_size);
2e74028a
ZJS
318ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out);
319
faa133f3 320DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey*, dns_resource_key_unref);
322345fd 321
7778dfff 322static inline bool dns_key_is_shared(const DnsResourceKey *key) {
4f06325c 323 return key->type == DNS_TYPE_PTR;
7778dfff
DM
324}
325
f57e3cd5
LP
326bool dns_resource_key_reduce(DnsResourceKey **a, DnsResourceKey **b);
327
faa133f3 328DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key);
8bf52d3d 329DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name);
74b2466e
LP
330DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr);
331DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr);
7daeec3e
ZJS
332
333#define DNS_RR_REPLACE(a, b) \
334 do { \
335 typeof(a)* _a = &(a); \
336 typeof(b) _b = (b); \
337 dns_resource_record_unref(*_a); \
338 *_a = _b; \
339 } while(0)
340
623a4c97 341int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name);
78c6a153 342int dns_resource_record_new_address(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name);
322345fd 343int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b);
51969a58
ZJS
344int dns_resource_record_payload_equal(const DnsResourceRecord *a, const DnsResourceRecord *b);
345
7b50eb2e 346const char* dns_resource_record_to_string(DnsResourceRecord *rr);
17c8de63 347DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr);
faa133f3 348DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref);
322345fd 349
a8812dd7
LP
350int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical);
351
97c67192
LP
352int dns_resource_record_signer(DnsResourceRecord *rr, const char **ret);
353int dns_resource_record_source(DnsResourceRecord *rr, const char **ret);
354int dns_resource_record_is_signer(DnsResourceRecord *rr, const char *zone);
ab481675 355int dns_resource_record_is_synthetic(DnsResourceRecord *rr);
97c67192 356
17c8de63
LP
357int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl);
358
48662847
LP
359bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr);
360
d1f8fbea
LP
361int dns_resource_record_get_cname_target(DnsResourceKey *key, DnsResourceRecord *cname, char **ret);
362
2001c805
LP
363DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i);
364bool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b);
17c8de63 365DnsTxtItem *dns_txt_item_copy(DnsTxtItem *i);
ebb779dc 366int dns_txt_item_new_empty(DnsTxtItem **ret);
2001c805 367
ab26cdf7
LP
368int dns_resource_record_new_from_raw(DnsResourceRecord **ret, const void *data, size_t size);
369
1482c86a
LP
370int dns_resource_key_to_json(DnsResourceKey *key, JsonVariant **ret);
371int dns_resource_record_to_json(DnsResourceRecord *rr, JsonVariant **ret);
372
7a08d314 373void dns_resource_record_hash_func(const DnsResourceRecord *i, struct siphash *state);
ae45e1a3 374int dns_resource_record_compare_func(const DnsResourceRecord *x, const DnsResourceRecord *y);
6d99904f 375
d5099efc 376extern const struct hash_ops dns_resource_key_hash_ops;
c9c72065 377extern const struct hash_ops dns_resource_record_hash_ops;
8730bccf 378
8e54f5d9 379int dnssec_algorithm_to_string_alloc(int i, char **ret);
8730bccf
LP
380int dnssec_algorithm_from_string(const char *s) _pure_;
381
8e54f5d9 382int dnssec_digest_to_string_alloc(int i, char **ret);
8730bccf 383int dnssec_digest_from_string(const char *s) _pure_;