X Tutup
Skip to content

Commit d0f14a6

Browse files
authored
Merge pull request systemd#19134 from poettering/outbound-special-hostname
introduce a new synthetic hostname "_outbound" that maps to "the" local IP address
2 parents 2d882d3 + 2f166bb commit d0f14a6

File tree

11 files changed

+262
-18
lines changed

11 files changed

+262
-18
lines changed

man/nss-myhostname.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@
5151
ordered by their metric. This assigns a stable hostname to the
5252
current gateway, useful for referencing it independently of the
5353
current network configuration state.</para></listitem>
54+
55+
<listitem><para>The hostname <literal>_outbound</literal> is resolved to the local IPv4 and IPv6
56+
addresses that are most likely used for communication with other hosts. This is determined by
57+
requesting a routing decision to the configured default gateways from the kernel and then using the
58+
local IP addresses selected by this decision. This hostname is only available if there is at least one
59+
local default gateway configured. This assigns a stable hostname to the local outbound IP addresses,
60+
useful for referencing them independently of the current network configuration state.</para></listitem>
5461
</itemizedlist>
5562

5663
<para>Various software relies on an always-resolvable local

man/resolvectl.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,11 +299,11 @@
299299

300300
<listitem><para>Takes a boolean parameter; used in conjunction with <command>query</command>. If true
301301
(the default), select domains are resolved on the local system, among them
302-
<literal>localhost</literal> and <literal>_gateway</literal> or entries from
303-
<filename>/etc/hosts</filename>. If false these domains are not resolved locally, and either fail (in
304-
case of <literal>localhost</literal> or <literal>_gateway</literal> and suchlike) or go to the
305-
network via regular DNS/mDNS/LLMNR lookups (in case of <filename>/etc/hosts</filename>
306-
entries).</para></listitem>
302+
<literal>localhost</literal>, <literal>_gateway</literal> and <literal>_outbound</literal>, or
303+
entries from <filename>/etc/hosts</filename>. If false these domains are not resolved locally, and
304+
either fail (in case of <literal>localhost</literal>, <literal>_gateway</literal> or
305+
<literal>_outbound</literal> and suchlike) or go to the network via regular DNS/mDNS/LLMNR lookups
306+
(in case of <filename>/etc/hosts</filename> entries).</para></listitem>
307307
</varlistentry>
308308

309309
<varlistentry>

man/systemd-resolved.service.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@
104104
gateway addresses, ordered by their metric. This assigns a stable hostname to the current gateway,
105105
useful for referencing it independently of the current network configuration state.</para></listitem>
106106

107+
<listitem><para>The hostname <literal>_outbound</literal> is resolved to the local IPv4 and IPv6
108+
addresses that are most likely used for communication with other hosts. This is determined by
109+
requesting a routing decision to the configured default gateways from the kernel and then using the
110+
local IP addresses selected by this decision. This hostname is only available if there is at least one
111+
local default gateway configured. This assigns a stable hostname to the local outbound IP addresses,
112+
useful for referencing them independently of the current network configuration state.</para></listitem>
113+
107114
<listitem><para>The mappings defined in <filename>/etc/hosts</filename> are resolved to their
108115
configured addresses and back, but they will not affect lookups for non-address types (like MX).
109116
Support for <filename>/etc/hosts</filename> may be disabled with <varname>ReadEtcHosts=no</varname>,

src/basic/hostname-util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,8 @@ static inline bool is_gateway_hostname(const char *hostname) {
2828
/* This tries to identify the valid syntaxes for the our synthetic "gateway" host. */
2929
return STRCASE_IN_SET(hostname, "_gateway", "_gateway.");
3030
}
31+
32+
static inline bool is_outbound_hostname(const char *hostname) {
33+
/* This tries to identify the valid syntaxes for the our synthetic "outbound" host. */
34+
return STRCASE_IN_SET(hostname, "_outbound", "_outbound.");
35+
}

src/nss-myhostname/nss-myhostname.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
5454
assert(h_errnop);
5555

5656
if (is_localhost(name)) {
57-
/* We respond to 'localhost', so that /etc/hosts
58-
* is optional */
57+
/* We respond to 'localhost', so that /etc/hosts is optional */
5958

6059
canonical = "localhost";
6160
local_address_ipv4 = htobe32(INADDR_LOOPBACK);
@@ -68,6 +67,14 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
6867

6968
canonical = "_gateway";
7069

70+
} else if (is_outbound_hostname(name)) {
71+
72+
n_addresses = local_outbounds(NULL, 0, AF_UNSPEC, &addresses);
73+
if (n_addresses <= 0)
74+
goto not_found;
75+
76+
canonical = "_outbound";
77+
7178
} else {
7279
hn = gethostname_malloc();
7380
if (!hn) {
@@ -343,6 +350,14 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
343350

344351
canonical = "_gateway";
345352

353+
} else if (is_outbound_hostname(name)) {
354+
355+
n_addresses = local_outbounds(NULL, 0, af, &addresses);
356+
if (n_addresses <= 0)
357+
goto not_found;
358+
359+
canonical = "_outbound";
360+
346361
} else {
347362
hn = gethostname_malloc();
348363
if (!hn) {

src/resolve/resolved-dns-scope.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,8 @@ DnsScopeMatch dns_scope_good_domain(
630630
if (dns_name_endswith(domain, "invalid") > 0)
631631
return DNS_SCOPE_NO;
632632

633-
/* Never go to network for the _gateway domain, it's something special, synthesized locally. */
634-
if (is_gateway_hostname(domain))
633+
/* Never go to network for the _gateway or _outbound domain — they're something special, synthesized locally. */
634+
if (is_gateway_hostname(domain) || is_outbound_hostname(domain))
635635
return DNS_SCOPE_NO;
636636

637637
switch (s->protocol) {
@@ -739,6 +739,7 @@ DnsScopeMatch dns_scope_good_domain(
739739

740740
if ((dns_name_is_single_label(domain) && /* only resolve single label names via LLMNR */
741741
!is_gateway_hostname(domain) && /* don't resolve "_gateway" with LLMNR, let local synthesizing logic handle that */
742+
!is_outbound_hostname(domain) && /* similar for "_outbound" */
742743
dns_name_equal(domain, "local") == 0 && /* don't resolve "local" with LLMNR, it's the top-level domain of mDNS after all, see above */
743744
manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */
744745
return DNS_SCOPE_YES_BASE + 1; /* Return +1, as we consider ourselves authoritative

src/resolve/resolved-dns-synthesize.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,27 +311,33 @@ static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_add
311311
return added;
312312
}
313313

314-
static int synthesize_gateway_rr(Manager *m, const DnsResourceKey *key, int ifindex, DnsAnswer **answer) {
314+
static int synthesize_gateway_rr(
315+
Manager *m,
316+
const DnsResourceKey *key,
317+
int ifindex,
318+
int (*lookup)(sd_netlink *context, int ifindex, int af, struct local_address **ret), /* either local_gateways() or local_outbound() */
319+
DnsAnswer **answer) {
315320
_cleanup_free_ struct local_address *addresses = NULL;
316321
int n = 0, af, r;
317322

318323
assert(m);
319324
assert(key);
325+
assert(lookup);
320326
assert(answer);
321327

322328
af = dns_type_to_af(key->type);
323329
if (af >= 0) {
324-
n = local_gateways(m->rtnl, ifindex, af, &addresses);
330+
n = lookup(m->rtnl, ifindex, af, &addresses);
325331
if (n < 0) /* < 0 means: error */
326332
return n;
327333

328334
if (n == 0) { /* == 0 means we have no gateway */
329335
/* See if there's a gateway on the other protocol */
330336
if (af == AF_INET)
331-
n = local_gateways(m->rtnl, ifindex, AF_INET6, NULL);
337+
n = lookup(m->rtnl, ifindex, AF_INET6, NULL);
332338
else {
333339
assert(af == AF_INET6);
334-
n = local_gateways(m->rtnl, ifindex, AF_INET, NULL);
340+
n = lookup(m->rtnl, ifindex, AF_INET, NULL);
335341
}
336342
if (n <= 0) /* error (if < 0) or really no gateway at all (if == 0) */
337343
return n;
@@ -402,14 +408,24 @@ int dns_synthesize_answer(
402408

403409
} else if (is_gateway_hostname(name)) {
404410

405-
r = synthesize_gateway_rr(m, key, ifindex, &answer);
411+
r = synthesize_gateway_rr(m, key, ifindex, local_gateways, &answer);
406412
if (r < 0)
407413
return log_error_errno(r, "Failed to synthesize gateway RRs: %m");
408414
if (r == 0) { /* if we have no gateway return NXDOMAIN */
409415
nxdomain = true;
410416
continue;
411417
}
412418

419+
} else if (is_outbound_hostname(name)) {
420+
421+
r = synthesize_gateway_rr(m, key, ifindex, local_outbounds, &answer);
422+
if (r < 0)
423+
return log_error_errno(r, "Failed to synthesize outbound RRs: %m");
424+
if (r == 0) { /* if we have no gateway return NXDOMAIN */
425+
nxdomain = true;
426+
continue;
427+
}
428+
413429
} else if ((dns_name_endswith(name, "127.in-addr.arpa") > 0 && dns_name_equal(name, "2.0.0.127.in-addr.arpa") == 0) ||
414430
dns_name_equal(name, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0) {
415431

@@ -431,6 +447,10 @@ int dns_synthesize_answer(
431447
if (v == 0 && w == 0) /* This IP address is neither a local one nor a gateway */
432448
continue;
433449

450+
/* Note that we never synthesize reverse PTR for _outbound, since those are local
451+
* addresses and thus mapped to the local hostname anyway, hence they already have a
452+
* mapping. */
453+
434454
} else
435455
continue;
436456

0 commit comments

Comments
 (0)
X Tutup