linux dnsmasq: how do I increase the ttl?

5

Is it possible to dictate the TTL of resolved entries? In other words, is it possible to override the received TTL for resolved entries and make those higher?

Reason: I find that dnsmasq tries to resolve www.google.com too often for my taste.

jldupont

Posted 2009-10-16T16:46:35.153

Reputation: 5 524

Answers

7

I don't think you can, not easily. The TTL is set by Google's nameservers and they like it low for loadbalancing purposes.

It's possible that increasing the cache size could help, but for super-short TTLs like Google's it probably won't.

Unofficially, there are a couple of patches to provide a TTL-override functionality. I found these on the dnsmasq-discuss mailing list, so if you feel like rolling your own, try them out (you might check the mailing list archives for patches against more recent versions):

quack quixote

Posted 2009-10-16T16:46:35.153

Reputation: 37 382

0

You can actually bypass the 3600 second --min-cache-ttl check by exploiting an integer overflow bug in the dnsmasq C source code, without any need for recompiling. Here is a value which works:

Via CLI: --min-cache-ttl=6442450943

Via dnsmasq.conf: min-cache-ttl=6442450943

Why does this work? Well, the dnsmasq C code specifies a signed integer value constant of 3600 seconds, which is compared and checked versus what the user specifies as an override value. If the value is greater than 3600, then the user input will be disregarded and the constant 3600 will be used instead. This override value is also a signed int, but a few lines later in the code the input ttl value is cast to an unsigned long int when initializing the daemon.

At first glance, you might wonder whe we don't just set the value to be -2 billion in the input or config file. Well, there is an initial dnsmasq input check that will abort early and terminate. However, if we wrap the integer over +4 billion, we will start back at zero. Add another +2 billion + 1 to that and we can wrap back to an effective negative number while still bypassing the initial check.

So, why does this work? Because signed integer ranges go from roughly -2 billion to +2 billion, while unsigned integers range from 0 to +4 billion. We need to get the value to wrap around at the roughly +2 billion mark to be interpreted as a negative value by the dnsmasq check following input parsing. In essence, the check for ttl > 3600 will pass because the value is interpreted negatively as -2 billion. -2 billion is certainly < 3600. But when the second part of the code goes to convert the -2 billion, it will end up converting our input ttl into the equivalent of roughly 2^31 + 1 (unsigned), instead of -2^31 + 1 (signed).

Of course, you can only specify really large ttl values this way, and this may not be useful to anyone because such ttl values are not very reasonable at all. But it is a neat trick (dnsmasq bug). Hope this helps someone even if it is only useful for debugging or messing around as a temporary solution. Feel free to comment if this does or doesn't work for your situation. Enjoy! :)

25931858

Posted 2009-10-16T16:46:35.153

Reputation: 1