1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <netinet/in.h>
9 #include "in-addr-util.h"
11 #include "string-util.h"
12 #include "time-util.h"
14 typedef struct DnsResourceKey DnsResourceKey
;
15 typedef struct DnsResourceRecord DnsResourceRecord
;
16 typedef struct DnsTxtItem DnsTxtItem
;
19 #define DNSKEY_FLAG_SEP (UINT16_C(1) << 0)
20 #define DNSKEY_FLAG_REVOKE (UINT16_C(1) << 7)
21 #define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8)
24 #define MDNS_RR_CACHE_FLUSH (UINT16_C(1) << 15)
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 */
30 DNSSEC_ALGORITHM_RSAMD5
= 1,
34 DNSSEC_ALGORITHM_RSASHA1
,
35 DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
,
36 DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
,
37 DNSSEC_ALGORITHM_RSASHA256
= 8, /* RFC 5702 */
38 DNSSEC_ALGORITHM_RSASHA512
= 10, /* RFC 5702 */
39 DNSSEC_ALGORITHM_ECC_GOST
= 12, /* RFC 5933 */
40 DNSSEC_ALGORITHM_ECDSAP256SHA256
= 13, /* RFC 6605 */
41 DNSSEC_ALGORITHM_ECDSAP384SHA384
= 14, /* RFC 6605 */
42 DNSSEC_ALGORITHM_ED25519
= 15, /* RFC 8080 */
43 DNSSEC_ALGORITHM_ED448
= 16, /* RFC 8080 */
44 DNSSEC_ALGORITHM_INDIRECT
= 252,
45 DNSSEC_ALGORITHM_PRIVATEDNS
,
46 DNSSEC_ALGORITHM_PRIVATEOID
,
47 _DNSSEC_ALGORITHM_MAX_DEFINED
50 /* DNSSEC digest identifiers, see
51 * https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
53 DNSSEC_DIGEST_SHA1
= 1,
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 */
57 _DNSSEC_DIGEST_MAX_DEFINED
60 /* DNSSEC NSEC3 hash algorithms, see
61 * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */
63 NSEC3_ALGORITHM_SHA1
= 1,
64 _NSEC3_ALGORITHM_MAX_DEFINED
67 struct DnsResourceKey
{
68 unsigned n_ref
; /* (unsigned -1) for const keys, see below */
70 char *_name
; /* don't access directly, use dns_resource_key_name()! */
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) \
79 .n_ref = (unsigned) -1, \
87 LIST_FIELDS(DnsTxtItem
, items
);
91 struct DnsResourceRecord
{
98 usec_t expiry
; /* RRSIG signature expiry */
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
;
107 bool wire_format_canonical
:1;
109 size_t wire_format_size
;
110 size_t wire_format_rdata_offset
;
127 } ptr
, ns
, cname
, dname
;
139 struct in_addr in_addr
;
143 struct in6_addr in6_addr
;
161 /* https://tools.ietf.org/html/rfc1876 */
172 /* https://tools.ietf.org/html/rfc4255#section-3.1 */
177 size_t fingerprint_size
;
180 /* http://tools.ietf.org/html/rfc4034#section-2.1 */
189 /* http://tools.ietf.org/html/rfc4034#section-3.1 */
191 uint16_t type_covered
;
194 uint32_t original_ttl
;
200 size_t signature_size
;
203 /* https://tools.ietf.org/html/rfc4034#section-4.1 */
205 char *next_domain_name
;
209 /* https://tools.ietf.org/html/rfc4034#section-5.1 */
224 void *next_hashed_name
;
225 size_t next_hashed_name_size
;
229 /* https://tools.ietf.org/html/draft-ietf-dane-protocol-23 */
233 uint8_t matching_type
;
238 /* https://tools.ietf.org/html/rfc6844 */
248 static inline const void* DNS_RESOURCE_RECORD_RDATA(const DnsResourceRecord
*rr
) {
252 if (!rr
->wire_format
)
255 assert(rr
->wire_format_rdata_offset
<= rr
->wire_format_size
);
256 return (uint8_t*) rr
->wire_format
+ rr
->wire_format_rdata_offset
;
259 static inline size_t DNS_RESOURCE_RECORD_RDATA_SIZE(const DnsResourceRecord
*rr
) {
262 if (!rr
->wire_format
)
265 assert(rr
->wire_format_rdata_offset
<= rr
->wire_format_size
);
266 return rr
->wire_format_size
- rr
->wire_format_rdata_offset
;
269 static inline uint8_t DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(const DnsResourceRecord
*rr
) {
271 assert(rr
->key
->type
== DNS_TYPE_OPT
);
273 return ((rr
->ttl
>> 16) & 0xFF) == 0;
276 DnsResourceKey
* dns_resource_key_new(uint16_t class, uint16_t type
, const char *name
);
277 DnsResourceKey
* dns_resource_key_new_redirect(const DnsResourceKey
*key
, const DnsResourceRecord
*cname
);
278 int dns_resource_key_new_append_suffix(DnsResourceKey
**ret
, DnsResourceKey
*key
, char *name
);
279 DnsResourceKey
* dns_resource_key_new_consume(uint16_t class, uint16_t type
, char *name
);
280 DnsResourceKey
* dns_resource_key_ref(DnsResourceKey
*key
);
281 DnsResourceKey
* dns_resource_key_unref(DnsResourceKey
*key
);
282 const char* dns_resource_key_name(const DnsResourceKey
*key
);
283 bool dns_resource_key_is_address(const DnsResourceKey
*key
);
284 bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey
*key
);
285 int dns_resource_key_equal(const DnsResourceKey
*a
, const DnsResourceKey
*b
);
286 int dns_resource_key_match_rr(const DnsResourceKey
*key
, DnsResourceRecord
*rr
, const char *search_domain
);
287 int dns_resource_key_match_cname_or_dname(const DnsResourceKey
*key
, const DnsResourceKey
*cname
, const char *search_domain
);
288 int dns_resource_key_match_soa(const DnsResourceKey
*key
, const DnsResourceKey
*soa
);
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)
294 char* dns_resource_key_to_string(const DnsResourceKey
*key
, char *buf
, size_t buf_size
);
295 ssize_t
dns_resource_record_payload(DnsResourceRecord
*rr
, void **out
);
297 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey
*, dns_resource_key_unref
);
299 static inline bool dns_key_is_shared(const DnsResourceKey
*key
) {
300 return IN_SET(key
->type
, DNS_TYPE_PTR
);
303 bool dns_resource_key_reduce(DnsResourceKey
**a
, DnsResourceKey
**b
);
305 DnsResourceRecord
* dns_resource_record_new(DnsResourceKey
*key
);
306 DnsResourceRecord
* dns_resource_record_new_full(uint16_t class, uint16_t type
, const char *name
);
307 DnsResourceRecord
* dns_resource_record_ref(DnsResourceRecord
*rr
);
308 DnsResourceRecord
* dns_resource_record_unref(DnsResourceRecord
*rr
);
309 int dns_resource_record_new_reverse(DnsResourceRecord
**ret
, int family
, const union in_addr_union
*address
, const char *name
);
310 int dns_resource_record_new_address(DnsResourceRecord
**ret
, int family
, const union in_addr_union
*address
, const char *name
);
311 int dns_resource_record_equal(const DnsResourceRecord
*a
, const DnsResourceRecord
*b
);
312 int dns_resource_record_payload_equal(const DnsResourceRecord
*a
, const DnsResourceRecord
*b
);
314 const char* dns_resource_record_to_string(DnsResourceRecord
*rr
);
315 DnsResourceRecord
*dns_resource_record_copy(DnsResourceRecord
*rr
);
316 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord
*, dns_resource_record_unref
);
318 int dns_resource_record_to_wire_format(DnsResourceRecord
*rr
, bool canonical
);
320 int dns_resource_record_signer(DnsResourceRecord
*rr
, const char **ret
);
321 int dns_resource_record_source(DnsResourceRecord
*rr
, const char **ret
);
322 int dns_resource_record_is_signer(DnsResourceRecord
*rr
, const char *zone
);
323 int dns_resource_record_is_synthetic(DnsResourceRecord
*rr
);
325 int dns_resource_record_clamp_ttl(DnsResourceRecord
**rr
, uint32_t max_ttl
);
327 DnsTxtItem
*dns_txt_item_free_all(DnsTxtItem
*i
);
328 bool dns_txt_item_equal(DnsTxtItem
*a
, DnsTxtItem
*b
);
329 DnsTxtItem
*dns_txt_item_copy(DnsTxtItem
*i
);
330 int dns_txt_item_new_empty(DnsTxtItem
**ret
);
332 void dns_resource_record_hash_func(const DnsResourceRecord
*i
, struct siphash
*state
);
334 extern const struct hash_ops dns_resource_key_hash_ops
;
335 extern const struct hash_ops dns_resource_record_hash_ops
;
337 int dnssec_algorithm_to_string_alloc(int i
, char **ret
);
338 int dnssec_algorithm_from_string(const char *s
) _pure_
;
340 int dnssec_digest_to_string_alloc(int i
, char **ret
);
341 int dnssec_digest_from_string(const char *s
) _pure_
;