Bug Summary

File:build-scan/../src/resolve/resolved-etc-hosts.c
Warning:line 166, column 16
Potential leak of memory pointed to by 'item'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name resolved-etc-hosts.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I systemd-resolved.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I /usr/include/p11-kit-1 -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/resolve/resolved-etc-hosts.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include "fd-util.h"
4#include "fileio.h"
5#include "hostname-util.h"
6#include "resolved-etc-hosts.h"
7#include "resolved-dns-synthesize.h"
8#include "string-util.h"
9#include "strv.h"
10#include "time-util.h"
11
12/* Recheck /etc/hosts at most once every 2s */
13#define ETC_HOSTS_RECHECK_USEC(2*((usec_t) 1000000ULL)) (2*USEC_PER_SEC((usec_t) 1000000ULL))
14
15typedef struct EtcHostsItem {
16 int family;
17 union in_addr_union address;
18
19 char **names;
20} EtcHostsItem;
21
22typedef struct EtcHostsItemByName {
23 char *name;
24
25 EtcHostsItem **items;
26 size_t n_items, n_allocated;
27} EtcHostsItemByName;
28
29void manager_etc_hosts_flush(Manager *m) {
30 EtcHostsItem *item;
31 EtcHostsItemByName *bn;
32
33 while ((item = set_steal_first(m->etc_hosts_by_address))) {
34 strv_free(item->names);
35 free(item);
36 }
37
38 while ((bn = hashmap_steal_first(m->etc_hosts_by_name))) {
39 free(bn->name);
40 free(bn->items);
41 free(bn);
42 }
43
44 m->etc_hosts_by_address = set_free(m->etc_hosts_by_address);
45 m->etc_hosts_by_name = hashmap_free(m->etc_hosts_by_name);
46
47 m->etc_hosts_mtime = USEC_INFINITY((usec_t) -1);
48}
49
50static void etc_hosts_item_hash_func(const void *p, struct siphash *state) {
51 const EtcHostsItem *item = p;
52
53 siphash24_compress(&item->family, sizeof(item->family), state);
54
55 if (item->family == AF_INET2)
56 siphash24_compress(&item->address.in, sizeof(item->address.in), state);
57 else if (item->family == AF_INET610)
58 siphash24_compress(&item->address.in6, sizeof(item->address.in6), state);
59}
60
61static int etc_hosts_item_compare_func(const void *a, const void *b) {
62 const EtcHostsItem *x = a, *y = b;
63
64 if (x->family != y->family)
65 return x->family - y->family;
66
67 if (x->family == AF_INET2)
68 return memcmp(&x->address.in.s_addr, &y->address.in.s_addr, sizeof(struct in_addr));
69
70 if (x->family == AF_INET610)
71 return memcmp(&x->address.in6.s6_addr__in6_u.__u6_addr8, &y->address.in6.s6_addr__in6_u.__u6_addr8, sizeof(struct in6_addr));
72
73 return trivial_compare_func(a, b);
74}
75
76static const struct hash_ops etc_hosts_item_ops = {
77 .hash = etc_hosts_item_hash_func,
78 .compare = etc_hosts_item_compare_func,
79};
80
81static int add_item(Manager *m, int family, const union in_addr_union *address, char **names) {
82
83 EtcHostsItem key = {
84 .family = family,
85 .address = *address,
86 };
87 EtcHostsItem *item;
88 char **n;
89 int r;
90
91 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolved-etc-hosts.c"
, 91, __PRETTY_FUNCTION__); } while (0)
;
56
Taking false branch
57
Loop condition is false. Exiting loop
92 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/resolve/resolved-etc-hosts.c"
, 92, __PRETTY_FUNCTION__); } while (0)
;
58
Taking false branch
59
Loop condition is false. Exiting loop
93
94 r = in_addr_is_null(family, address);
95 if (r < 0)
60
Assuming 'r' is >= 0
61
Taking false branch
96 return r;
97 if (r > 0)
62
Assuming 'r' is <= 0
63
Taking false branch
98 /* This is an 0.0.0.0 or :: item, which we assume means that we shall map the specified hostname to
99 * nothing. */
100 item = NULL((void*)0);
101 else {
102 /* If this is a normal address, then, simply add entry mapping it to the specified names */
103
104 item = set_get(m->etc_hosts_by_address, &key);
105 if (item) {
64
Assuming 'item' is null
65
Taking false branch
106 r = strv_extend_strv(&item->names, names, true1);
107 if (r < 0)
108 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 108, __func__)
;
109 } else {
110
111 r = set_ensure_allocated(&m->etc_hosts_by_address, &etc_hosts_item_ops)internal_set_ensure_allocated(&m->etc_hosts_by_address
, &etc_hosts_item_ops )
;
112 if (r < 0)
66
Assuming 'r' is >= 0
67
Taking false branch
113 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 113, __func__)
;
114
115 item = new0(EtcHostsItem, 1)((EtcHostsItem*) calloc((1), sizeof(EtcHostsItem)));
68
Memory is allocated
116 if (!item)
69
Assuming 'item' is non-null
70
Taking false branch
117 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 117, __func__)
;
118
119 item->family = family;
120 item->address = *address;
121 item->names = names;
122
123 r = set_put(m->etc_hosts_by_address, item);
124 if (r < 0) {
71
Assuming 'r' is >= 0
72
Taking false branch
125 free(item);
126 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 126, __func__)
;
127 }
128 }
129 }
130
131 STRV_FOREACH(n, names)for ((n) = (names); (n) && *(n); (n)++) {
73
Loop condition is false. Execution continues on line 166
132 EtcHostsItemByName *bn;
133
134 bn = hashmap_get(m->etc_hosts_by_name, *n);
135 if (!bn) {
136 r = hashmap_ensure_allocated(&m->etc_hosts_by_name, &dns_name_hash_ops)internal_hashmap_ensure_allocated(&m->etc_hosts_by_name
, &dns_name_hash_ops )
;
137 if (r < 0)
138 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 138, __func__)
;
139
140 bn = new0(EtcHostsItemByName, 1)((EtcHostsItemByName*) calloc((1), sizeof(EtcHostsItemByName)
))
;
141 if (!bn)
142 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 142, __func__)
;
143
144 bn->name = strdup(*n);
145 if (!bn->name) {
146 free(bn);
147 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 147, __func__)
;
148 }
149
150 r = hashmap_put(m->etc_hosts_by_name, bn->name, bn);
151 if (r < 0) {
152 free(bn->name);
153 free(bn);
154 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 154, __func__)
;
155 }
156 }
157
158 if (item) {
159 if (!GREEDY_REALLOC(bn->items, bn->n_allocated, bn->n_items+1)greedy_realloc((void**) &(bn->items), &(bn->n_allocated
), (bn->n_items+1), sizeof((bn->items)[0]))
)
160 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 160, __func__)
;
161
162 bn->items[bn->n_items++] = item;
163 }
164 }
165
166 return 0;
74
Potential leak of memory pointed to by 'item'
167}
168
169static int parse_line(Manager *m, unsigned nr, const char *line) {
170 _cleanup_free___attribute__((cleanup(freep))) char *address = NULL((void*)0);
171 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **names = NULL((void*)0);
172 union in_addr_union in;
173 bool_Bool suppressed = false0;
174 int family, r;
175
176 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolved-etc-hosts.c"
, 176, __PRETTY_FUNCTION__); } while (0)
;
28
Taking false branch
29
Loop condition is false. Exiting loop
177 assert(line)do { if ((__builtin_expect(!!(!(line)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("line"), "../src/resolve/resolved-etc-hosts.c"
, 177, __PRETTY_FUNCTION__); } while (0)
;
30
Taking false branch
31
Loop condition is false. Exiting loop
178
179 r = extract_first_word(&line, &address, NULL((void*)0), EXTRACT_RELAX);
180 if (r < 0)
32
Assuming 'r' is >= 0
33
Taking false branch
181 return log_error_errno(r, "Couldn't extract address, in line /etc/hosts:%u.", nr)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolved-etc-hosts.c", 181, __func__, "Couldn't extract address, in line /etc/hosts:%u."
, nr) : -abs(_e); })
;
182 if (r == 0) {
34
Assuming 'r' is not equal to 0
35
Taking false branch
183 log_error("Premature end of line, in line /etc/hosts:%u.", nr)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolved-etc-hosts.c", 183, __func__, "Premature end of line, in line /etc/hosts:%u."
, nr) : -abs(_e); })
;
184 return -EINVAL22;
185 }
186
187 r = in_addr_from_string_auto(address, &family, &in);
188 if (r < 0)
36
Assuming 'r' is >= 0
37
Taking false branch
189 return log_error_errno(r, "Address '%s' is invalid, in line /etc/hosts:%u.", address, nr)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolved-etc-hosts.c", 189, __func__, "Address '%s' is invalid, in line /etc/hosts:%u."
, address, nr) : -abs(_e); })
;
190
191 for (;;) {
38
Loop condition is true. Entering loop body
48
Loop condition is true. Entering loop body
192 _cleanup_free___attribute__((cleanup(freep))) char *name = NULL((void*)0);
193
194 r = extract_first_word(&line, &name, NULL((void*)0), EXTRACT_RELAX);
195 if (r < 0)
39
Assuming 'r' is >= 0
40
Taking false branch
49
Assuming 'r' is >= 0
50
Taking false branch
196 return log_error_errno(r, "Couldn't extract host name, in line /etc/hosts:%u.", nr)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolved-etc-hosts.c", 196, __func__, "Couldn't extract host name, in line /etc/hosts:%u."
, nr) : -abs(_e); })
;
197 if (r == 0)
41
Assuming 'r' is not equal to 0
42
Taking false branch
51
Assuming 'r' is equal to 0
52
Taking true branch
198 break;
53
Execution continues on line 217
199
200 r = dns_name_is_valid(name);
201 if (r
42.1
'r' is > 0
<= 0)
43
Taking false branch
202 return log_error_errno(r, "Hostname %s is not valid, ignoring, in line /etc/hosts:%u.", name, nr)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolved-etc-hosts.c", 202, __func__, "Hostname %s is not valid, ignoring, in line /etc/hosts:%u."
, name, nr) : -abs(_e); })
;
203
204 if (is_localhost(name)) {
44
Assuming the condition is false
45
Taking false branch
205 /* Suppress the "localhost" line that is often seen */
206 suppressed = true1;
207 continue;
208 }
209
210 r = strv_push(&names, name);
211 if (r < 0)
46
Assuming 'r' is >= 0
47
Taking false branch
212 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolved-etc-hosts.c"
, 212, __func__)
;
213
214 name = NULL((void*)0);
215 }
216
217 if (strv_isempty(names)) {
54
Taking false branch
218
219 if (suppressed)
220 return 0;
221
222 log_error("Line is missing any host names, in line /etc/hosts:%u.", nr)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolved-etc-hosts.c", 222, __func__, "Line is missing any host names, in line /etc/hosts:%u."
, nr) : -abs(_e); })
;
223 return -EINVAL22;
224 }
225
226 /* Takes possession of the names strv */
227 r = add_item(m, family, &in, names);
55
Calling 'add_item'
228 if (r < 0)
229 return r;
230
231 names = NULL((void*)0);
232 return r;
233}
234
235int manager_etc_hosts_read(Manager *m) {
236 _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0);
237 char line[LINE_MAX2048];
238 struct stat st;
239 usec_t ts;
240 unsigned nr = 0;
241 int r;
242
243 assert_se(sd_event_now(m->event, clock_boottime_or_monotonic(), &ts) >= 0)do { if ((__builtin_expect(!!(!(sd_event_now(m->event, clock_boottime_or_monotonic
(), &ts) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("sd_event_now(m->event, clock_boottime_or_monotonic(), &ts) >= 0"
), "../src/resolve/resolved-etc-hosts.c", 243, __PRETTY_FUNCTION__
); } while (0)
;
11
Assuming the condition is true
12
Taking false branch
13
Loop condition is false. Exiting loop
244
245 /* See if we checked /etc/hosts recently already */
246 if (m->etc_hosts_last != USEC_INFINITY((usec_t) -1) && m->etc_hosts_last + ETC_HOSTS_RECHECK_USEC(2*((usec_t) 1000000ULL)) > ts)
14
Assuming the condition is false
247 return 0;
248
249 m->etc_hosts_last = ts;
250
251 if (m->etc_hosts_mtime != USEC_INFINITY((usec_t) -1)) {
15
Assuming the condition is false
16
Taking false branch
252 if (stat("/etc/hosts", &st) < 0) {
253 if (errno(*__errno_location ()) == ENOENT2) {
254 r = 0;
255 goto clear;
256 }
257
258 return log_error_errno(errno, "Failed to stat /etc/hosts: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolved-etc-hosts.c", 258
, __func__, "Failed to stat /etc/hosts: %m") : -abs(_e); })
;
259 }
260
261 /* Did the mtime change? If not, there's no point in re-reading the file. */
262 if (timespec_load(&st.st_mtim) == m->etc_hosts_mtime)
263 return 0;
264 }
265
266 f = fopen("/etc/hosts", "re");
267 if (!f) {
17
Assuming 'f' is non-null
18
Taking false branch
268 if (errno(*__errno_location ()) == ENOENT2) {
269 r = 0;
270 goto clear;
271 }
272
273 return log_error_errno(errno, "Failed to open /etc/hosts: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolved-etc-hosts.c", 273
, __func__, "Failed to open /etc/hosts: %m") : -abs(_e); })
;
274 }
275
276 /* Take the timestamp at the beginning of processing, so that any changes made later are read on the next
277 * invocation */
278 r = fstat(fileno(f), &st);
279 if (r < 0)
19
Assuming 'r' is >= 0
20
Taking false branch
280 return log_error_errno(errno, "Failed to fstat() /etc/hosts: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolved-etc-hosts.c", 280
, __func__, "Failed to fstat() /etc/hosts: %m") : -abs(_e); }
)
;
281
282 manager_etc_hosts_flush(m);
283
284 FOREACH_LINE(line, f, return log_error_errno(errno, "Failed to read /etc/hosts: %m"))for (;;) if (!fgets(line, sizeof(line), f)) { if (ferror(f)) {
return ({ int _level = ((3)), _e = (((*__errno_location ()))
), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm
) >= ((_level) & 0x07)) ? log_internal_realm(((_realm)
<< 10 | (_level)), _e, "../src/resolve/resolved-etc-hosts.c"
, 284, __func__, "Failed to read /etc/hosts: %m") : -abs(_e);
}); } break; } else
{
21
Loop condition is true. Entering loop body
22
Assuming the condition is false
23
Taking false branch
285 char *l;
286
287 nr++;
288
289 l = strstrip(line);
290 if (isempty(l))
24
Taking false branch
291 continue;
292 if (l[0] == '#')
25
Assuming the condition is false
26
Taking false branch
293 continue;
294
295 r = parse_line(m, nr, l);
27
Calling 'parse_line'
296 if (r == -ENOMEM12) /* On OOM we abandon the half-built-up structure. All other errors we ignore and proceed */
297 goto clear;
298 }
299
300 m->etc_hosts_mtime = timespec_load(&st.st_mtim);
301 m->etc_hosts_last = ts;
302
303 return 1;
304
305clear:
306 manager_etc_hosts_flush(m);
307 return r;
308}
309
310int manager_etc_hosts_lookup(Manager *m, DnsQuestion* q, DnsAnswer **answer) {
311 bool_Bool found_a = false0, found_aaaa = false0;
312 EtcHostsItemByName *bn;
313 EtcHostsItem k = {};
314 DnsResourceKey *t;
315 const char *name;
316 unsigned i;
317 int r;
318
319 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolved-etc-hosts.c"
, 319, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'm' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
320 assert(q)do { if ((__builtin_expect(!!(!(q)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("q"), "../src/resolve/resolved-etc-hosts.c"
, 320, __PRETTY_FUNCTION__); } while (0)
;
4
Assuming 'q' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
321 assert(answer)do { if ((__builtin_expect(!!(!(answer)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("answer"), "../src/resolve/resolved-etc-hosts.c"
, 321, __PRETTY_FUNCTION__); } while (0)
;
7
Assuming 'answer' is non-null
8
Taking false branch
9
Loop condition is false. Exiting loop
322
323 r = manager_etc_hosts_read(m);
10
Calling 'manager_etc_hosts_read'
324 if (r < 0)
325 return r;
326
327 name = dns_question_first_name(q);
328 if (!name)
329 return 0;
330
331 r = dns_name_address(name, &k.family, &k.address);
332 if (r > 0) {
333 EtcHostsItem *item;
334 DnsResourceKey *found_ptr = NULL((void*)0);
335
336 item = set_get(m->etc_hosts_by_address, &k);
337 if (!item)
338 return 0;
339
340 /* We have an address in /etc/hosts that matches the queried name. Let's return successful. Actual data
341 * we'll only return if the request was for PTR. */
342
343 DNS_QUESTION_FOREACH(t, q)for (size_t __unique_prefix_i7 = ({ (t) = ((q) && (q)
->n_keys > 0) ? (q)->keys[0] : ((void*)0); 0; }); (q
) && (__unique_prefix_i7 < (q)->n_keys); __unique_prefix_i7
++, (t) = (__unique_prefix_i7 < (q)->n_keys ? (q)->keys
[__unique_prefix_i7] : ((void*)0)))
{
344 if (!IN_SET(t->type, DNS_TYPE_PTR, DNS_TYPE_ANY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){DNS_TYPE_PTR, DNS_TYPE_ANY})/sizeof(int)
]; switch(t->type) { case DNS_TYPE_PTR: case DNS_TYPE_ANY:
_found = 1; break; default: break; } _found; })
)
345 continue;
346 if (!IN_SET(t->class, DNS_CLASS_IN, DNS_CLASS_ANY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){DNS_CLASS_IN, DNS_CLASS_ANY})/sizeof(int
)]; switch(t->class) { case DNS_CLASS_IN: case DNS_CLASS_ANY
: _found = 1; break; default: break; } _found; })
)
347 continue;
348
349 r = dns_name_equal(dns_resource_key_name(t), name);
350 if (r < 0)
351 return r;
352 if (r > 0) {
353 found_ptr = t;
354 break;
355 }
356 }
357
358 if (found_ptr) {
359 char **n;
360
361 r = dns_answer_reserve(answer, strv_length(item->names));
362 if (r < 0)
363 return r;
364
365 STRV_FOREACH(n, item->names)for ((n) = (item->names); (n) && *(n); (n)++) {
366 _cleanup_(dns_resource_record_unrefp)__attribute__((cleanup(dns_resource_record_unrefp))) DnsResourceRecord *rr = NULL((void*)0);
367
368 rr = dns_resource_record_new(found_ptr);
369 if (!rr)
370 return -ENOMEM12;
371
372 rr->ptr.name = strdup(*n);
373 if (!rr->ptr.name)
374 return -ENOMEM12;
375
376 r = dns_answer_add(*answer, rr, 0, DNS_ANSWER_AUTHENTICATED);
377 if (r < 0)
378 return r;
379 }
380 }
381
382 return 1;
383 }
384
385 bn = hashmap_get(m->etc_hosts_by_name, name);
386 if (!bn)
387 return 0;
388
389 r = dns_answer_reserve(answer, bn->n_items);
390 if (r < 0)
391 return r;
392
393 DNS_QUESTION_FOREACH(t, q)for (size_t __unique_prefix_i8 = ({ (t) = ((q) && (q)
->n_keys > 0) ? (q)->keys[0] : ((void*)0); 0; }); (q
) && (__unique_prefix_i8 < (q)->n_keys); __unique_prefix_i8
++, (t) = (__unique_prefix_i8 < (q)->n_keys ? (q)->keys
[__unique_prefix_i8] : ((void*)0)))
{
394 if (!IN_SET(t->type, DNS_TYPE_A, DNS_TYPE_AAAA, DNS_TYPE_ANY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){DNS_TYPE_A, DNS_TYPE_AAAA, DNS_TYPE_ANY}
)/sizeof(int)]; switch(t->type) { case DNS_TYPE_A: case DNS_TYPE_AAAA
: case DNS_TYPE_ANY: _found = 1; break; default: break; } _found
; })
)
395 continue;
396 if (!IN_SET(t->class, DNS_CLASS_IN, DNS_CLASS_ANY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){DNS_CLASS_IN, DNS_CLASS_ANY})/sizeof(int
)]; switch(t->class) { case DNS_CLASS_IN: case DNS_CLASS_ANY
: _found = 1; break; default: break; } _found; })
)
397 continue;
398
399 r = dns_name_equal(dns_resource_key_name(t), name);
400 if (r < 0)
401 return r;
402 if (r == 0)
403 continue;
404
405 if (IN_SET(t->type, DNS_TYPE_A, DNS_TYPE_ANY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){DNS_TYPE_A, DNS_TYPE_ANY})/sizeof(int)];
switch(t->type) { case DNS_TYPE_A: case DNS_TYPE_ANY: _found
= 1; break; default: break; } _found; })
)
406 found_a = true1;
407 if (IN_SET(t->type, DNS_TYPE_AAAA, DNS_TYPE_ANY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){DNS_TYPE_AAAA, DNS_TYPE_ANY})/sizeof(int
)]; switch(t->type) { case DNS_TYPE_AAAA: case DNS_TYPE_ANY
: _found = 1; break; default: break; } _found; })
)
408 found_aaaa = true1;
409
410 if (found_a && found_aaaa)
411 break;
412 }
413
414 for (i = 0; i < bn->n_items; i++) {
415 _cleanup_(dns_resource_record_unrefp)__attribute__((cleanup(dns_resource_record_unrefp))) DnsResourceRecord *rr = NULL((void*)0);
416
417 if ((!found_a && bn->items[i]->family == AF_INET2) ||
418 (!found_aaaa && bn->items[i]->family == AF_INET610))
419 continue;
420
421 r = dns_resource_record_new_address(&rr, bn->items[i]->family, &bn->items[i]->address, bn->name);
422 if (r < 0)
423 return r;
424
425 r = dns_answer_add(*answer, rr, 0, DNS_ANSWER_AUTHENTICATED);
426 if (r < 0)
427 return r;
428 }
429
430 return found_a || found_aaaa;
431}