From: Benjamin Franzke Date: Tue, 31 May 2022 19:36:55 +0000 (+0200) Subject: resolved: define source address for proxy-only stub replies X-Git-Tag: v252-rc1~883^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dfa14e2859418593b2f9bfae8936d780148c4e6a;p=thirdparty%2Fsystemd.git resolved: define source address for proxy-only stub replies DnsPacket.ifindex=1 (loopback) is normalized to 0 whenever a message is received on the loopback iface, so for both listeners, 127.0.0.53 and 127.0.0.54, the ifindex will be set to 0 by manager_recv() for queries that have a local origin. Replies to such local messages need to set a proper ifindex in any case, as the supplied source-address would otherwise be ignored in manager_ipv4_send() (CMSG generation is skipped due to ifindex > 0 check). Note that this change only forces `ifindex` to loopback if it was actually normalized to `0` before (due to a loopback detection) in order to keep the nat-to-127.0.0.54-from-another-interface usecase that was described in a8d09063447568d87288a8e868fe386c1da7ce09 intact. Also note that nat is not supported for the main stub 127.0.0.53 which is why forcing LOOPBACK_IFINDEX was/is fine for that case. Fixes #23495 --- diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c index 9e34161eb32..89d1f1cdfc2 100644 --- a/src/resolve/resolved-dns-stub.c +++ b/src/resolve/resolved-dns-stub.c @@ -528,18 +528,26 @@ static int dns_stub_send( if (s) r = dns_stream_write_packet(s, reply); else { - int fd; + int fd, ifindex; fd = find_socket_fd(m, l, p->family, &p->sender, SOCK_DGRAM); if (fd < 0) return fd; + if (address_is_proxy(p->family, &p->destination)) + /* Force loopback iface if this is the loopback proxy stub + * and ifindex was normalized to 0 by manager_recv(). */ + ifindex = p->ifindex ?: LOOPBACK_IFINDEX; + else + /* Force loopback iface if this is the main listener stub. */ + ifindex = l ? p->ifindex : LOOPBACK_IFINDEX; + /* Note that it is essential here that we explicitly choose the source IP address for this * packet. This is because otherwise the kernel will choose it automatically based on the - * routing table and will thus pick 127.0.0.1 rather than 127.0.0.53. */ + * routing table and will thus pick 127.0.0.1 rather than 127.0.0.53/54. */ r = manager_send(m, fd, - l || address_is_proxy(p->family, &p->destination) ? p->ifindex : LOOPBACK_IFINDEX, /* force loopback iface if this is the main listener stub */ + ifindex, p->family, &p->sender, p->sender_port, &p->destination, reply); }