We're lately seeing novel DNS RRTYPEs that are extensible by
introduction of new RDATA field types.
Well-motivated examples of this are SVCB and HTTPS records, in which
future "keys" can have novel value data types, and there is already
a mix of value data types among the existing keys.
While such extensibility is very useful, it is challenging to design
APIs that expose a mix of known and not yet known value types to users.
One ends up with complex models, with abstract classes for the value
slot, and extensible codecs with pluggable cocrete methods for the known
value types, and a generic "opaque" decoder that handles octet string
blobs for the unknown types. Applications can then do type-safe casts
of an abstract value field to a known concrete type.
Basically, we have a trade-off between future-proofing the RRTYPE to
meet evolving needs, and the complexity of the application API to
use the RRTYPE.
I am not trying to make a case against SVCB/HTTPS, these are
well-motivated as mentioned above. However, for completeness sake I
just implemented RFC8777 AMTRELAY support in a Haskell stub resolver,
and in that case decided to punt on API-compatible extensibility in
order to keep the API simple. I really don't expect to ever see new
relay types beyond the current:
0 - empty
1 - IPv4 address
2 - IPv6 address
3 - wire-form domain name
My take is that RFC8777 should NOT have reserved types 4-127 for future
extensions, creating an IANA registry for these. This instance of
future-proofing rather feelds like a case of
<https://fr.wikipedia.org/wiki/YAGNI>.
So instead I defined a union type with the above four variants plus one
more "opaque" blob format for anything with types 4-127, with no
abstract class or hooks to support API-compatible extensions that add
support additional non-opaque variants.
My message to the WG is in essence to be sparing in defining RRTYPEs
with extensible field subtypes. IMHO there needs to be a reasonably
clear case for future extensions that would introduce fundamentally new
data types within an RRTYPE.
The usability cost of open data types is non-trivial, and when the
benefit is remote, it may be prudent to have a fixed data type design,
with any unanticipated future changes handled by defining a new RRTYPE,
to carry those additional values rather than shoehorning them as
extensions onto the existing record.
--
Viktor. 🇺🇦 Слава Україні!
FWIW, the non-extensible Haskell AMTRELAY type definition is below.
This does not support decoding of hypothetical future relay types to
their concrete values. Types 4-127 are frozen as opaque octet-string
blobs.
data T_amtrelay = T_AMTRELAY
{ amtPref :: Word8 -- ^ Preference, lower is better
, amtDisc :: Bool -- ^ Discovery optional
, amtRelay :: AmtRelay
} deriving (Eq, Ord, Show)
data AmtRelay = Amt_Nil
| Amt_A IPv4
| Amt_AAAA IPv6
| Amt_Host Host
| Amt_Wild Word8 ShortByteString
deriving (Eq, Ord, Show)
-- | /Smart constructor/ of opaque relay forms, that ensures
-- a non-empty value and type in [4,127]. The underlying
-- Amt_Wild constructor is not exposed,
--
pattern Amt_Opaque :: Word8 -> ShortByteString -> AmtRelay
pattern Amt_Opaque t b <- Amt_Wild t b where
Amt_Opaque t b | t > 3 && t < 128 && not (SB.null b)
= Amt_Wild t b
| otherwise
= error "Invalid opaque AmtRelay"
_______________________________________________
DNSOP mailing list -- [email protected]
To unsubscribe send an email to [email protected]