[Dnsmasq-discuss] --server=/example/ --server=/example/ behaviour

Petr Menšík pemensik at redhat.com
Fri Apr 16 16:26:09 UTC 2021

Hi all,

I am trying to improve dnsmasq to handle better redirections of some
given domains to multiple servers. Current implementation allows
specifying multiple domains in single --server= statement, but only one
server. It can be specified by multiple --server statements.

But some people would like domain specific forwards to choose outgoing
forwarders in similar way to common forwarders. By common forwarders I
mean multiple --server=<ip> without any domain specification, the same
way /etc/resolv.conf parsing with at least two nameservers works.
Current implementation chooses the best responding server (last_server)
and only sometime tries also other servers.

I would like to implement similar logic not only for global forwarders,
but also for any domain specific forwarders, where multiple forwarders
are configured. Current behavior is to send queries to all
domain-specific forwarders used for the domain. Even if three forwarders
are configured and all are perfectly working, requests would be
forwarded to all of them for every single query. It is bombarding all of
them, but just the first reply would be forwarded back to client and be
used. Is there a good reason for such behaviour? Are multiple servers
for a domain considered exceptional?

--rev-server for example allows only single target IP specified, even if
syntax would allow more easily. In DNS world a zone usually requires at
least two servers handling it.

Current code walks multiple times daemon->servers list. First it finds
longest domain match in search_servers() function.
All servers are checked, when FORWARD_TEST queries were sent or
FORWARD_TIME elapsed since last all servers check, whichever is sooner.
Also on error responses. Then it walks the same list again, starting on
daemon->last_server, sending forwarded queries. Unless
forward->forwardall is set, only last_server is used. For domain
specific forwarders, forwardall is always set.

It seems to me each domain should have at least a structure:
struct server_domain {
  char *domain;
  struct server *last_server;
  time_t forwardtime;
  int forwardcount;
  struct server_domain *next;

Where it could store forwardcount, forwardtime and last_server for each
different domain. I think it would make sense to add struct server
*servers and int flags and iterate only servers for given domain on each
forwarded query. But required changes for that seem to be huge, I failed
to prepare working patch yet. Minimal change would use domain found by
search_servers and just find server_domain structure with matching domain.

What do you think? Do you use multiple servers for custom domains?


Petr Menšík
Software Engineer
Red Hat, http://www.redhat.com/
email: pemensik at redhat.com
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20210416/f4cc0e17/attachment.sig>

More information about the Dnsmasq-discuss mailing list