Skip to content

Commit 139cb31

Browse files
ldv-altkeszybz
authored andcommitted
resolved: keep track of first names listed for each address in /etc/hosts
These names will be used later in responses as canonical names. (cherry picked from commit 1bd76a6)
1 parent 3ce7c97 commit 139cb31

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

src/resolve/resolved-etc-hosts.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,18 @@ static int parse_line(EtcHosts *hosts, unsigned nr, const char *line) {
189189
return log_oom();
190190
}
191191

192-
r = set_ensure_consume(&item->names, &dns_name_hash_ops_free, TAKE_PTR(name));
192+
r = set_ensure_put(&item->names, &dns_name_hash_ops_free, name);
193193
if (r < 0)
194194
return log_oom();
195+
if (r == 0) /* the name is already listed */
196+
continue;
197+
/*
198+
* Keep track of the first name listed for this address.
199+
* This name will be used in responses as the canonical name.
200+
*/
201+
if (!item->canonical_name)
202+
item->canonical_name = name;
203+
TAKE_PTR(name);
195204
}
196205

197206
if (!found)

src/resolve/resolved-etc-hosts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
typedef struct EtcHostsItemByAddress {
99
struct in_addr_data address;
1010
Set *names;
11+
const char *canonical_name;
1112
} EtcHostsItemByAddress;
1213

1314
typedef struct EtcHostsItemByName {

src/resolve/test-resolved-etc-hosts.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,17 @@ TEST(parse_etc_hosts_system) {
2727
assert_se(etc_hosts_parse(&hosts, f) == 0);
2828
}
2929

30+
#define in_addr_4(_address_str) \
31+
(&(struct in_addr_data) { .family = AF_INET, .address.in = { .s_addr = inet_addr(_address_str) } })
32+
33+
#define in_addr_6(...) \
34+
(&(struct in_addr_data) { .family = AF_INET6, .address.in6 = { .s6_addr = __VA_ARGS__ } })
35+
3036
#define has_4(_set, _address_str) \
31-
set_contains(_set, &(struct in_addr_data) { .family = AF_INET, .address.in = { .s_addr = inet_addr(_address_str) } })
37+
set_contains(_set, in_addr_4(_address_str))
3238

3339
#define has_6(_set, ...) \
34-
set_contains(_set, &(struct in_addr_data) { .family = AF_INET6, .address.in6 = { .s6_addr = __VA_ARGS__ } })
40+
set_contains(_set, in_addr_6(__VA_ARGS__))
3541

3642
TEST(parse_etc_hosts) {
3743
_cleanup_(unlink_tempfilep) char
@@ -110,6 +116,20 @@ TEST(parse_etc_hosts) {
110116
assert_se(set_size(bn->addresses) == 1);
111117
assert_se(has_6(bn->addresses, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5}));
112118

119+
EtcHostsItemByAddress *ba;
120+
assert_se(ba = hashmap_get(hosts.by_address, in_addr_4("1.2.3.6")));
121+
assert_se(set_size(ba->names) == 2);
122+
assert_se(set_contains(ba->names, "dash"));
123+
assert_se(set_contains(ba->names, "dash-dash.where-dash"));
124+
assert_se(streq(ba->canonical_name, "dash"));
125+
126+
assert_se(ba = hashmap_get(hosts.by_address, in_addr_6({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5})));
127+
assert_se(set_size(ba->names) == 3);
128+
assert_se(set_contains(ba->names, "some.where"));
129+
assert_se(set_contains(ba->names, "some.other"));
130+
assert_se(set_contains(ba->names, "foobar.foo.foo"));
131+
assert_se(streq(ba->canonical_name, "some.where"));
132+
113133
assert_se( set_contains(hosts.no_address, "some.where"));
114134
assert_se( set_contains(hosts.no_address, "some.other"));
115135
assert_se( set_contains(hosts.no_address, "deny.listed"));

0 commit comments

Comments
 (0)