]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/resolve/resolved-dns-rr.c
networkd: improve error message when udev device can not be found
[thirdparty/systemd.git] / src / resolve / resolved-dns-rr.c
... / ...
CommitLineData
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include "resolved-dns-domain.h"
23#include "resolved-dns-rr.h"
24
25DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
26 DnsResourceKey *k;
27 size_t l;
28
29 assert(name);
30
31 l = strlen(name);
32 k = malloc0(sizeof(DnsResourceKey) + l + 1);
33 if (!k)
34 return NULL;
35
36 k->n_ref = 1;
37 k->class = class;
38 k->type = type;
39
40 strcpy((char*) k + sizeof(DnsResourceKey), name);
41
42 return k;
43}
44
45DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
46 DnsResourceKey *k;
47
48 assert(name);
49
50 k = new0(DnsResourceKey, 1);
51 if (!k)
52 return NULL;
53
54 k->n_ref = 1;
55 k->class = class;
56 k->type = type;
57 k->_name = name;
58
59 return k;
60}
61
62DnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
63
64 if (!k)
65 return NULL;
66
67 assert(k->n_ref > 0);
68 k->n_ref++;
69
70 return k;
71}
72
73DnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
74 if (!k)
75 return NULL;
76
77 assert(k->n_ref > 0);
78
79 if (k->n_ref == 1) {
80 free(k->_name);
81 free(k);
82 } else
83 k->n_ref--;
84
85 return NULL;
86}
87
88int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
89 int r;
90
91 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
92 if (r <= 0)
93 return r;
94
95 if (a->class != b->class)
96 return 0;
97
98 if (a->type != b->type)
99 return 0;
100
101 return 1;
102}
103
104int dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr) {
105 assert(key);
106 assert(rr);
107
108 if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
109 return 0;
110
111 if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
112 return 0;
113
114 return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
115}
116
117int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr) {
118 assert(key);
119 assert(rr);
120
121 if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
122 return 0;
123
124 if (rr->key->type != DNS_TYPE_CNAME)
125 return 0;
126
127 return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
128}
129
130unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
131 const DnsResourceKey *k = i;
132 unsigned long ul;
133
134 ul = dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), hash_key);
135 ul = ul * hash_key[0] + ul + k->class;
136 ul = ul * hash_key[1] + ul + k->type;
137
138 return ul;
139}
140
141int dns_resource_key_compare_func(const void *a, const void *b) {
142 const DnsResourceKey *x = a, *y = b;
143 int ret;
144
145 ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
146 if (ret != 0)
147 return ret;
148
149 if (x->type < y->type)
150 return -1;
151 if (x->type > y->type)
152 return 1;
153
154 if (x->class < y->class)
155 return -1;
156 if (x->class > y->class)
157 return 1;
158
159 return 0;
160}
161
162DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
163 DnsResourceRecord *rr;
164
165 rr = new0(DnsResourceRecord, 1);
166 if (!rr)
167 return NULL;
168
169 rr->n_ref = 1;
170 rr->key = dns_resource_key_ref(key);
171
172 return rr;
173}
174
175DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name) {
176 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
177
178 key = dns_resource_key_new(class, type, name);
179 if (!key)
180 return NULL;
181
182 return dns_resource_record_new(key);
183}
184
185DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
186 if (!rr)
187 return NULL;
188
189 assert(rr->n_ref > 0);
190 rr->n_ref++;
191
192 return rr;
193}
194
195DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
196 if (!rr)
197 return NULL;
198
199 assert(rr->n_ref > 0);
200
201 if (rr->n_ref > 1) {
202 rr->n_ref--;
203 return NULL;
204 }
205
206 if (rr->key) {
207 if (IN_SET(rr->key->type, DNS_TYPE_PTR, DNS_TYPE_NS, DNS_TYPE_CNAME))
208 free(rr->ptr.name);
209 else if (rr->key->type == DNS_TYPE_HINFO) {
210 free(rr->hinfo.cpu);
211 free(rr->hinfo.os);
212 } else if (rr->key->type == DNS_TYPE_SOA) {
213 free(rr->soa.mname);
214 free(rr->soa.rname);
215 } else if (!IN_SET(rr->key->type, DNS_TYPE_A, DNS_TYPE_AAAA))
216 free(rr->generic.data);
217
218 dns_resource_key_unref(rr->key);
219 }
220
221 free(rr);
222
223 return NULL;
224}
225
226int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
227 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
228 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
229 _cleanup_free_ char *ptr = NULL;
230 int r;
231
232 assert(ret);
233 assert(address);
234 assert(hostname);
235
236 r = dns_name_reverse(family, address, &ptr);
237 if (r < 0)
238 return r;
239
240 key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, ptr);
241 if (!key)
242 return -ENOMEM;
243
244 ptr = NULL;
245
246 rr = dns_resource_record_new(key);
247 if (!rr)
248 return -ENOMEM;
249
250 rr->ptr.name = strdup(hostname);
251 if (!rr->ptr.name)
252 return -ENOMEM;
253
254 *ret = rr;
255 rr = NULL;
256
257 return 0;
258}
259
260int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
261 int r;
262
263 assert(a);
264 assert(b);
265
266 r = dns_resource_key_equal(a->key, b->key);
267 if (r <= 0)
268 return r;
269
270 if (IN_SET(a->key->type, DNS_TYPE_PTR, DNS_TYPE_NS, DNS_TYPE_CNAME))
271 return dns_name_equal(a->ptr.name, b->ptr.name);
272 else if (a->key->type == DNS_TYPE_HINFO)
273 return strcasecmp(a->hinfo.cpu, b->hinfo.cpu) == 0 &&
274 strcasecmp(a->hinfo.os, b->hinfo.os) == 0;
275 else if (a->key->type == DNS_TYPE_A)
276 return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
277 else if (a->key->type == DNS_TYPE_AAAA)
278 return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
279 else if (a->key->type == DNS_TYPE_SOA) {
280 r = dns_name_equal(a->soa.mname, b->soa.mname);
281 if (r <= 0)
282 return r;
283 r = dns_name_equal(a->soa.rname, b->soa.rname);
284 if (r <= 0)
285 return r;
286
287 return a->soa.serial == b->soa.serial &&
288 a->soa.refresh == b->soa.refresh &&
289 a->soa.retry == b->soa.retry &&
290 a->soa.expire == b->soa.expire &&
291 a->soa.minimum == b->soa.minimum;
292 } else
293 return a->generic.size == b->generic.size &&
294 memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
295}
296
297const char *dns_class_to_string(uint16_t class) {
298
299 switch (class) {
300
301 case DNS_CLASS_IN:
302 return "IN";
303
304 case DNS_CLASS_ANY:
305 return "ANY";
306 }
307
308 return NULL;
309}
310
311const char *dns_type_to_string(uint16_t type) {
312
313 switch (type) {
314
315 case DNS_TYPE_A:
316 return "A";
317
318 case DNS_TYPE_NS:
319 return "NS";
320
321 case DNS_TYPE_CNAME:
322 return "CNAME";
323
324 case DNS_TYPE_SOA:
325 return "SOA";
326
327 case DNS_TYPE_PTR:
328 return "PTR";
329
330 case DNS_TYPE_HINFO:
331 return "HINFO";
332
333 case DNS_TYPE_MX:
334 return "MX";
335
336 case DNS_TYPE_TXT:
337 return "TXT";
338
339 case DNS_TYPE_AAAA:
340 return "AAAA";
341
342 case DNS_TYPE_SRV:
343 return "SRV";
344
345 case DNS_TYPE_SSHFP:
346 return "SSHFP";
347
348 case DNS_TYPE_DNAME:
349 return "DNAME";
350
351 case DNS_TYPE_ANY:
352 return "ANY";
353
354 case DNS_TYPE_OPT:
355 return "OPT";
356
357 case DNS_TYPE_TKEY:
358 return "TKEY";
359
360 case DNS_TYPE_TSIG:
361 return "TSIG";
362
363 case DNS_TYPE_IXFR:
364 return "IXFR";
365
366 case DNS_TYPE_AXFR:
367 return "AXFR";
368 }
369
370 return NULL;
371}