]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-rr.h
Merge pull request #2190 from poettering/dnssec6
[thirdparty/systemd.git] / src / resolve / resolved-dns-rr.h
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 #pragma once
4
5 /***
6 This file is part of systemd.
7
8 Copyright 2014 Lennart Poettering
9
10 systemd is free software; you can redistribute it and/or modify it
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 ***/
23
24 #include <netinet/in.h>
25
26 #include "bitmap.h"
27 #include "dns-type.h"
28 #include "hashmap.h"
29 #include "in-addr-util.h"
30 #include "list.h"
31
32 typedef struct DnsResourceKey DnsResourceKey;
33 typedef struct DnsResourceRecord DnsResourceRecord;
34 typedef struct DnsTxtItem DnsTxtItem;
35
36 /* DNSKEY RR flags */
37 #define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8)
38 #define DNSKEY_FLAG_SEP (UINT16_C(1) << 0)
39
40 /* mDNS RR flags */
41 #define MDNS_RR_CACHE_FLUSH (UINT16_C(1) << 15)
42
43 /* DNSSEC algorithm identifiers, see
44 * http://tools.ietf.org/html/rfc4034#appendix-A.1 and
45 * https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
46 enum {
47 DNSSEC_ALGORITHM_RSAMD5 = 1,
48 DNSSEC_ALGORITHM_DH,
49 DNSSEC_ALGORITHM_DSA,
50 DNSSEC_ALGORITHM_ECC,
51 DNSSEC_ALGORITHM_RSASHA1,
52 DNSSEC_ALGORITHM_DSA_NSEC3_SHA1,
53 DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
54 DNSSEC_ALGORITHM_RSASHA256 = 8, /* RFC 5702 */
55 DNSSEC_ALGORITHM_RSASHA512 = 10, /* RFC 5702 */
56 DNSSEC_ALGORITHM_INDIRECT = 252,
57 DNSSEC_ALGORITHM_PRIVATEDNS,
58 DNSSEC_ALGORITHM_PRIVATEOID,
59 _DNSSEC_ALGORITHM_MAX_DEFINED
60 };
61
62 /* DNSSEC digest identifiers, see
63 * https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
64 enum {
65 DNSSEC_DIGEST_SHA1 = 1,
66 DNSSEC_DIGEST_SHA256 = 2,
67 _DNSSEC_DIGEST_MAX_DEFINED
68 };
69
70 struct DnsResourceKey {
71 unsigned n_ref;
72 uint16_t class, type;
73 char *_name; /* don't access directy, use DNS_RESOURCE_KEY_NAME()! */
74 };
75
76 /* Creates a temporary resource key. This is only useful to quickly
77 * look up something, without allocating a full DnsResourceKey object
78 * for it. Note that it is not OK to take references to this kind of
79 * resource key object. */
80 #define DNS_RESOURCE_KEY_CONST(c, t, n) \
81 ((DnsResourceKey) { \
82 .n_ref = (unsigned) -1, \
83 .class = c, \
84 .type = t, \
85 ._name = (char*) n, \
86 })
87
88
89 struct DnsTxtItem {
90 size_t length;
91 LIST_FIELDS(DnsTxtItem, items);
92 uint8_t data[];
93 };
94
95 struct DnsResourceRecord {
96 unsigned n_ref;
97 DnsResourceKey *key;
98 uint32_t ttl;
99 bool unparseable:1;
100 bool wire_format_canonical:1;
101 void *wire_format;
102 size_t wire_format_size;
103 size_t wire_format_rdata_offset;
104 union {
105 struct {
106 void *data;
107 size_t size;
108 } generic, opt;
109
110 struct {
111 uint16_t priority;
112 uint16_t weight;
113 uint16_t port;
114 char *name;
115 } srv;
116
117 struct {
118 char *name;
119 } ptr, ns, cname, dname;
120
121 struct {
122 char *cpu;
123 char *os;
124 } hinfo;
125
126 struct {
127 DnsTxtItem *items;
128 } txt, spf;
129
130 struct {
131 struct in_addr in_addr;
132 } a;
133
134 struct {
135 struct in6_addr in6_addr;
136 } aaaa;
137
138 struct {
139 char *mname;
140 char *rname;
141 uint32_t serial;
142 uint32_t refresh;
143 uint32_t retry;
144 uint32_t expire;
145 uint32_t minimum;
146 } soa;
147
148 struct {
149 uint16_t priority;
150 char *exchange;
151 } mx;
152
153 struct {
154 uint8_t version;
155 uint8_t size;
156 uint8_t horiz_pre;
157 uint8_t vert_pre;
158 uint32_t latitude;
159 uint32_t longitude;
160 uint32_t altitude;
161 } loc;
162
163 struct {
164 uint16_t key_tag;
165 uint8_t algorithm;
166 uint8_t digest_type;
167 void *digest;
168 size_t digest_size;
169 } ds;
170
171 /* https://tools.ietf.org/html/rfc4255#section-3.1 */
172 struct {
173 uint8_t algorithm;
174 uint8_t fptype;
175 void *fingerprint;
176 size_t fingerprint_size;
177 } sshfp;
178
179 /* http://tools.ietf.org/html/rfc4034#section-2.1 */
180 struct {
181 uint16_t flags;
182 uint8_t protocol;
183 uint8_t algorithm;
184 void* key;
185 size_t key_size;
186 } dnskey;
187
188 /* http://tools.ietf.org/html/rfc4034#section-3.1 */
189 struct {
190 uint16_t type_covered;
191 uint8_t algorithm;
192 uint8_t labels;
193 uint32_t original_ttl;
194 uint32_t expiration;
195 uint32_t inception;
196 uint16_t key_tag;
197 char *signer;
198 void *signature;
199 size_t signature_size;
200 } rrsig;
201
202 /* https://tools.ietf.org/html/rfc4034#section-4.1 */
203 struct {
204 char *next_domain_name;
205 Bitmap *types;
206 } nsec;
207
208 struct {
209 uint8_t algorithm;
210 uint8_t flags;
211 uint16_t iterations;
212 void *salt;
213 size_t salt_size;
214 void *next_hashed_name;
215 size_t next_hashed_name_size;
216 Bitmap *types;
217 } nsec3;
218 };
219 };
220
221 static inline const char* DNS_RESOURCE_KEY_NAME(const DnsResourceKey *key) {
222 if (_unlikely_(!key))
223 return NULL;
224
225 if (key->_name)
226 return key->_name;
227
228 return (char*) key + sizeof(DnsResourceKey);
229 }
230
231 DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name);
232 DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname);
233 int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key, char *name);
234 DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name);
235 DnsResourceKey* dns_resource_key_ref(DnsResourceKey *key);
236 DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
237 bool dns_resource_key_is_address(const DnsResourceKey *key);
238 int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b);
239 int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain);
240 int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain);
241 int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *soa);
242 int dns_resource_key_to_string(const DnsResourceKey *key, char **ret);
243 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey*, dns_resource_key_unref);
244
245 static inline bool dns_key_is_shared(const DnsResourceKey *key) {
246 return IN_SET(key->type, DNS_TYPE_PTR);
247 }
248
249 DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key);
250 DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name);
251 DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr);
252 DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr);
253 int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name);
254 int dns_resource_record_new_address(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name);
255 int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b);
256 int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret);
257 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref);
258
259 int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical);
260
261 DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i);
262 bool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b);
263
264 extern const struct hash_ops dns_resource_key_hash_ops;
265
266 const char* dnssec_algorithm_to_string(int i) _const_;
267 int dnssec_algorithm_from_string(const char *s) _pure_;
268
269 const char *dnssec_digest_to_string(int i) _const_;
270 int dnssec_digest_from_string(const char *s) _pure_;