Score:-1

DNS record with multiple IPs + 512 bytes UDP limit

kr flag

I had a DNS record (ex: test.example.com) pointing to a single IP:

test.example.com IN A 192.0.2.1

Working fine. Now I have +30 IPs answering for it, example:

teste.example.com IN A 192.0.2.1
teste.example.com IN A 192.0.2.2
(...)
teste.example.com IN A 192.0.2.31

And now it's unstable ("can't find host" errors). Using dig I got a warning "Truncated, retrying in TCP mode". After some Google searches, I found out that a multi-IP query must have no more than 512 bytes to guarantee that UDP will be used, and avoid an extra query (or problems with no-tcp dns clients or providers, old dns sw, etc).

So, how can I know how many v4 IPs can I have in a single dns entry to guarantee a maximum of 512 bytes UDP answer?

or

Is it possible to configure ISC Bind to return only one IP in a multi-IP query? I know that the IP can be cycled with rrset-order { order cyclic; };.

Like:

> test.example.com
Server: x.x.x.x
Address: x.x.x.x:53

Name: test.example.com
Address: 192.0.2.6

so, only one of them? Thanks.

Ron Maupin avatar
us flag
You can use TCP for DNS. There is no reason to stick with UDP if you are having problems. _[RFC 7766, DNS Transport over TCP - Implementation Requirements](https://datatracker.ietf.org/doc/html/rfc7766)_ explains it and says: "_This document therefore updates the core DNS protocol specifications such that support for TCP is henceforth a REQUIRED part of a full DNS protocol implementation._"
Arvy avatar
kr flag
Yes, in normal situation, but the affected people in this case are using routers with no TCP DNS support, or buggy ones. I realized this since the affected people are using old routers from a local provider, only wifi/wired. Using 3G/4G they were no affected.
Ron Maupin avatar
us flag
I would suggest that is a problem for the users to correct. For example, if you had a web site that for good reason is HTTPS-only, would you scramble to also use HTTP for users with old browsers unable to correctly use HTTPS? At some point, you must stop supporting outdated applications and technology, and you should never put up with buggy products.
Score:2
cn flag

And now it's unstable ("can't find host" errors)

From where/how?

All properly set up resolvers, as you noticed, will get a Truncated flag on their first query over UDP and then will switch over TCP and everything will be fine.

Of course, you remember that DNS is over UDP AND TCP (contrary to a popular myth) so you need to make sure your authoritative nameservers can be queried over TCP, and all will be fine.

After some Google searches, I found out that a multi-IP query must have no more than 512 bytes to guarantee that UDP will be used

It depends. You can sometimes go over 1000. But most importantly, things fallback to TCP so shouldn't be a problem (just a slight loss in performances, maybe).

and avoid an extra query (or problems with no-tcp dns clients or providers, old dns sw, etc).

"no-tcp dns clients or providers" shouldn't exist as it makes no sense and is against the DNS specifications written... more than 40 years ago! Or do you have specific proofs of those cases?

Don't try to go around things like that. If these pieces of software exist they are broken and will have A TON of other problems, like for DNSSEC secured domains.

So, how can I know how many v4 IPs can I have in a single dns entry to guarantee a maximum of 512 bytes UDP answer?

This is not possible to answer in general (because depends on the name) but most important, it is kind of futile to try optimizing things that way.

Anyway you can do the computation easily:

  • a UDP packet has 8 bytes header before the data (RFC 768)
  • a DNS packet, see RFC 1035, has an header (12 bytes), then the question (variable amount of bytes, see later), then the answer (see later), and we will consider additional and authority section to be empty.

So we are already at 512-8-12 = 492 bytes for DNS question + answer.

In answer, an A record will be name (variable length) + type (2 bytes) + class (2 bytes) + TTL (4 bytes) + length (2 bytes) and then the data. For A the data is 4 bytes (an IPv4 address).

The question is name (variable length) + type (2 bytes) + class (2 bytes).

Names in DNS packets have these two properties:

  • they are encoded as a list of labels prefixed by length
  • there may be compressed so that a given name or part of name appears only once.

So for example example.com is encoded in DNS as 7,e,x,a,m,p,l,e,3,c,o,m,0 where each length is one byte, but if the name is later needed it will be replaced by a pointer using 2 bytes only.

If we take that name:

  • the size of the name part in question will be: 13 bytes, so total size of question: 13 + 2 + 2 = 17
  • in answer, each name can be a pointer of 2 bytes referencing the name in the question, so each record in answer will be in length 2 bytes for name and then the rest above, so 16 bytes.

Hence the full DNS packet will be of size 12 (header) + 17 (question) + x times 16 where x is the number of A records.

So we have to resolve: 512 = 8 + 12 + 17 + 16x for x, which yields x=29 or so. Remember that this is under the best circumstances (no additional/authority records, and name compression used in full) and for a specific name (but if using compression the name appears in full only once in question, so only that size changes).

[Also, by the way, don't be trapped in last century legacy Internet; nowadays IPv6 should be the norm; of course you put even less AAAA record types in a fixed size DNS packet than IPv4 ones :-) ]

Is it possible to configure ISC Bind to return only one IP in a multi-IP query?

I don't think so and if it existed how bind would choose which IP to return? If you are here it is up to you to only list one IP in the zonefile. Or if you are really attached to this idea (but again all the time you loose in this won't prevent other problems because the clients are buggy so you are trying to battle an infinite hill anyway), you may try dnsdist that is kind of a swiss-army knife and allows fine tuning.

PS: also remember that DNS has an extension to allow one party to specify the (UDP) buffer size it can receive. See RFC 6891. A recent dig uses 1232 as default there. You might be interested in general to look at https://kb.isc.org/docs/aa-01219 or the DNS flag day of 2020 at https://dnsflagday.net/2020/ that was exactly about this.

Arvy avatar
kr flag
Thanks for the answer! For some reason, several people are having problems to resolve the 31 IPs DNS answer... I'm right now investigating the DNS packet using WireShark, it's returning 572 bytes...`112402 2022-03-09 18:28:09,664371 8.8.8.8 192.168.0.3 DNS 572 Standard query response 0x0003 A xxxxxxxx A` (...long list of IPs).
Patrick Mevzek avatar
cn flag
31 IPs is certainly not a frequent case, but again, shouldn't be a concern for any normal DNS client. Ask those "several" people what recursive DNS provider they use, if things change by forcing TCP (`+tcp` in `dig`) or by playing with `+bufsize` (see my edited answer at the end about that)
Arvy avatar
kr flag
Yes, I understand your explanation and I can see perfectly what you said in WireShark. I agree about UDP+TCP, but I realized problems in some routers (ex: D-Link 510), even modern ones, that are having problems to resolve that 31 IPs DNS (*note*: internal DNS solvers, proxying). A simple `ping` in Windows fails or pings only sometimes (I agree, non sense)... if I reduce the number of IPs, never fails.
Arvy avatar
kr flag
If I `nslookup` to the router (192.168.0.1), it returns "server failed" for the 31 IP entry. If I change `server 8.8.8.8` works fine. Well, I'll reduce to avoid this, even I don't know why. Thanks for your valuable help.
Patrick Mevzek avatar
cn flag
"If I nslookup to the router (192.168.0.1), it returns "server failed" for the 31 IP entry. If I change server 8.8.8.8 works fine. " I think that shows very well were the problem is... so you can either try to circumvent it (you could even re-architecture your system to not depend on 30+ IP addresses, look at anycast for example) or just explains to people they have broken systems and they should fix it (or use working public resolvers instead of local broken ones)
Arvy avatar
kr flag
Yes, explain to people is impossible, I reduced to 20 IPs and seems to work ok now. Probably I'll create 2 DNS entries, with 15 IPs each, and then "load balance" the entries programatically (since they will be loaded in PHP sites). Thanks!
Patrick Mevzek avatar
cn flag
Race to the bottom is never something I recommend personally. This doesn't help the Internet globally nor those clients in fact, because if they have this problem a lot of other things are probably broken for them or abnormaly slow, etc.
Arvy avatar
kr flag
Agreed, but I have no choice, the affected people are using old routers provided by some big internet providers, so, since I'm in Brazil, we're talking about millions of routers :( My "test.example.com", in the real world, is an audio streaming service for +200,000 users.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.