File: | build-scan/../src/resolve/resolved-dns-answer.c |
Warning: | line 757, column 24 Potential leak of memory pointed to by 'n' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include "alloc-util.h" | |||
4 | #include "dns-domain.h" | |||
5 | #include "resolved-dns-answer.h" | |||
6 | #include "resolved-dns-dnssec.h" | |||
7 | #include "string-util.h" | |||
8 | ||||
9 | DnsAnswer *dns_answer_new(size_t n) { | |||
10 | DnsAnswer *a; | |||
11 | ||||
12 | a = malloc0(offsetof(DnsAnswer, items) + sizeof(DnsAnswerItem) * n)(calloc(1, (__builtin_offsetof(DnsAnswer, items) + sizeof(DnsAnswerItem ) * n))); | |||
13 | if (!a) | |||
14 | return NULL((void*)0); | |||
15 | ||||
16 | a->n_ref = 1; | |||
17 | a->n_allocated = n; | |||
18 | ||||
19 | return a; | |||
20 | } | |||
21 | ||||
22 | DnsAnswer *dns_answer_ref(DnsAnswer *a) { | |||
23 | if (!a) | |||
24 | return NULL((void*)0); | |||
25 | ||||
26 | assert(a->n_ref > 0)do { if ((__builtin_expect(!!(!(a->n_ref > 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a->n_ref > 0"), "../src/resolve/resolved-dns-answer.c" , 26, __PRETTY_FUNCTION__); } while (0); | |||
27 | a->n_ref++; | |||
28 | return a; | |||
29 | } | |||
30 | ||||
31 | static void dns_answer_flush(DnsAnswer *a) { | |||
32 | DnsResourceRecord *rr; | |||
33 | ||||
34 | if (!a) | |||
35 | return; | |||
36 | ||||
37 | DNS_ANSWER_FOREACH(rr, a)for (size_t __unique_prefix_i54 = ({ (rr) = ((a) && ( a)->n_rrs > 0) ? (a)->items[0].rr : ((void*)0); 0; } ); (a) && (__unique_prefix_i54 < (a)->n_rrs); __unique_prefix_i54 ++, (rr) = (__unique_prefix_i54 < (a)->n_rrs ? (a)-> items[__unique_prefix_i54].rr : ((void*)0))) | |||
38 | dns_resource_record_unref(rr); | |||
39 | ||||
40 | a->n_rrs = 0; | |||
41 | } | |||
42 | ||||
43 | DnsAnswer *dns_answer_unref(DnsAnswer *a) { | |||
44 | if (!a) | |||
45 | return NULL((void*)0); | |||
46 | ||||
47 | assert(a->n_ref > 0)do { if ((__builtin_expect(!!(!(a->n_ref > 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a->n_ref > 0"), "../src/resolve/resolved-dns-answer.c" , 47, __PRETTY_FUNCTION__); } while (0); | |||
48 | ||||
49 | if (a->n_ref == 1) { | |||
50 | dns_answer_flush(a); | |||
51 | free(a); | |||
52 | } else | |||
53 | a->n_ref--; | |||
54 | ||||
55 | return NULL((void*)0); | |||
56 | } | |||
57 | ||||
58 | static int dns_answer_add_raw(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags) { | |||
59 | assert(rr)do { if ((__builtin_expect(!!(!(rr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rr"), "../src/resolve/resolved-dns-answer.c" , 59, __PRETTY_FUNCTION__); } while (0); | |||
60 | ||||
61 | if (!a) | |||
62 | return -ENOSPC28; | |||
63 | ||||
64 | if (a->n_rrs >= a->n_allocated) | |||
65 | return -ENOSPC28; | |||
66 | ||||
67 | a->items[a->n_rrs++] = (DnsAnswerItem) { | |||
68 | .rr = dns_resource_record_ref(rr), | |||
69 | .ifindex = ifindex, | |||
70 | .flags = flags, | |||
71 | }; | |||
72 | ||||
73 | return 1; | |||
74 | } | |||
75 | ||||
76 | static int dns_answer_add_raw_all(DnsAnswer *a, DnsAnswer *source) { | |||
77 | DnsResourceRecord *rr; | |||
78 | DnsAnswerFlags flags; | |||
79 | int ifindex, r; | |||
80 | ||||
81 | DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, source)for (size_t __unique_prefix_i55 = ({ (rr) = ((source) && (source)->n_rrs > 0) ? (source)->items[0].rr : ((void *)0); (ifindex) = ((source) && (source)->n_rrs > 0) ? (source)->items[0].ifindex : 0; (flags) = ((source) && (source)->n_rrs > 0) ? (source)->items[0].flags : 0 ; 0; }); (source) && (__unique_prefix_i55 < (source )->n_rrs); __unique_prefix_i55++, (rr) = ((__unique_prefix_i55 < (source)->n_rrs) ? (source)->items[__unique_prefix_i55 ].rr : ((void*)0)), (ifindex) = ((__unique_prefix_i55 < (source )->n_rrs) ? (source)->items[__unique_prefix_i55].ifindex : 0), (flags) = ((__unique_prefix_i55 < (source)->n_rrs ) ? (source)->items[__unique_prefix_i55].flags : 0)) { | |||
82 | r = dns_answer_add_raw(a, rr, ifindex, flags); | |||
83 | if (r < 0) | |||
84 | return r; | |||
85 | } | |||
86 | ||||
87 | return 0; | |||
88 | } | |||
89 | ||||
90 | int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags) { | |||
91 | size_t i; | |||
92 | int r; | |||
93 | ||||
94 | assert(rr)do { if ((__builtin_expect(!!(!(rr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rr"), "../src/resolve/resolved-dns-answer.c" , 94, __PRETTY_FUNCTION__); } while (0); | |||
95 | ||||
96 | if (!a) | |||
97 | return -ENOSPC28; | |||
98 | if (a->n_ref > 1) | |||
99 | return -EBUSY16; | |||
100 | ||||
101 | for (i = 0; i < a->n_rrs; i++) { | |||
102 | if (a->items[i].ifindex != ifindex) | |||
103 | continue; | |||
104 | ||||
105 | r = dns_resource_record_equal(a->items[i].rr, rr); | |||
106 | if (r < 0) | |||
107 | return r; | |||
108 | if (r > 0) { | |||
109 | /* Don't mix contradicting TTLs (see below) */ | |||
110 | if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0)) | |||
111 | return -EINVAL22; | |||
112 | ||||
113 | /* Entry already exists, keep the entry with | |||
114 | * the higher RR. */ | |||
115 | if (rr->ttl > a->items[i].rr->ttl) { | |||
116 | dns_resource_record_ref(rr); | |||
117 | dns_resource_record_unref(a->items[i].rr); | |||
118 | a->items[i].rr = rr; | |||
119 | } | |||
120 | ||||
121 | a->items[i].flags |= flags; | |||
122 | return 0; | |||
123 | } | |||
124 | ||||
125 | r = dns_resource_key_equal(a->items[i].rr->key, rr->key); | |||
126 | if (r < 0) | |||
127 | return r; | |||
128 | if (r > 0) { | |||
129 | /* There's already an RR of the same RRset in | |||
130 | * place! Let's see if the TTLs more or less | |||
131 | * match. We don't really care if they match | |||
132 | * precisely, but we do care whether one is 0 | |||
133 | * and the other is not. See RFC 2181, Section | |||
134 | * 5.2. */ | |||
135 | ||||
136 | if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0)) | |||
137 | return -EINVAL22; | |||
138 | } | |||
139 | } | |||
140 | ||||
141 | return dns_answer_add_raw(a, rr, ifindex, flags); | |||
142 | } | |||
143 | ||||
144 | static int dns_answer_add_all(DnsAnswer *a, DnsAnswer *b) { | |||
145 | DnsResourceRecord *rr; | |||
146 | DnsAnswerFlags flags; | |||
147 | int ifindex, r; | |||
148 | ||||
149 | DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, b)for (size_t __unique_prefix_i56 = ({ (rr) = ((b) && ( b)->n_rrs > 0) ? (b)->items[0].rr : ((void*)0); (ifindex ) = ((b) && (b)->n_rrs > 0) ? (b)->items[0]. ifindex : 0; (flags) = ((b) && (b)->n_rrs > 0) ? (b)->items[0].flags : 0; 0; }); (b) && (__unique_prefix_i56 < (b)->n_rrs); __unique_prefix_i56++, (rr) = ((__unique_prefix_i56 < (b)->n_rrs) ? (b)->items[__unique_prefix_i56].rr : ((void*)0)), (ifindex) = ((__unique_prefix_i56 < (b)-> n_rrs) ? (b)->items[__unique_prefix_i56].ifindex : 0), (flags ) = ((__unique_prefix_i56 < (b)->n_rrs) ? (b)->items [__unique_prefix_i56].flags : 0)) { | |||
150 | r = dns_answer_add(a, rr, ifindex, flags); | |||
151 | if (r < 0) | |||
152 | return r; | |||
153 | } | |||
154 | ||||
155 | return 0; | |||
156 | } | |||
157 | ||||
158 | int dns_answer_add_extend(DnsAnswer **a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags) { | |||
159 | int r; | |||
160 | ||||
161 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/resolve/resolved-dns-answer.c" , 161, __PRETTY_FUNCTION__); } while (0); | |||
162 | assert(rr)do { if ((__builtin_expect(!!(!(rr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rr"), "../src/resolve/resolved-dns-answer.c" , 162, __PRETTY_FUNCTION__); } while (0); | |||
163 | ||||
164 | r = dns_answer_reserve_or_clone(a, 1); | |||
165 | if (r < 0) | |||
166 | return r; | |||
167 | ||||
168 | return dns_answer_add(*a, rr, ifindex, flags); | |||
169 | } | |||
170 | ||||
171 | int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl, int ifindex) { | |||
172 | _cleanup_(dns_resource_record_unrefp)__attribute__((cleanup(dns_resource_record_unrefp))) DnsResourceRecord *soa = NULL((void*)0); | |||
173 | ||||
174 | soa = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_SOA, name); | |||
175 | if (!soa) | |||
176 | return -ENOMEM12; | |||
177 | ||||
178 | soa->ttl = ttl; | |||
179 | ||||
180 | soa->soa.mname = strdup(name); | |||
181 | if (!soa->soa.mname) | |||
182 | return -ENOMEM12; | |||
183 | ||||
184 | soa->soa.rname = strappend("root.", name); | |||
185 | if (!soa->soa.rname) | |||
186 | return -ENOMEM12; | |||
187 | ||||
188 | soa->soa.serial = 1; | |||
189 | soa->soa.refresh = 1; | |||
190 | soa->soa.retry = 1; | |||
191 | soa->soa.expire = 1; | |||
192 | soa->soa.minimum = ttl; | |||
193 | ||||
194 | return dns_answer_add(a, soa, ifindex, DNS_ANSWER_AUTHENTICATED); | |||
195 | } | |||
196 | ||||
197 | int dns_answer_match_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags *ret_flags) { | |||
198 | DnsAnswerFlags flags = 0, i_flags; | |||
199 | DnsResourceRecord *i; | |||
200 | bool_Bool found = false0; | |||
201 | int r; | |||
202 | ||||
203 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/resolve/resolved-dns-answer.c" , 203, __PRETTY_FUNCTION__); } while (0); | |||
204 | ||||
205 | DNS_ANSWER_FOREACH_FLAGS(i, i_flags, a)for (size_t __unique_prefix_i57 = ({ (i) = ((a) && (a )->n_rrs > 0) ? (a)->items[0].rr : ((void*)0); (i_flags ) = ((a) && (a)->n_rrs > 0) ? (a)->items[0]. flags : 0; 0; }); (a) && (__unique_prefix_i57 < (a )->n_rrs); __unique_prefix_i57++, (i) = ((__unique_prefix_i57 < (a)->n_rrs) ? (a)->items[__unique_prefix_i57].rr : ((void*)0)), (i_flags) = ((__unique_prefix_i57 < (a)-> n_rrs) ? (a)->items[__unique_prefix_i57].flags : 0)) { | |||
206 | r = dns_resource_key_match_rr(key, i, NULL((void*)0)); | |||
207 | if (r < 0) | |||
208 | return r; | |||
209 | if (r == 0) | |||
210 | continue; | |||
211 | ||||
212 | if (!ret_flags) | |||
213 | return 1; | |||
214 | ||||
215 | if (found) | |||
216 | flags &= i_flags; | |||
217 | else { | |||
218 | flags = i_flags; | |||
219 | found = true1; | |||
220 | } | |||
221 | } | |||
222 | ||||
223 | if (ret_flags) | |||
224 | *ret_flags = flags; | |||
225 | ||||
226 | return found; | |||
227 | } | |||
228 | ||||
229 | int dns_answer_contains_rr(DnsAnswer *a, DnsResourceRecord *rr, DnsAnswerFlags *ret_flags) { | |||
230 | DnsAnswerFlags flags = 0, i_flags; | |||
231 | DnsResourceRecord *i; | |||
232 | bool_Bool found = false0; | |||
233 | int r; | |||
234 | ||||
235 | assert(rr)do { if ((__builtin_expect(!!(!(rr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rr"), "../src/resolve/resolved-dns-answer.c" , 235, __PRETTY_FUNCTION__); } while (0); | |||
236 | ||||
237 | DNS_ANSWER_FOREACH_FLAGS(i, i_flags, a)for (size_t __unique_prefix_i58 = ({ (i) = ((a) && (a )->n_rrs > 0) ? (a)->items[0].rr : ((void*)0); (i_flags ) = ((a) && (a)->n_rrs > 0) ? (a)->items[0]. flags : 0; 0; }); (a) && (__unique_prefix_i58 < (a )->n_rrs); __unique_prefix_i58++, (i) = ((__unique_prefix_i58 < (a)->n_rrs) ? (a)->items[__unique_prefix_i58].rr : ((void*)0)), (i_flags) = ((__unique_prefix_i58 < (a)-> n_rrs) ? (a)->items[__unique_prefix_i58].flags : 0)) { | |||
238 | r = dns_resource_record_equal(i, rr); | |||
239 | if (r < 0) | |||
240 | return r; | |||
241 | if (r == 0) | |||
242 | continue; | |||
243 | ||||
244 | if (!ret_flags) | |||
245 | return 1; | |||
246 | ||||
247 | if (found) | |||
248 | flags &= i_flags; | |||
249 | else { | |||
250 | flags = i_flags; | |||
251 | found = true1; | |||
252 | } | |||
253 | } | |||
254 | ||||
255 | if (ret_flags) | |||
256 | *ret_flags = flags; | |||
257 | ||||
258 | return found; | |||
259 | } | |||
260 | ||||
261 | int dns_answer_contains_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags *ret_flags) { | |||
262 | DnsAnswerFlags flags = 0, i_flags; | |||
263 | DnsResourceRecord *i; | |||
264 | bool_Bool found = false0; | |||
265 | int r; | |||
266 | ||||
267 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/resolve/resolved-dns-answer.c" , 267, __PRETTY_FUNCTION__); } while (0); | |||
268 | ||||
269 | DNS_ANSWER_FOREACH_FLAGS(i, i_flags, a)for (size_t __unique_prefix_i59 = ({ (i) = ((a) && (a )->n_rrs > 0) ? (a)->items[0].rr : ((void*)0); (i_flags ) = ((a) && (a)->n_rrs > 0) ? (a)->items[0]. flags : 0; 0; }); (a) && (__unique_prefix_i59 < (a )->n_rrs); __unique_prefix_i59++, (i) = ((__unique_prefix_i59 < (a)->n_rrs) ? (a)->items[__unique_prefix_i59].rr : ((void*)0)), (i_flags) = ((__unique_prefix_i59 < (a)-> n_rrs) ? (a)->items[__unique_prefix_i59].flags : 0)) { | |||
270 | r = dns_resource_key_equal(i->key, key); | |||
271 | if (r < 0) | |||
272 | return r; | |||
273 | if (r == 0) | |||
274 | continue; | |||
275 | ||||
276 | if (!ret_flags) | |||
277 | return true1; | |||
278 | ||||
279 | if (found) | |||
280 | flags &= i_flags; | |||
281 | else { | |||
282 | flags = i_flags; | |||
283 | found = true1; | |||
284 | } | |||
285 | } | |||
286 | ||||
287 | if (ret_flags) | |||
288 | *ret_flags = flags; | |||
289 | ||||
290 | return found; | |||
291 | } | |||
292 | ||||
293 | int dns_answer_contains_nsec_or_nsec3(DnsAnswer *a) { | |||
294 | DnsResourceRecord *i; | |||
295 | ||||
296 | DNS_ANSWER_FOREACH(i, a)for (size_t __unique_prefix_i60 = ({ (i) = ((a) && (a )->n_rrs > 0) ? (a)->items[0].rr : ((void*)0); 0; }) ; (a) && (__unique_prefix_i60 < (a)->n_rrs); __unique_prefix_i60 ++, (i) = (__unique_prefix_i60 < (a)->n_rrs ? (a)->items [__unique_prefix_i60].rr : ((void*)0))) { | |||
297 | if (IN_SET(i->key->type, DNS_TYPE_NSEC, DNS_TYPE_NSEC3)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){DNS_TYPE_NSEC, DNS_TYPE_NSEC3})/sizeof(int )]; switch(i->key->type) { case DNS_TYPE_NSEC: case DNS_TYPE_NSEC3 : _found = 1; break; default: break; } _found; })) | |||
298 | return true1; | |||
299 | } | |||
300 | ||||
301 | return false0; | |||
302 | } | |||
303 | ||||
304 | int dns_answer_contains_zone_nsec3(DnsAnswer *answer, const char *zone) { | |||
305 | DnsResourceRecord *rr; | |||
306 | int r; | |||
307 | ||||
308 | /* Checks whether the specified answer contains at least one NSEC3 RR in the specified zone */ | |||
309 | ||||
310 | DNS_ANSWER_FOREACH(rr, answer)for (size_t __unique_prefix_i61 = ({ (rr) = ((answer) && (answer)->n_rrs > 0) ? (answer)->items[0].rr : ((void *)0); 0; }); (answer) && (__unique_prefix_i61 < (answer )->n_rrs); __unique_prefix_i61++, (rr) = (__unique_prefix_i61 < (answer)->n_rrs ? (answer)->items[__unique_prefix_i61 ].rr : ((void*)0))) { | |||
311 | const char *p; | |||
312 | ||||
313 | if (rr->key->type != DNS_TYPE_NSEC3) | |||
314 | continue; | |||
315 | ||||
316 | p = dns_resource_key_name(rr->key); | |||
317 | r = dns_name_parent(&p); | |||
318 | if (r < 0) | |||
319 | return r; | |||
320 | if (r == 0) | |||
321 | continue; | |||
322 | ||||
323 | r = dns_name_equal(p, zone); | |||
324 | if (r != 0) | |||
325 | return r; | |||
326 | } | |||
327 | ||||
328 | return false0; | |||
329 | } | |||
330 | ||||
331 | int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags) { | |||
332 | DnsResourceRecord *rr, *soa = NULL((void*)0); | |||
333 | DnsAnswerFlags rr_flags, soa_flags = 0; | |||
334 | int r; | |||
335 | ||||
336 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/resolve/resolved-dns-answer.c" , 336, __PRETTY_FUNCTION__); } while (0); | |||
337 | ||||
338 | /* For a SOA record we can never find a matching SOA record */ | |||
339 | if (key->type == DNS_TYPE_SOA) | |||
340 | return 0; | |||
341 | ||||
342 | DNS_ANSWER_FOREACH_FLAGS(rr, rr_flags, a)for (size_t __unique_prefix_i62 = ({ (rr) = ((a) && ( a)->n_rrs > 0) ? (a)->items[0].rr : ((void*)0); (rr_flags ) = ((a) && (a)->n_rrs > 0) ? (a)->items[0]. flags : 0; 0; }); (a) && (__unique_prefix_i62 < (a )->n_rrs); __unique_prefix_i62++, (rr) = ((__unique_prefix_i62 < (a)->n_rrs) ? (a)->items[__unique_prefix_i62].rr : ((void*)0)), (rr_flags) = ((__unique_prefix_i62 < (a)-> n_rrs) ? (a)->items[__unique_prefix_i62].flags : 0)) { | |||
343 | r = dns_resource_key_match_soa(key, rr->key); | |||
344 | if (r < 0) | |||
345 | return r; | |||
346 | if (r > 0) { | |||
347 | ||||
348 | if (soa) { | |||
349 | r = dns_name_endswith(dns_resource_key_name(rr->key), dns_resource_key_name(soa->key)); | |||
350 | if (r < 0) | |||
351 | return r; | |||
352 | if (r > 0) | |||
353 | continue; | |||
354 | } | |||
355 | ||||
356 | soa = rr; | |||
357 | soa_flags = rr_flags; | |||
358 | } | |||
359 | } | |||
360 | ||||
361 | if (!soa) | |||
362 | return 0; | |||
363 | ||||
364 | if (ret) | |||
365 | *ret = soa; | |||
366 | if (flags) | |||
367 | *flags = soa_flags; | |||
368 | ||||
369 | return 1; | |||
370 | } | |||
371 | ||||
372 | int dns_answer_find_cname_or_dname(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags) { | |||
373 | DnsResourceRecord *rr; | |||
374 | DnsAnswerFlags rr_flags; | |||
375 | int r; | |||
376 | ||||
377 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/resolve/resolved-dns-answer.c" , 377, __PRETTY_FUNCTION__); } while (0); | |||
378 | ||||
379 | /* For a {C,D}NAME record we can never find a matching {C,D}NAME record */ | |||
380 | if (!dns_type_may_redirect(key->type)) | |||
381 | return 0; | |||
382 | ||||
383 | DNS_ANSWER_FOREACH_FLAGS(rr, rr_flags, a)for (size_t __unique_prefix_i63 = ({ (rr) = ((a) && ( a)->n_rrs > 0) ? (a)->items[0].rr : ((void*)0); (rr_flags ) = ((a) && (a)->n_rrs > 0) ? (a)->items[0]. flags : 0; 0; }); (a) && (__unique_prefix_i63 < (a )->n_rrs); __unique_prefix_i63++, (rr) = ((__unique_prefix_i63 < (a)->n_rrs) ? (a)->items[__unique_prefix_i63].rr : ((void*)0)), (rr_flags) = ((__unique_prefix_i63 < (a)-> n_rrs) ? (a)->items[__unique_prefix_i63].flags : 0)) { | |||
384 | r = dns_resource_key_match_cname_or_dname(key, rr->key, NULL((void*)0)); | |||
385 | if (r < 0) | |||
386 | return r; | |||
387 | if (r > 0) { | |||
388 | if (ret) | |||
389 | *ret = rr; | |||
390 | if (flags) | |||
391 | *flags = rr_flags; | |||
392 | return 1; | |||
393 | } | |||
394 | } | |||
395 | ||||
396 | return 0; | |||
397 | } | |||
398 | ||||
399 | int dns_answer_merge(DnsAnswer *a, DnsAnswer *b, DnsAnswer **ret) { | |||
400 | _cleanup_(dns_answer_unrefp)__attribute__((cleanup(dns_answer_unrefp))) DnsAnswer *k = NULL((void*)0); | |||
401 | int r; | |||
402 | ||||
403 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/resolve/resolved-dns-answer.c" , 403, __PRETTY_FUNCTION__); } while (0); | |||
404 | ||||
405 | if (dns_answer_size(a) <= 0) { | |||
406 | *ret = dns_answer_ref(b); | |||
407 | return 0; | |||
408 | } | |||
409 | ||||
410 | if (dns_answer_size(b) <= 0) { | |||
411 | *ret = dns_answer_ref(a); | |||
412 | return 0; | |||
413 | } | |||
414 | ||||
415 | k = dns_answer_new(a->n_rrs + b->n_rrs); | |||
416 | if (!k) | |||
417 | return -ENOMEM12; | |||
418 | ||||
419 | r = dns_answer_add_raw_all(k, a); | |||
420 | if (r < 0) | |||
421 | return r; | |||
422 | ||||
423 | r = dns_answer_add_all(k, b); | |||
424 | if (r < 0) | |||
425 | return r; | |||
426 | ||||
427 | *ret = TAKE_PTR(k)({ typeof(k) _ptr_ = (k); (k) = ((void*)0); _ptr_; }); | |||
428 | ||||
429 | return 0; | |||
430 | } | |||
431 | ||||
432 | int dns_answer_extend(DnsAnswer **a, DnsAnswer *b) { | |||
433 | DnsAnswer *merged; | |||
434 | int r; | |||
435 | ||||
436 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/resolve/resolved-dns-answer.c" , 436, __PRETTY_FUNCTION__); } while (0); | |||
437 | ||||
438 | r = dns_answer_merge(*a, b, &merged); | |||
439 | if (r < 0) | |||
440 | return r; | |||
441 | ||||
442 | dns_answer_unref(*a); | |||
443 | *a = merged; | |||
444 | ||||
445 | return 0; | |||
446 | } | |||
447 | ||||
448 | int dns_answer_remove_by_key(DnsAnswer **a, const DnsResourceKey *key) { | |||
449 | bool_Bool found = false0, other = false0; | |||
450 | DnsResourceRecord *rr; | |||
451 | size_t i; | |||
452 | int r; | |||
453 | ||||
454 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/resolve/resolved-dns-answer.c" , 454, __PRETTY_FUNCTION__); } while (0); | |||
455 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/resolve/resolved-dns-answer.c" , 455, __PRETTY_FUNCTION__); } while (0); | |||
456 | ||||
457 | /* Remove all entries matching the specified key from *a */ | |||
458 | ||||
459 | DNS_ANSWER_FOREACH(rr, *a)for (size_t __unique_prefix_i64 = ({ (rr) = ((*a) && ( *a)->n_rrs > 0) ? (*a)->items[0].rr : ((void*)0); 0; }); (*a) && (__unique_prefix_i64 < (*a)->n_rrs ); __unique_prefix_i64++, (rr) = (__unique_prefix_i64 < (* a)->n_rrs ? (*a)->items[__unique_prefix_i64].rr : ((void *)0))) { | |||
460 | r = dns_resource_key_equal(rr->key, key); | |||
461 | if (r < 0) | |||
462 | return r; | |||
463 | if (r > 0) | |||
464 | found = true1; | |||
465 | else | |||
466 | other = true1; | |||
467 | ||||
468 | if (found && other) | |||
469 | break; | |||
470 | } | |||
471 | ||||
472 | if (!found) | |||
473 | return 0; | |||
474 | ||||
475 | if (!other) { | |||
476 | *a = dns_answer_unref(*a); /* Return NULL for the empty answer */ | |||
477 | return 1; | |||
478 | } | |||
479 | ||||
480 | if ((*a)->n_ref > 1) { | |||
481 | _cleanup_(dns_answer_unrefp)__attribute__((cleanup(dns_answer_unrefp))) DnsAnswer *copy = NULL((void*)0); | |||
482 | DnsAnswerFlags flags; | |||
483 | int ifindex; | |||
484 | ||||
485 | copy = dns_answer_new((*a)->n_rrs); | |||
486 | if (!copy) | |||
487 | return -ENOMEM12; | |||
488 | ||||
489 | DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, *a)for (size_t __unique_prefix_i65 = ({ (rr) = ((*a) && ( *a)->n_rrs > 0) ? (*a)->items[0].rr : ((void*)0); (ifindex ) = ((*a) && (*a)->n_rrs > 0) ? (*a)->items[ 0].ifindex : 0; (flags) = ((*a) && (*a)->n_rrs > 0) ? (*a)->items[0].flags : 0; 0; }); (*a) && (__unique_prefix_i65 < (*a)->n_rrs); __unique_prefix_i65++, (rr) = ((__unique_prefix_i65 < (*a)->n_rrs) ? (*a)->items[__unique_prefix_i65].rr : ((void*)0)), (ifindex) = ((__unique_prefix_i65 < (*a)-> n_rrs) ? (*a)->items[__unique_prefix_i65].ifindex : 0), (flags ) = ((__unique_prefix_i65 < (*a)->n_rrs) ? (*a)->items [__unique_prefix_i65].flags : 0)) { | |||
490 | r = dns_resource_key_equal(rr->key, key); | |||
491 | if (r < 0) | |||
492 | return r; | |||
493 | if (r > 0) | |||
494 | continue; | |||
495 | ||||
496 | r = dns_answer_add_raw(copy, rr, ifindex, flags); | |||
497 | if (r < 0) | |||
498 | return r; | |||
499 | } | |||
500 | ||||
501 | dns_answer_unref(*a); | |||
502 | *a = TAKE_PTR(copy)({ typeof(copy) _ptr_ = (copy); (copy) = ((void*)0); _ptr_; } ); | |||
503 | ||||
504 | return 1; | |||
505 | } | |||
506 | ||||
507 | /* Only a single reference, edit in-place */ | |||
508 | ||||
509 | i = 0; | |||
510 | for (;;) { | |||
511 | if (i >= (*a)->n_rrs) | |||
512 | break; | |||
513 | ||||
514 | r = dns_resource_key_equal((*a)->items[i].rr->key, key); | |||
515 | if (r < 0) | |||
516 | return r; | |||
517 | if (r > 0) { | |||
518 | /* Kill this entry */ | |||
519 | ||||
520 | dns_resource_record_unref((*a)->items[i].rr); | |||
521 | memmove((*a)->items + i, (*a)->items + i + 1, sizeof(DnsAnswerItem) * ((*a)->n_rrs - i - 1)); | |||
522 | (*a)->n_rrs--; | |||
523 | continue; | |||
524 | ||||
525 | } else | |||
526 | /* Keep this entry */ | |||
527 | i++; | |||
528 | } | |||
529 | ||||
530 | return 1; | |||
531 | } | |||
532 | ||||
533 | int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rm) { | |||
534 | bool_Bool found = false0, other = false0; | |||
535 | DnsResourceRecord *rr; | |||
536 | size_t i; | |||
537 | int r; | |||
538 | ||||
539 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/resolve/resolved-dns-answer.c" , 539, __PRETTY_FUNCTION__); } while (0); | |||
540 | assert(rm)do { if ((__builtin_expect(!!(!(rm)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rm"), "../src/resolve/resolved-dns-answer.c" , 540, __PRETTY_FUNCTION__); } while (0); | |||
541 | ||||
542 | /* Remove all entries matching the specified RR from *a */ | |||
543 | ||||
544 | DNS_ANSWER_FOREACH(rr, *a)for (size_t __unique_prefix_i66 = ({ (rr) = ((*a) && ( *a)->n_rrs > 0) ? (*a)->items[0].rr : ((void*)0); 0; }); (*a) && (__unique_prefix_i66 < (*a)->n_rrs ); __unique_prefix_i66++, (rr) = (__unique_prefix_i66 < (* a)->n_rrs ? (*a)->items[__unique_prefix_i66].rr : ((void *)0))) { | |||
545 | r = dns_resource_record_equal(rr, rm); | |||
546 | if (r < 0) | |||
547 | return r; | |||
548 | if (r > 0) | |||
549 | found = true1; | |||
550 | else | |||
551 | other = true1; | |||
552 | ||||
553 | if (found && other) | |||
554 | break; | |||
555 | } | |||
556 | ||||
557 | if (!found) | |||
558 | return 0; | |||
559 | ||||
560 | if (!other) { | |||
561 | *a = dns_answer_unref(*a); /* Return NULL for the empty answer */ | |||
562 | return 1; | |||
563 | } | |||
564 | ||||
565 | if ((*a)->n_ref > 1) { | |||
566 | _cleanup_(dns_answer_unrefp)__attribute__((cleanup(dns_answer_unrefp))) DnsAnswer *copy = NULL((void*)0); | |||
567 | DnsAnswerFlags flags; | |||
568 | int ifindex; | |||
569 | ||||
570 | copy = dns_answer_new((*a)->n_rrs); | |||
571 | if (!copy) | |||
572 | return -ENOMEM12; | |||
573 | ||||
574 | DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, *a)for (size_t __unique_prefix_i67 = ({ (rr) = ((*a) && ( *a)->n_rrs > 0) ? (*a)->items[0].rr : ((void*)0); (ifindex ) = ((*a) && (*a)->n_rrs > 0) ? (*a)->items[ 0].ifindex : 0; (flags) = ((*a) && (*a)->n_rrs > 0) ? (*a)->items[0].flags : 0; 0; }); (*a) && (__unique_prefix_i67 < (*a)->n_rrs); __unique_prefix_i67++, (rr) = ((__unique_prefix_i67 < (*a)->n_rrs) ? (*a)->items[__unique_prefix_i67].rr : ((void*)0)), (ifindex) = ((__unique_prefix_i67 < (*a)-> n_rrs) ? (*a)->items[__unique_prefix_i67].ifindex : 0), (flags ) = ((__unique_prefix_i67 < (*a)->n_rrs) ? (*a)->items [__unique_prefix_i67].flags : 0)) { | |||
575 | r = dns_resource_record_equal(rr, rm); | |||
576 | if (r < 0) | |||
577 | return r; | |||
578 | if (r > 0) | |||
579 | continue; | |||
580 | ||||
581 | r = dns_answer_add_raw(copy, rr, ifindex, flags); | |||
582 | if (r < 0) | |||
583 | return r; | |||
584 | } | |||
585 | ||||
586 | dns_answer_unref(*a); | |||
587 | *a = TAKE_PTR(copy)({ typeof(copy) _ptr_ = (copy); (copy) = ((void*)0); _ptr_; } ); | |||
588 | ||||
589 | return 1; | |||
590 | } | |||
591 | ||||
592 | /* Only a single reference, edit in-place */ | |||
593 | ||||
594 | i = 0; | |||
595 | for (;;) { | |||
596 | if (i >= (*a)->n_rrs) | |||
597 | break; | |||
598 | ||||
599 | r = dns_resource_record_equal((*a)->items[i].rr, rm); | |||
600 | if (r < 0) | |||
601 | return r; | |||
602 | if (r > 0) { | |||
603 | /* Kill this entry */ | |||
604 | ||||
605 | dns_resource_record_unref((*a)->items[i].rr); | |||
606 | memmove((*a)->items + i, (*a)->items + i + 1, sizeof(DnsAnswerItem) * ((*a)->n_rrs - i - 1)); | |||
607 | (*a)->n_rrs--; | |||
608 | continue; | |||
609 | ||||
610 | } else | |||
611 | /* Keep this entry */ | |||
612 | i++; | |||
613 | } | |||
614 | ||||
615 | return 1; | |||
616 | } | |||
617 | ||||
618 | int dns_answer_copy_by_key(DnsAnswer **a, DnsAnswer *source, const DnsResourceKey *key, DnsAnswerFlags or_flags) { | |||
619 | DnsResourceRecord *rr_source; | |||
620 | int ifindex_source, r; | |||
621 | DnsAnswerFlags flags_source; | |||
622 | ||||
623 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/resolve/resolved-dns-answer.c" , 623, __PRETTY_FUNCTION__); } while (0); | |||
624 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/resolve/resolved-dns-answer.c" , 624, __PRETTY_FUNCTION__); } while (0); | |||
625 | ||||
626 | /* Copy all RRs matching the specified key from source into *a */ | |||
627 | ||||
628 | DNS_ANSWER_FOREACH_FULL(rr_source, ifindex_source, flags_source, source)for (size_t __unique_prefix_i68 = ({ (rr_source) = ((source) && (source)->n_rrs > 0) ? (source)->items[0].rr : ((void *)0); (ifindex_source) = ((source) && (source)->n_rrs > 0) ? (source)->items[0].ifindex : 0; (flags_source) = ((source) && (source)->n_rrs > 0) ? (source)-> items[0].flags : 0; 0; }); (source) && (__unique_prefix_i68 < (source)->n_rrs); __unique_prefix_i68++, (rr_source) = ((__unique_prefix_i68 < (source)->n_rrs) ? (source)-> items[__unique_prefix_i68].rr : ((void*)0)), (ifindex_source) = ((__unique_prefix_i68 < (source)->n_rrs) ? (source)-> items[__unique_prefix_i68].ifindex : 0), (flags_source) = ((__unique_prefix_i68 < (source)->n_rrs) ? (source)->items[__unique_prefix_i68 ].flags : 0)) { | |||
629 | ||||
630 | r = dns_resource_key_equal(rr_source->key, key); | |||
631 | if (r < 0) | |||
632 | return r; | |||
633 | if (r == 0) | |||
634 | continue; | |||
635 | ||||
636 | /* Make space for at least one entry */ | |||
637 | r = dns_answer_reserve_or_clone(a, 1); | |||
638 | if (r < 0) | |||
639 | return r; | |||
640 | ||||
641 | r = dns_answer_add(*a, rr_source, ifindex_source, flags_source|or_flags); | |||
642 | if (r < 0) | |||
643 | return r; | |||
644 | } | |||
645 | ||||
646 | return 0; | |||
647 | } | |||
648 | ||||
649 | int dns_answer_move_by_key(DnsAnswer **to, DnsAnswer **from, const DnsResourceKey *key, DnsAnswerFlags or_flags) { | |||
650 | int r; | |||
651 | ||||
652 | assert(to)do { if ((__builtin_expect(!!(!(to)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("to"), "../src/resolve/resolved-dns-answer.c" , 652, __PRETTY_FUNCTION__); } while (0); | |||
| ||||
653 | assert(from)do { if ((__builtin_expect(!!(!(from)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("from"), "../src/resolve/resolved-dns-answer.c" , 653, __PRETTY_FUNCTION__); } while (0); | |||
654 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/resolve/resolved-dns-answer.c" , 654, __PRETTY_FUNCTION__); } while (0); | |||
655 | ||||
656 | r = dns_answer_copy_by_key(to, *from, key, or_flags); | |||
657 | if (r < 0) | |||
658 | return r; | |||
659 | ||||
660 | return dns_answer_remove_by_key(from, key); | |||
661 | } | |||
662 | ||||
663 | void dns_answer_order_by_scope(DnsAnswer *a, bool_Bool prefer_link_local) { | |||
664 | DnsAnswerItem *items; | |||
665 | size_t i, start, end; | |||
666 | ||||
667 | if (!a) | |||
668 | return; | |||
669 | ||||
670 | if (a->n_rrs <= 1) | |||
671 | return; | |||
672 | ||||
673 | start = 0; | |||
674 | end = a->n_rrs-1; | |||
675 | ||||
676 | /* RFC 4795, Section 2.6 suggests we should order entries | |||
677 | * depending on whether the sender is a link-local address. */ | |||
678 | ||||
679 | items = newa(DnsAnswerItem, a->n_rrs)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof (DnsAnswerItem), a->n_rrs))),0))) log_assert_failed_realm( LOG_REALM_SYSTEMD, ("!size_multiply_overflow(sizeof(DnsAnswerItem), a->n_rrs)" ), "../src/resolve/resolved-dns-answer.c", 679, __PRETTY_FUNCTION__ ); } while (0); (DnsAnswerItem*) __builtin_alloca (sizeof(DnsAnswerItem )*(a->n_rrs)); }); | |||
680 | for (i = 0; i < a->n_rrs; i++) { | |||
681 | ||||
682 | if (a->items[i].rr->key->class == DNS_CLASS_IN && | |||
683 | ((a->items[i].rr->key->type == DNS_TYPE_A && in_addr_is_link_local(AF_INET2, (union in_addr_union*) &a->items[i].rr->a.in_addr) != prefer_link_local) || | |||
684 | (a->items[i].rr->key->type == DNS_TYPE_AAAA && in_addr_is_link_local(AF_INET610, (union in_addr_union*) &a->items[i].rr->aaaa.in6_addr) != prefer_link_local))) | |||
685 | /* Order address records that are not preferred to the end of the array */ | |||
686 | items[end--] = a->items[i]; | |||
687 | else | |||
688 | /* Order all other records to the beginning of the array */ | |||
689 | items[start++] = a->items[i]; | |||
690 | } | |||
691 | ||||
692 | assert(start == end+1)do { if ((__builtin_expect(!!(!(start == end+1)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("start == end+1"), "../src/resolve/resolved-dns-answer.c" , 692, __PRETTY_FUNCTION__); } while (0); | |||
693 | memcpy(a->items, items, sizeof(DnsAnswerItem) * a->n_rrs); | |||
694 | } | |||
695 | ||||
696 | int dns_answer_reserve(DnsAnswer **a, size_t n_free) { | |||
697 | DnsAnswer *n; | |||
698 | ||||
699 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/resolve/resolved-dns-answer.c" , 699, __PRETTY_FUNCTION__); } while (0); | |||
700 | ||||
701 | if (n_free <= 0) | |||
702 | return 0; | |||
703 | ||||
704 | if (*a) { | |||
705 | size_t ns; | |||
706 | ||||
707 | if ((*a)->n_ref > 1) | |||
708 | return -EBUSY16; | |||
709 | ||||
710 | ns = (*a)->n_rrs + n_free; | |||
711 | ||||
712 | if ((*a)->n_allocated >= ns) | |||
713 | return 0; | |||
714 | ||||
715 | /* Allocate more than we need */ | |||
716 | ns *= 2; | |||
717 | ||||
718 | n = realloc(*a, offsetof(DnsAnswer, items)__builtin_offsetof(DnsAnswer, items) + sizeof(DnsAnswerItem) * ns); | |||
719 | if (!n) | |||
720 | return -ENOMEM12; | |||
721 | ||||
722 | n->n_allocated = ns; | |||
723 | } else { | |||
724 | n = dns_answer_new(n_free); | |||
725 | if (!n) | |||
726 | return -ENOMEM12; | |||
727 | } | |||
728 | ||||
729 | *a = n; | |||
730 | return 0; | |||
731 | } | |||
732 | ||||
733 | int dns_answer_reserve_or_clone(DnsAnswer **a, size_t n_free) { | |||
734 | _cleanup_(dns_answer_unrefp)__attribute__((cleanup(dns_answer_unrefp))) DnsAnswer *n = NULL((void*)0); | |||
735 | int r; | |||
736 | ||||
737 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/resolve/resolved-dns-answer.c" , 737, __PRETTY_FUNCTION__); } while (0); | |||
738 | ||||
739 | /* Tries to extend the DnsAnswer object. And if that's not | |||
740 | * possible, since we are not the sole owner, then allocate a | |||
741 | * new, appropriately sized one. Either way, after this call | |||
742 | * the object will only have a single reference, and has room | |||
743 | * for at least the specified number of RRs. */ | |||
744 | ||||
745 | r = dns_answer_reserve(a, n_free); | |||
746 | if (r != -EBUSY16) | |||
747 | return r; | |||
748 | ||||
749 | assert(*a)do { if ((__builtin_expect(!!(!(*a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("*a"), "../src/resolve/resolved-dns-answer.c" , 749, __PRETTY_FUNCTION__); } while (0); | |||
750 | ||||
751 | n = dns_answer_new(((*a)->n_rrs + n_free) * 2); | |||
752 | if (!n
| |||
753 | return -ENOMEM12; | |||
754 | ||||
755 | r = dns_answer_add_raw_all(n, *a); | |||
756 | if (r
| |||
757 | return r; | |||
| ||||
758 | ||||
759 | dns_answer_unref(*a); | |||
760 | *a = TAKE_PTR(n)({ typeof(n) _ptr_ = (n); (n) = ((void*)0); _ptr_; }); | |||
761 | ||||
762 | return 0; | |||
763 | } | |||
764 | ||||
765 | void dns_answer_dump(DnsAnswer *answer, FILE *f) { | |||
766 | DnsResourceRecord *rr; | |||
767 | DnsAnswerFlags flags; | |||
768 | int ifindex; | |||
769 | ||||
770 | if (!f) | |||
771 | f = stdoutstdout; | |||
772 | ||||
773 | DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, answer)for (size_t __unique_prefix_i69 = ({ (rr) = ((answer) && (answer)->n_rrs > 0) ? (answer)->items[0].rr : ((void *)0); (ifindex) = ((answer) && (answer)->n_rrs > 0) ? (answer)->items[0].ifindex : 0; (flags) = ((answer) && (answer)->n_rrs > 0) ? (answer)->items[0].flags : 0 ; 0; }); (answer) && (__unique_prefix_i69 < (answer )->n_rrs); __unique_prefix_i69++, (rr) = ((__unique_prefix_i69 < (answer)->n_rrs) ? (answer)->items[__unique_prefix_i69 ].rr : ((void*)0)), (ifindex) = ((__unique_prefix_i69 < (answer )->n_rrs) ? (answer)->items[__unique_prefix_i69].ifindex : 0), (flags) = ((__unique_prefix_i69 < (answer)->n_rrs ) ? (answer)->items[__unique_prefix_i69].flags : 0)) { | |||
774 | const char *t; | |||
775 | ||||
776 | fputc('\t', f); | |||
777 | ||||
778 | t = dns_resource_record_to_string(rr); | |||
779 | if (!t) { | |||
780 | log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-dns-answer.c" , 780, __func__); | |||
781 | continue; | |||
782 | } | |||
783 | ||||
784 | fputs(t, f); | |||
785 | ||||
786 | if (ifindex != 0 || flags & (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE|DNS_ANSWER_SHARED_OWNER)) | |||
787 | fputs("\t;", f); | |||
788 | ||||
789 | if (ifindex != 0) | |||
790 | printf(" ifindex=%i", ifindex); | |||
791 | if (flags & DNS_ANSWER_AUTHENTICATED) | |||
792 | fputs(" authenticated", f); | |||
793 | if (flags & DNS_ANSWER_CACHEABLE) | |||
794 | fputs(" cachable", f); | |||
795 | if (flags & DNS_ANSWER_SHARED_OWNER) | |||
796 | fputs(" shared-owner", f); | |||
797 | ||||
798 | fputc('\n', f); | |||
799 | } | |||
800 | } | |||
801 | ||||
802 | bool_Bool dns_answer_has_dname_for_cname(DnsAnswer *a, DnsResourceRecord *cname) { | |||
803 | DnsResourceRecord *rr; | |||
804 | int r; | |||
805 | ||||
806 | assert(cname)do { if ((__builtin_expect(!!(!(cname)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("cname"), "../src/resolve/resolved-dns-answer.c" , 806, __PRETTY_FUNCTION__); } while (0); | |||
807 | ||||
808 | /* Checks whether the answer contains a DNAME record that indicates that the specified CNAME record is | |||
809 | * synthesized from it */ | |||
810 | ||||
811 | if (cname->key->type != DNS_TYPE_CNAME) | |||
812 | return 0; | |||
813 | ||||
814 | DNS_ANSWER_FOREACH(rr, a)for (size_t __unique_prefix_i70 = ({ (rr) = ((a) && ( a)->n_rrs > 0) ? (a)->items[0].rr : ((void*)0); 0; } ); (a) && (__unique_prefix_i70 < (a)->n_rrs); __unique_prefix_i70 ++, (rr) = (__unique_prefix_i70 < (a)->n_rrs ? (a)-> items[__unique_prefix_i70].rr : ((void*)0))) { | |||
815 | _cleanup_free___attribute__((cleanup(freep))) char *n = NULL((void*)0); | |||
816 | ||||
817 | if (rr->key->type != DNS_TYPE_DNAME) | |||
818 | continue; | |||
819 | if (rr->key->class != cname->key->class) | |||
820 | continue; | |||
821 | ||||
822 | r = dns_name_change_suffix(cname->cname.name, rr->dname.name, dns_resource_key_name(rr->key), &n); | |||
823 | if (r < 0) | |||
824 | return r; | |||
825 | if (r == 0) | |||
826 | continue; | |||
827 | ||||
828 | r = dns_name_equal(n, dns_resource_key_name(cname->key)); | |||
829 | if (r < 0) | |||
830 | return r; | |||
831 | if (r > 0) | |||
832 | return 1; | |||
833 | ||||
834 | } | |||
835 | ||||
836 | return 0; | |||
837 | } |