]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: define source address for proxy-only stub replies
authorBenjamin Franzke <benjaminfranzke@googlemail.com>
Tue, 31 May 2022 19:36:55 +0000 (21:36 +0200)
committerBenjamin Franzke <benjaminfranzke@googlemail.com>
Tue, 31 May 2022 20:38:47 +0000 (22:38 +0200)
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

src/resolve/resolved-dns-stub.c

index 9e34161eb3283587d2fffb771c13c931c19f4392..89d1f1cdfc214fc3b2e5d55d82af3b379ca860e7 100644 (file)
@@ -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);
         }