| File: | build-scan/../src/resolve/resolved-etc-hosts.c | 
| Warning: | line 166, column 16 Potential leak of memory pointed to by 'item' | 
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | ||||
| 15 | typedef struct EtcHostsItem { | |||
| 16 | int family; | |||
| 17 | union in_addr_union address; | |||
| 18 | ||||
| 19 | char **names; | |||
| 20 | } EtcHostsItem; | |||
| 21 | ||||
| 22 | typedef struct EtcHostsItemByName { | |||
| 23 | char *name; | |||
| 24 | ||||
| 25 | EtcHostsItem **items; | |||
| 26 | size_t n_items, n_allocated; | |||
| 27 | } EtcHostsItemByName; | |||
| 28 | ||||
| 29 | void 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 | ||||
| 50 | static 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 | ||||
| 61 | static 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 | ||||
| 76 | static const struct hash_ops etc_hosts_item_ops = { | |||
| 77 | .hash = etc_hosts_item_hash_func, | |||
| 78 | .compare = etc_hosts_item_compare_func, | |||
| 79 | }; | |||
| 80 | ||||
| 81 | static 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); | |||
| 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); | |||
| 93 | ||||
| 94 | r = in_addr_is_null(family, address); | |||
| 95 | if (r < 0) | |||
| 96 | return r; | |||
| 97 | if (r > 0) | |||
| 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) { | |||
| 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) | |||
| 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))); | |||
| 116 | if (!item) | |||
| 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) { | |||
| 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)++) { | |||
| 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; | |||
| 
 | ||||
| 167 | } | |||
| 168 | ||||
| 169 | static 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); | |||
| 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); | |||
| 178 | ||||
| 179 | r = extract_first_word(&line, &address, NULL((void*)0), EXTRACT_RELAX); | |||
| 180 | if (r < 0) | |||
| 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) { | |||
| 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) | |||
| 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 (;;) { | |||
| 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) | |||
| 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) | |||
| 198 | break; | |||
| 199 | ||||
| 200 | r = dns_name_is_valid(name); | |||
| 201 | if (r 
 | |||
| 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)) { | |||
| 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) | |||
| 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)) { | |||
| 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); | |||
| 228 | if (r < 0) | |||
| 229 | return r; | |||
| 230 | ||||
| 231 | names = NULL((void*)0); | |||
| 232 | return r; | |||
| 233 | } | |||
| 234 | ||||
| 235 | int 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); | |||
| 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) | |||
| 247 | return 0; | |||
| 248 | ||||
| 249 | m->etc_hosts_last = ts; | |||
| 250 | ||||
| 251 | if (m->etc_hosts_mtime != USEC_INFINITY((usec_t) -1)) { | |||
| 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) { | |||
| 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) | |||
| 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 { | |||
| 285 | char *l; | |||
| 286 | ||||
| 287 | nr++; | |||
| 288 | ||||
| 289 | l = strstrip(line); | |||
| 290 | if (isempty(l)) | |||
| 291 | continue; | |||
| 292 | if (l[0] == '#') | |||
| 293 | continue; | |||
| 294 | ||||
| 295 | r = parse_line(m, nr, l); | |||
| 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 | ||||
| 305 | clear: | |||
| 306 | manager_etc_hosts_flush(m); | |||
| 307 | return r; | |||
| 308 | } | |||
| 309 | ||||
| 310 | int 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); | |||
| 
 | ||||
| 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); | |||
| 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); | |||
| 322 | ||||
| 323 | r = manager_etc_hosts_read(m); | |||
| 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 | } |