Files
firezone/rust/connlib
Thomas Eizinger 0008539b65 refactor(connlib): use dedicated UDP DNS client (#10850)
By default, DNS queries are sent over UDP by most systems. UDP is an
easy to understand protocol because each packet stands by itself and at
least as far as UDP is concerned, the payload is contained within a
single packet.

In Firezone, we receive all DNS traffic on the TUN device as IP packets.
Processing the UDP packets is trivial as each query is contained within
a single IP packet. For TCP, we first need to assemble the TCP stream
before we can read the entire query.

In case a DNS query is not for a Firezone DNS resource, we want to
forward it to the specified upstream resolver, either directly from the
system or - in case the specified upstream resolver is an IP resource -
through the tunnel as an IP packet. Specifically, the forwarding of UDP
DNS packets through the tunnel currently happens like this:

IP packet -> read UDP payload -> parse DNS query -> mangle original
destination IP to new upstream -> send through tunnel

For TCP DNS queries, it is not quite as easy as we have to decode the
incoming TCP stream first before we can parse the DNS query. Thus, when
we want to then forward the query, we need to open our own TCP stream to
the upstream resolver and encode the DNS query onto that stream, sending
each IP packet from the TCP client through the tunnel.

The difference in these designs makes several code paths in connlib hard
to follow.

Therefore - and despite the simplicity of DNS over UDP - we already
created our own "Layer 3 UDP DNS"-client. This PR now integrates this
client into the tunnel. Using this new client, we can simplify the
processing of UDP DNS queries because we never have to "go back" to the
original IP packet. Instead, when a DNS query needs to be forwarded to
an usptream resolver through the tunnel, we simply tell the Layer 3 UDP
DNS client to make a new DNS query. The processing of the resulting IP
packet then happens in a different place, right next to where we also
process the IP packets of the TCP DNS client.

That simplifications unlocks further refactorings where we now only
process DNS queries in a single place and the transport we received it
over is a simple function parameter with the control flow for both of
them being identical.

Related: #4668
2025-11-11 03:53:25 +00:00
..

Connlib

Firezone's connectivity library shared by all clients.

Building Connlib

You shouldn't need to build connlib directly; it's typically built as a dependency of one of the other Firezone components. See READMEs in those directories for relevant instructions.