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