resolved: allow the full TTL to be used by OPT records
authorJames Coglan <james@neighbourhood.ie>
Fri, 28 Jun 2024 12:41:31 +0000 (13:41 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 5 Jul 2024 18:00:04 +0000 (20:00 +0200)
commit6ead24fcac878b3623408ecb1a05d07f29c4c04c
tree1afc20163a32bdeb069ddc72016fccda9ba64965
parentdc0167b674bc6b555c25f374719c818bc6ad1416
resolved: allow the full TTL to be used by OPT records

Whereas RFC 1035 says the TTL field takes the "positive values of a
signed 32 bit number", and RFC 2181 says "Implementations should treat
TTL values received with the most significant bit set as if the entire
value received was zero,", the dns_packet_read_rr() function sets
rr->ttl to zero if the MSB is set.

However, EDNS(0) as specified in RFC 6891 repurposes the TTL field's 4
octets to store other information, c.f.:

                  +0 (MSB)                            +1 (LSB)
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    0: |         EXTENDED-RCODE        |            VERSION            |
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    2: | DO|                           Z                               |
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

The first octet extends the usual 4-bit RCODE from the packet header by
providing an additional 8 bits of space, extending the RCODE to 12 bits.
But, our handling of the TTL field means that the high bit in the first
octet is not actually usable, since setting it will mean these 4 octets
are replaced with 0. This may have the effect of making us believe a
server does not support DNSSEC when it actually set the DO bit in its
OPT record.

Here we change things so that the TTL is only set to zero for record
types other than OPT.

(cherry picked from commit 131787979c700becaf6ec24a810658d1313587cc)
src/resolve/resolved-dns-packet.c