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