diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2022-02-18 04:03:53 +0100 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-02-21 13:41:13 +0100 |
commit | 89678c515755403277938e34984f3faf4863d593 (patch) | |
tree | 2e704fe4f036cc017e27be5103098b70e4954c75 /udp.c | |
parent | 01ae772dcc4ba7930179521bb22712bb4256bb03 (diff) | |
download | passt-89678c515755403277938e34984f3faf4863d593.tar passt-89678c515755403277938e34984f3faf4863d593.tar.gz passt-89678c515755403277938e34984f3faf4863d593.tar.bz2 passt-89678c515755403277938e34984f3faf4863d593.tar.lz passt-89678c515755403277938e34984f3faf4863d593.tar.xz passt-89678c515755403277938e34984f3faf4863d593.tar.zst passt-89678c515755403277938e34984f3faf4863d593.zip |
conf, udp: Introduce basic DNS forwarding
For compatibility with libslirp/slirp4netns users: introduce a
mechanism to map, in the UDP routines, an address facing guest or
namespace to the first IPv4 or IPv6 address resulting from
configuration as resolver. This can be enabled with the new
--dns-forward option.
This implies that sourcing and using DNS addresses and search lists,
passed via command line or read from /etc/resolv.conf, is not bound
anymore to DHCP/DHCPv6/NDP usage: for example, pasta users might just
want to use addresses from /etc/resolv.conf as mapping target, while
not passing DNS options via DHCP.
Reflect this in all the involved code paths by differentiating
DHCP/DHCPv6/NDP usage from DNS configuration per se, and in the new
options --dhcp-dns, --dhcp-search for pasta, and --no-dhcp-dns,
--no-dhcp-search for passt.
This should be the last bit to enable substantial compatibility
between slirp4netns.sh and slirp4netns(1): pass the --dns-forward
option from the script too.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'udp.c')
-rw-r--r-- | udp.c | 16 |
1 files changed, 16 insertions, 0 deletions
@@ -718,6 +718,12 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, udp_tap_map[V6][src].loopback = 0; bitmap_set(udp_act[V6][UDP_ACT_TAP], src); + } else if (!IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) && + !memcmp(&b->s_in6.sin6_addr, &c->dns6_fwd, + sizeof(c->dns6_fwd)) && + ntohs(b->s_in6.sin6_port) == 53) { + b->ip6h.daddr = c->addr6_seen; + b->ip6h.saddr = c->dns6_fwd; } else { b->ip6h.daddr = c->addr6_seen; b->ip6h.saddr = b->s_in6.sin6_addr; @@ -797,6 +803,10 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, udp_tap_map[V4][src].loopback = 1; bitmap_set(udp_act[V4][UDP_ACT_TAP], src); + } else if (c->dns4_fwd && + s_addr == ntohl(c->dns4[0]) && + ntohs(b->s_in.sin_port) == 53) { + b->iph.saddr = c->dns4_fwd; } else { b->iph.saddr = b->s_in.sin_addr.s_addr; } @@ -958,6 +968,9 @@ int udp_tap_handler(struct ctx *c, int af, void *addr, s_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); else s_in.sin_addr.s_addr = c->addr4_seen; + } else if (s_in.sin_addr.s_addr == c->dns4_fwd && + ntohs(s_in.sin_port) == 53) { + s_in.sin_addr.s_addr = c->dns4[0]; } } else { s_in6 = (struct sockaddr_in6) { @@ -976,6 +989,9 @@ int udp_tap_handler(struct ctx *c, int af, void *addr, s_in6.sin6_addr = in6addr_loopback; else s_in6.sin6_addr = c->addr6_seen; + } else if (!memcmp(addr, &c->dns6_fwd, sizeof(c->dns6_fwd)) && + ntohs(s_in6.sin6_port) == 53) { + s_in6.sin6_addr = c->dns6[0]; } else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) { bind_to = BIND_LL; } |