[Dnsmasq-discuss] [dnsmasq][dns query]dns query failed if the first server replis REFUSE

Baptiste Jonglez baptiste at bitsofnetworks.org
Sun May 7 18:23:19 BST 2017


Hi,

On Tue, Apr 25, 2017 at 12:13:40PM +0800, Mi Bear wrote:
> Hello Everyone,
> 
> I found an issue about DNS query. In my test scenario, there are two DNS
> servers, and the first one will always return REFUSE, and the second one
> can work properly. And the strict order option is on.
> 
> In this case, I expect the a domain name can be resolved correctly by the
> second DNS server.
> 
> But I saw a DNS query packet was sent to the first server, and received a
> REFUSE from it, and I got REFUSED as the the final result at the LAN side
> PC. I did not see the DNS query packet sent to the second DNS server.

You're right, it's a bug, introduced in 2.76.  It has been fixed in
v2.77test2, but unfortunately the final version of 2.77 has apparently not
been released yet.

More details here: http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=68f6312d4bae30b78daafcd6f51dc441b8685b1e

> 
> I checked the source code, I think the following part of code is hard to be
> understood.
> 
> ---------------------
> I copied it here from dnsmasq-2.76
> 
> Line 788,function reply_query, in forward.c:
> 
>   /* Note: if we send extra options in the EDNS0 header, we can't recreate
>      the query from the reply. */
>   if (RCODE(header) == REFUSED &&
>       *!*option_bool(OPT_ORDER) &&
>       forward->forwardall == 0 &&
>       !(forward->flags & FREC_HAS_EXTRADATA))
>     /* for broken servers, attempt to send to another one. */
>     {
> 
> The meaning of this part code is, for broken servers, attempt to send to
> another one, if:
> 1. strict order is *NOT* set
> 2. REFUSED got from a server
> 3. forwardall is 0
> 4. some conditions else
> 
> according to my understanding, if the option strict order is *set*, I think
> dnsmasq will forward the DNS query packet to DNS servers one by one in the
> list. If the first refused the query, dnsmasq should forward the query to
> the second one.
> 
> But in this part of code, if the option strict order is *NOT* set and got
> refused, (also with some other conditions), dnsmasq would try to send to
> another one. It's different from my understanding.
> 
> --------------------
> Also in the source code of function forward_query, I can see, if option
> strict order is *NOT *set, forwardall would be set as* 1*.
> 
> So the condition 1(strict order is* not *set) and 3(forwardall is* 0*) in
> function reply_query would never be matched together, and no dns query
> would be sent to the second DNS server in my test case, just as what I saw.
> 
> 
> I think the "!" in the condition 1 in function reply_query should be
> removed as below. It's more reasonable. I tested the modified source code,
> and it worked fine in my test case.
> 
> 
>   /* Note: if we send extra options in the EDNS0 header, we can't recreate
>      the query from the reply. */
>   if (RCODE(header) == REFUSED &&
>       option_bool(OPT_ORDER) &&
>       forward->forwardall == 0 &&
>       !(forward->flags & FREC_HAS_EXTRADATA))
>     /* for broken servers, attempt to send to another one. */
>     {
> 
> 
> I beg your help or comments on this issue.

> _______________________________________________
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss at lists.thekelleys.org.uk
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20170507/24369cc9/attachment.sig>


More information about the Dnsmasq-discuss mailing list