Age | Commit message (Collapse) | Author |
|
|
|
This moves management of the OPT RR out of the scope management and into
the server and packet management. There are now explicit calls for
appending and truncating the OPT RR from a packet
(dns_packet_append_opt() and dns_packet_truncate_opt()) as well as a
call to do the right thing depending on a DnsServer's feature level
(dns_server_adjust_opt()).
This also unifies the code to pick a server between the TCP and UDP code
paths, and makes sure the feature level used for the transaction is
selected at the time the server is picked, and not changed until the
next time we pick a server. The server selction code is now unified in
dns_transaction_pick_server().
This all fixes problems when changing between UDP and TCP communication
for the same server, and makes sure the UDP and TCP codepaths are more
alike. It also makes sure we never keep the UDP port open when switchung
to TCP, so that we don't have to handle incoming datagrams on the latter
we don't expect.
As the new code picks the DNS server at the time we make a connection,
we don't need to invalidate the DNS server anymore when changing to the
next one, thus dns_transaction_next_dns_server() has been removed.
|
|
This adds a new DnsAnswer item flag "DNS_ANSWER_SHARED_OWNER" which is
set for mDNS RRs that lack the cache-flush bit. The cache-flush bit is
removed from the DnsResourceRecord object in favour of this.
This also splits out the code that removes previous entries when adding
new positive ones into a new separate call dns_cache_remove_previous().
|
|
validation
Specifically, it appears as if the NSEC next domain name should be in
the original casing rather than canonical form, when validating.
|
|
It's complicated enough, it deserves its own call.
(Also contains some unrelated whitespace, comment and assertion changes)
|
|
As soon as we encounter the OPT RR while parsing, store it in a special
field in the DnsPacket structure. That way, we won't be confused if we
iterate through RRs, and can check that there's really only one of these
RRs around.
|
|
For mDNS, we need to support the TC bit in case the list of known answers
exceed the maximum packet size.
For this, add a 'more' pointer to DnsPacket for an additional packet.
When a packet is unref'ed, the ->more packet is also unrefed, so it
sufficient to only keep track of the 1st packet in a chain.
|
|
We need to support the TC bit in queries in case known answers exceed the
maximum packet size. Factor out the flags compilation to
dns_packet_set_flags() and make it externally available.
|
|
Per link, join the mDNS multicast groups when the scope is created, and
leave it again when the scope goes away.
|
|
Validate mDNS queries and responses by looking at some header fields,
add mDNS flags.
|
|
This adds a new SD_RESOLVED_AUTHENTICATED flag for responses we return
on the bus. When set, then the data has been authenticated. For now this
mostly reflects the DNSSEC AD bit, if DNSSEC=trust is set. As soon as
the client-side validation is complete it will be hooked up to this flag
too.
We also set this bit whenver we generated the data ourselves, for
example, because it originates in our local LLMNR zone, or from the
built-in trust anchor database.
The "systemd-resolve-host" tool has been updated to show the flag state
for the data it shows.
|
|
The setting controls which kind of DNSSEC validation is done: none at
all, trusting the AD bit, or client-side validation.
For now, no validation is implemented, hence the setting doesn't do much
yet, except of toggling the CD bit in the generated messages if full
client-side validation is requested.
|
|
After all, they are for flags and parameters of RRs and already relevant
when dealing with RRs outside of the serialization concept.
|
|
This adds dns_resource_record_to_wire_format() that generates the raw
wire-format of a single DnsResourceRecord object, and caches it in the
object, optionally in DNSSEC canonical form. This call is used later to
generate the RR serialization of RRs to verify.
This adds four new fields to DnsResourceRecord objects:
- wire_format points to the buffer with the wire-format version of the
RR
- wire_format_size stores the size of that buffer
- wire_format_rdata_offset specifies the index into the buffer where the
RDATA of the RR begins (i.e. the size of the key part of the RR).
- wire_format_canonical is a boolean that stores whether the cached wire
format is in DNSSEC canonical form or not.
Note that this patch adds a mode where a DnsPacket is allocated on the
stack (instead of on the heap), so that it is cheaper to reuse the
DnsPacket object for generating this wire format. After all we reuse the
DnsPacket object for this, since it comes with all the dynamic memory
management, and serialization calls we need anyway.
|
|
|
|
When verifying signatures we need to be able to verify the original
data we got for an RR set, and that means we cannot simply drop flags
bits or consider RRs invalid too eagerly. Hence, instead of parsing the
DNSKEY flags store them as-is. Similar, accept the protocol field as it
is, and don't consider it a parsing error if it is not 3.
Of course, this means that the DNSKEY handling code later on needs to
check explicit for protocol != 3.
|
|
|
|
This is often needed for proper DNSSEC support, and even to handle AAAA records
without falling back to TCP.
If the path between the client and server is fully compliant, this should always
work, however, that is not the case, and overlarge packets will get mysteriously
lost in some cases.
For that reason, we use a similar fallback mechanism as we do for palin EDNS0,
EDNS0+DO, etc.:
The large UDP size feature is different from the other supported feature, as we
cannot simply verify that it works based on receiving a reply (as the server
will usually send us much smaller packets than what we claim to support, so
simply receiving a reply does not mean much).
For that reason, we keep track of the largest UDP packet we ever received, as this
is the smallest known good size (defaulting to the standard 512 bytes). If
announcing the default large size of 4096 fails (in the same way as the other
features), we fall back to the known good size. The same logic of retrying after a
grace-period applies.
|
|
This indicates that we can handle DNSSEC records (per RFC3225), even if
all we do is silently drop them. This feature requires EDNS0 support.
As we do not yet support larger UDP packets, this feature increases the
risk of getting truncated packets.
Similarly to how we fall back to plain UDP if EDNS0 fails, we will fall
back to plain EDNS0 if EDNS0+DO fails (with the same logic of remembering
success and retrying after a grace period after failure).
|
|
This is a minimal implementation of RFC6891. Only default values
are used, so in reality this will be a noop.
EDNS0 support is dependent on the current server's feature level,
so appending the OPT pseudo RR is done when the packet is emitted,
rather than when it is assembled. To handle different feature
levels on retransmission, we strip off the OPT RR again after
sending the packet.
Similarly, to how we fall back to TCP if UDP fails, we fall back
to plain UDP if EDNS0 fails (but if EDNS0 ever succeeded we never
fall back again, and after a timeout we will retry EDNS0).
|
|
Needed for EDNS0.
|
|
After all, this is likely a local DNS forwarder that caches anyway,
hence there's no point in caching twice.
Fixes #2038.
|
|
RFC 6763 is very clear that TXT RRs should allow arbitrary binary
content, hence let's actually accept that. This also means accepting NUL
bytes in the middle of strings.
|
|
This is a continuation of the previous include sort patch, which
only sorted for .c files.
|
|
|
|
Some flags are defined differently on unicast DNS and LLMNR, let's
document this in the DNS_PACKET_MAKE_FLAGS() macro.
|
|
With more protocols to come, switch repetitive if-else blocks with a
switch-case statements.
|
|
We explicitly need to turn off name compression when marshalling or
demarshalling RRs for bus transfer, since they otherwise refer to packet
offsets that reference packets that are not transmitted themselves.
|
|
Needed for DNSSEC.
|
|
Currently we only make sure our links can handle the size of the payload witohut
taking the headers into account.
|
|
The C and T bits in the DNS packet header definitions are specific to LLMNR.
In regular DNS, they are called AA and RD instead. Reflect that by calling
the macros accordingly, and alias LLMNR specific macros.
While at it, define RA, AD and CD getters as well.
|
|
This patch removes includes that are not used. The removals were found with
include-what-you-use which checks if any of the symbols from a header is
in use.
|
|
something up
Also, return on which protocol/family/interface we found something.
|
|
|
|
|
|
|
|
|
|
|
|
Name defending is still missing.
|
|
|
|
different clients
|
|
Let's settle on a single type for all address family values, even if
UNIX is very inconsitent on the precise type otherwise. Given that
socket() is the primary entrypoint for the sockets API, and that uses
"int", and "int" is relatively simple and generic, we settle on "int"
for this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Let's turn resolved into a something truly useful: a fully asynchronous
DNS stub resolver that subscribes to network changes.
(More to come: caching, LLMNR, mDNS/DNS-SD, DNSSEC, IDN, NSS module)
|