While browsing, I stumbled upon https://pkg.go.dev/golang.org/x/net/dns/dnsmessage#Builder and I can see that is a way quicker way to create a DNS message. This made me think about a miekg/dns.v2 package again and what that should fix. I think it’s indeed better to just retain the wire format at all times as this is faster - although just working with a Go struct is very much a joy. Also begs the question: “Is it really that slow?” (compression on large messages is slow, memory use will def. be higher in current miekg/dns).

The referenced package also has a Parser to parse out specific RR(sets) (mostly) from a message received from the wire. Not sure (and didn’t check) if that just points back into the bytes, or copies things.

DNS v2?

The builder method makes sense. And has seen use in the standard library as well, as strings.Builder. Trouble with doing this that you need custom types for everything, i.e. Name, instead of string.

Parse is the other side of this. You can just reference to an offset in the message’s byte slice, or copy it out. Keeping a reference is even more efficient, but you need to be very aware of sharing that buffer. And how does work with parsing a zone, convert to wire format on the fly? Currently we don’t have to do that, so that’s something that would be faster.

Improvements

Other stuff I would like to fix is:

Access specific elements of an RR. Sometimes you just need the ownername, or better, drop the owner name of the RR and only save the rest (to make things space efficient in a cache for instance). There should be need to do this more naturally. I.e. CopyWith or CopyWithout maybe we can do this today.

EDNS RRs. This sort of came into existence and it’s a complete separate world from the other RRs; there is no real reason why this can’t be unified into a single world. This can probably also be retrofitted.

More interfaces. The amount of time we spend hacking around the fixed TSIG implementation for folks who wanted to do something different was crazy; this should be all interfaced out.

Generics? Is there a place for the shiny new generics?

Postamble

So yes, I’m very much on the fence if keeping everything in wire format is worth it. Especially taking the task of caching into account. There you need to twiddle with the TTL of an RR (among other things!), so you can’t keep on using the shared buffer that holds the original RR.

Storing zone data can be done much more efficient when you can only store some bits once. I.e. for miek.nl you don’t need every RR stored to have that suffix, nor the Class or TTL.