I have a DNS domain with 3 TXT records:
$ORIGIN example.com.
@ IN TXT "thing one veryveryveryveryveryverylong"
@ IN TXT "thing two veryveryveryveryveryverylong"
@ IN TXT "thing three veryveryveryveryveryverylong"
When I do a DNS query (dig example.com. txt
) the reply fits in a UDP packet because the payload is less than 512 bytes (resulting in a packet less than 576 bytes).
However I know that if the reply is long enough, it will be truncated and the DNS client will have to repeat the request using TCP, which has longer length limits.
How can I calculate whether or not I have exceeded the length limit without generating the DNS records and doing a query?
I assume that the formula is something like:
N: the number of TXT records on that label.
P: the number of bytes in all the TXT records.
S: the total number of text segments (TXT records can have multiple text segments per record)
UDP is required if N*a + P*b + S*c is more than 512
What are the values of a, b, and c?
(or am I going in the wrong direction?)
In practice, you should not be trying to pre-calculate the exact response size of your TXT records prior to implementing them. There are many variables in play, some of which you do not control. Most admins generalize based off the size of an existing TXT record response that they observe from their authoritative server and call it a day. Since the focus of your question is how to avoid generalizing, this answer is going to focus on why it is difficult to use precise calculations.
(This answer should not be taken as a statement for or against trying to stay inside of 512 bytes, it is a commentary on the approach used to do so.)
Can you write a program or script that will do all of this calculation for you? Sure. Is it a good use of time for the problem you're trying to solve? Probably not. Use an existing TXT record within the zone as your rough sizing guideline, and if growing over 512 bytes is a concern make sure you are familiar with any "include" functionality built into the relevant standard leveraging the TXT records. (SPF, etc.)
historically you get 512 octets of DNS payload, of which 10 octets is a fixed header. you have to make room for the copy of the question section that will be included in the response. that's roughly the question name plus four octets. each TXT RR will use a compression pointer up to the question name, for its owner name. that's two octets. then 10 octets of fixed overhead (ttl, class, type, and rdlen). you'll fit more text into a single really long TXT RR than into multiple discrete TXT RR's. in general you should try entering a bunch of different TXT RRs into one of your zones and then use "dig" to fetch each one and see how long "dig" says the payload is.
the historical 512 number was chosen for IPv4 but was not relaxed for IPv6. in IPv4, the payload plus the worst-case UDP and IP headers would yield a 568 octet IP datagram, which was the lowest allowed minimum reassembly buffer size -- an IPv4 endstation isn't "compliant" if it can't reassemble at least that much, so, noone is allowed to assume that you can reassemble more.
in modern DNS, the buffer size will be negotiated using an OPT RR ("EDNS0") and will usually be 4096. this reflects the much-larger-than-568-octets size that endstations can actually reassemble. obviously EDNS0 buffer sizes larger than your ethernet MTU (or your path MTU if you discover it) will cause IP fragmentation, and that often leads to loss since firewalls don't allow it. when EDNS0 @4K fails, it will often retry at 1460 (to leave room for IP and UDP headers plus your payload and still fit in an ethernet packet), and then retry at 512, and then perhaps retry without EDNS0 (which is also 512). if you depend on EDNS, you will often end up sending TC=1 ("truncation occurred") in which case the requestor will probably retry using TCP, or just fail outright.
what this means is if you depend on more than 512, you'll be using TCP a lot. since your question was about UDP, that likely means you should fit into 512.
If I read RFC1035 right, you have:
So, for your example (where there is only one text segment S per TXT record):
So, we have 12+11+5=28 + answers
TXT records can hold a maximum of 255 bytes of data and UDP packets can be any size. The UDP packet will be fragmented to fit into an IP at 65,507.