Commit Graph

79 Commits

Author SHA1 Message Date
Lennart Poettering 5777c6130b resolved: always take a timestamp when first seeing a packet
This is later useful if we want to adjust the TTLs of packets we want to
propagate to clients.
2020-12-16 14:20:49 +01:00
Pavel Sapezhko 6d8325f66a resolved: allow cache responses from local DNS servers 2020-11-27 09:03:42 +09:00
Yu Watanabe db9ecf0501 license: LGPL-2.1+ -> LGPL-2.1-or-later 2020-11-09 13:23:58 +09:00
Lennart Poettering c36d5b5be9 resolved: don't append RFC6975 data to stub replies
We previously checked the QR bit to decide whether the RFC6975 algorithm
data in our packets. But that doesn't work in many cases, since we
initialize the QR flags along with the other flags usually only after
appending OPT (since success to do so propagates into flags). Hence,
let's add an explicit parameter that controls whether to include RFC6975
data in DNS packets, and set it to false for stub reply, and on true for
upstream queries.

Fixes: #17217
2020-10-10 16:22:22 +02:00
Lennart Poettering 0354029bf5 resolved: don't store udp/tcp fd in DnsPacket object
DnsPacket should better be a "dead" object, i.e. list facts, not track
resources. By including an fd in its fields it started tracking
resources however, without actually taking a ref to the fd (i.e. no
dup() or so was called on it).

Let's hence rework things so that we don#t have to keep track of the fd
a packet came in from. Instead, pass around the DnsStubListenerExtra
object wherever we need to.

This should be useful as soon as we start caching whole DnsPacket
objects to allow replying to DNSSEC/CO packets, i.e. where we have to
keep a copy of the original DnsPacket around for a long time in cache,
potentially much longer than the fds the packet was received on.
2020-09-08 19:47:30 +02:00
Yu Watanabe 89f7435d0c resolve: use correct fd for UDP stub listner 2020-09-04 23:54:35 +09:00
Lennart Poettering acd74d61d2 resolved: don't let EDNS0 OPT dgram size affect TCP
Fixes: #11884
2019-03-13 19:34:05 +01:00
Victor Tapia e6eed94459 resolved: Increase size of TCP stub replies
DNS_PACKET_PAYLOAD_SIZE_MAX is limiting the size of the stub replies to
512 with EDNS off or 4096 with EDNS on, without checking the protocol
used. This makes TCP replies for clients without EDNS support to be
limited to 512, making the truncate flag useless if the query result is
bigger than 512 bytes.

This commit increases the size of TCP replies to DNS_PACKET_SIZE_MAX

Fixes: #10816
2018-11-28 14:06:36 +01:00
Yu Watanabe cf4b2f9906 tree-wide: use unsigned for refcount 2018-08-27 13:48:04 +09:00
Yu Watanabe afb76fdbff tree-wide: drop double newline 2018-06-29 11:02:17 +09:00
Yu Watanabe 8f5dd8c094 tree-wide: drop empty comments 2018-06-29 11:00:30 +09:00
Lennart Poettering 0c69794138 tree-wide: remove Lennart's copyright lines
These lines are generally out-of-date, incomplete and unnecessary. With
SPDX and git repository much more accurate and fine grained information
about licensing and authorship is available, hence let's drop the
per-file copyright notice. Of course, removing copyright lines of others
is problematic, hence this commit only removes my own lines and leaves
all others untouched. It might be nicer if sooner or later those could
go away too, making git the only and accurate source of authorship
information.
2018-06-14 10:20:20 +02:00
Lennart Poettering 818bf54632 tree-wide: drop 'This file is part of systemd' blurb
This part of the copyright blurb stems from the GPL use recommendations:

https://www.gnu.org/licenses/gpl-howto.en.html

The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.

hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
2018-06-14 10:20:20 +02:00
Iwan Timmer 98767d75d7 resolved: longlived TCP connections
Keep DNS over TCP connection open until it's closed by the server or after a timeout.
2018-06-11 20:17:51 +02:00
Zbigniew Jędrzejewski-Szmek 11a1589223 tree-wide: drop license boilerplate
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.

I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
2018-04-06 18:58:55 +02:00
Zbigniew Jędrzejewski-Szmek 53e1b68390 Add SPDX license identifiers to source files under the LGPL
This follows what the kernel is doing, c.f.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5fd54ace4721fc5ce2bb5aef6318fcf17f421460.
2017-11-19 19:08:15 +01:00
Lennart Poettering 5102765695 resolved: rework how we handle truncation in the stub resolver
When we a reply message gets longer than the client supports we need to
truncate the response and set the TC bit, and we already do that.
However, we are not supposed to send incomplete RRs in that case, but
instead truncate right at a record boundary. Do that.

This fixes the "Message parser reports malformed message packet."
warning the venerable "host" tool outputs when a very large response is
requested.

See: #6520
2017-10-05 12:22:43 +02:00
Zbigniew Jędrzejewski-Szmek 86d0608929 test-resolved-packet: skip most of the loop
We want to test the edge cases, but testing all the values in between
is mostly pointless and slow on slow architectures (>1s on rpi).
2017-07-13 17:55:02 -04:00
Benjamin Robin 46a5859673 resolve: Try to remove the ambiguity about the mtu parameter of dns_packet_new (#6285)
Actually the caller of dns_packet_new() pass 0 or the data size of the UDP message.
So try to reflect that, so rename the `mtu` parameter to `min_alloc_dsize`.

In fact `mtu` is the size of the whole UDP message, including the UDP header,
and here we just need to pass the size of data (without header). This was confusing.

Also add a check on the requested allocated size, since some caller do not check what is really allocated.
Indeed the function do not allocate more than DNS_PACKET_SIZE_MAX whatever the value of the `mtu` parameter.
2017-07-05 22:56:17 -04:00
Zbigniew Jędrzejewski-Szmek 64a21fdaca resolved: define various packet sizes as unsigned
This seems like the right thing to do, and apparently at least some compilers
warn about signed/unsigned comparisons with DNS_PACKET_SIZE_MAX.
2017-06-27 17:02:35 -04:00
Zbigniew Jędrzejewski-Szmek db848813ba resolved: simplify alloc size calculation
The allocation size was calculated in a complicated way, and for values
close to the page size we would actually allocate less than requested.

Reported by Chris Coulson <chris.coulson@canonical.com>.

CVE-2017-9445
2017-06-27 13:19:52 -04:00
Dmitry Rozhkov 58ab31d57f resolved: add cache-flush bit to answers in mDNS announcements
See the section 10.2 of RFC6762 for details.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
2017-01-19 11:51:21 +02:00
Lennart Poettering 6f21e066f6 resolved: properly handle BADCOOKIE DNS error
Add this new error code (documented in RFC7873) to our list of known errors.
2016-10-06 19:04:09 +02:00
Lennart Poettering b30bf55d5c resolved: respond to local resolver requests on 127.0.0.53:53
In order to improve compatibility with local clients that speak DNS directly
(and do not use NSS or our bus API) listen locally on 127.0.0.53:53 and process
any queries made that way.

Note that resolved does not implement a full DNS server on this port, but
simply enough to allow normal, local clients to resolve RRs through resolved.
Specifically it does not implement queries without the RD bit set (these are
requests where recursive lookups are explicitly disabled), and neither queries
with DNSSEC DO set in combination with DNSSEC CD (i.e. DNSSEC lookups with
validation turned off). It also refuses zone transfers and obsolete RR types.
All lookups done this way will be rejected with a clean error code, so that the
client side can repeat the query with a reduced feature set.

The code will set the DNSSEC AD flag however, depending on whether the data
resolved has been validated (or comes from a local, trusted source).

Lookups made via this mechanisms are propagated to LLMNR and mDNS as necessary,
but this is only partially useful as DNS packets cannot carry IP scope data
(i.e. the ifindex), and hence link-local addresses returned cannot be used
properly (and given that LLMNR/mDNS are mostly about link-local communication
this is quite a limitation). Also, given that DNS tends to use IDNA for
non-ASCII names, while LLMNR/mDNS uses UTF-8 lookups cannot be mapped 1:1.

In general this should improve compatibility with clients bypassing NSS but
it is highly recommended for clients to instead use NSS or our native bus API.

This patch also beefs up the DnsStream logic, as it reuses the code for local
TCP listening. DnsStream now provides proper reference counting for its
objects.

In order to avoid feedback loops resolved will no silently ignore 127.0.0.53
specified as DNS server when reading configuration.

resolved listens on 127.0.0.53:53 instead of 127.0.0.1:53 in order to leave
the latter free for local, external DNS servers or forwarders.

This also changes the "etc.conf" tmpfiles snippet to create a symlink from
/etc/resolv.conf to /usr/lib/systemd/resolv.conf by default, thus making this
stub the default mode of operation if /etc is not populated.
2016-06-21 14:15:23 +02:00
Lennart Poettering f2ed4c696a resolved: extend dns_packet_append_opt() so that it can set the extended rcode
We don't make use of this yet, but later work will.
2016-06-21 13:20:48 +02:00
Lennart Poettering f471bc11c6 resolved: add dns_packet_add_{question,answer}() helper
And make use of it at a couple of places.
2016-06-21 13:20:48 +02:00
Lennart Poettering 12e1893af3 resolved: fix definition of SD_RESOLVED_FLAGS_MAKE 2016-02-13 20:33:49 +01:00
Daniel Mack b26fa1a2fb tree-wide: remove Emacs lines from all files
This should be handled fine now by .dir-locals.el, so need to carry that
stuff in every file.
2016-02-10 13:41:57 +01:00
Daniel Mack b6c5d46b23 resolved: fix mDNS IPv6 multicast address
Fixes #2366
2016-01-19 14:11:05 +01:00
Lennart Poettering f3abbe2540 resolved: parse EDNS0 rcode extension bits 2015-12-29 21:42:09 +01:00
Lennart Poettering 519ef04651 resolved: rework OPT RR generation logic
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.
2015-12-27 01:41:40 +01:00
Lennart Poettering d2579eec5e resolved: rework mDNS cache-flush bit handling
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().
2015-12-18 19:40:47 +01:00
Lennart Poettering a3db237b8f resolved: apparently not all names are used in canonical form for DNSSEC validation
Specifically, it appears as if the NSEC next domain name should be in
the original casing rather than canonical form, when validating.
2015-12-14 21:28:39 +01:00
Lennart Poettering 8af5b88322 resolved: split out check whether reply matches our question
It's complicated enough, it deserves its own call.

(Also contains some unrelated whitespace, comment and assertion changes)
2015-12-10 11:35:52 +01:00
Lennart Poettering d75acfb059 resolved: when parsing DNS packets, handle OPT RR specially
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.
2015-12-10 11:35:52 +01:00
Daniel Mack 9c49156383 resolved: add support for linked packets
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.
2015-12-10 10:20:54 +01:00
Daniel Mack dbfbb6e776 resolved: add dns_packet_set_flags()
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.
2015-12-10 10:20:23 +01:00
Daniel Mack 0db4c90afd resolved: add code to join/leave mDNS multicast groups
Per link, join the mDNS multicast groups when the scope is created, and
leave it again when the scope goes away.
2015-12-08 16:41:45 +01:00
Daniel Mack 4e5bf5e158 resolved: add packet header details for mDNS
Validate mDNS queries and responses by looking at some header fields,
add mDNS flags.
2015-12-08 16:41:45 +01:00
Lennart Poettering 931851e8e4 resolved: add a concept of "authenticated" responses
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.
2015-12-03 21:17:49 +01:00
Lennart Poettering 24710c48ed resolved: introduce a dnssec_mode setting per scope
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.
2015-12-03 21:17:49 +01:00
Lennart Poettering 8730bccfc5 resolved: move algorithm/digest definitions into resolved-dns-rr.h
After all, they are for flags and parameters of RRs and already relevant
when dealing with RRs outside of the serialization concept.
2015-12-03 00:26:58 +01:00
Lennart Poettering a8812dd7f1 resolved: add code to generate the wire format for a single RR
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.
2015-12-02 22:50:11 +01:00
Lennart Poettering 9551c15505 resolved: add code to map DNSSEC digest types to strings and back 2015-12-02 22:50:11 +01:00
Lennart Poettering f91dc2400d resolved: store DNSKEY fields flags+protocol as-is
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.
2015-12-02 22:50:11 +01:00
Lennart Poettering e30ec345ac resolved: add RFC 5702 defined DNSSEC algorithms to table 2015-12-02 22:50:11 +01:00
Tom Gundersen d74fb368b1 resolved: announce support for large UDP packets
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.
2015-11-27 01:35:47 +01:00
Tom Gundersen 7586f4d172 resolved: set the DNSSEC OK (DO) flag
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).
2015-11-27 01:35:34 +01:00
Tom Gundersen 9c5e12a431 resolved: implement minimal EDNS0 support
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).
2015-11-27 01:35:34 +01:00
Tom Gundersen dc913c9a1f resolved: rr - add OPT pseudo-rr support
Needed for EDNS0.
2015-11-27 01:35:34 +01:00