<div dir="ltr"><div>Hello Everyone,</div><div><br></div><div>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. </div><div><br></div><div>In this case, I expect the a domain name can be resolved correctly by the second DNS server.<br></div><div><br></div><div>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.</div><div><br></div><div><br></div><div>I checked the source code, I think the following part of code is hard to be understood.</div><div><br></div><div>---------------------</div><div>I copied it here from dnsmasq-2.76</div><div><br></div><div>Line 788,function reply_query, in forward.c:</div><div><br></div><div><div>  /* Note: if we send extra options in the EDNS0 header, we can't recreate</div><div>     the query from the reply. */</div><div>  if (RCODE(header) == REFUSED &&</div><div>     <font size="4"> <b><font color="#ff0000"><i>!</i></font></b></font>option_bool(OPT_ORDER) &&</div><div>      forward->forwardall == 0 &&</div><div>      !(forward->flags & FREC_HAS_EXTRADATA))</div><div>    /* for broken servers, attempt to send to another one. */</div><div>    {</div></div><div><br></div><div>The meaning of this part code is, for broken servers, attempt to send to another one, if:</div><div>1. strict order is <b><font color="#ff0000">NOT</font></b> set</div><div>2. REFUSED got from a server</div><div>3. forwardall is 0</div><div>4. some conditions else</div><div><br></div><div>according to my understanding, if the option strict order is <b>set</b>, 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.</div><div><br></div><div>But in this part of code, if the option strict order is <b><font color="#ff0000">NOT</font></b> set and got refused, (also with some other conditions), dnsmasq would try to send to another one. It's different from my understanding.</div><div><br></div><div>--------------------</div><div>Also in the source code of function forward_query, I can see, if option strict order is <b><font color="#ff0000">NOT </font></b>set, forwardall would be set as<b><font color="#ff0000"> 1</font></b>. </div><div><br></div>So the condition 1(strict order is<b><font color="#ff0000"> not </font></b>set) and 3(forwardall is<b><font color="#ff0000"> 0</font></b>) 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.<br clear="all"><div><br></div><div><br></div><div>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.</div><div><br></div><div><br></div><div><div>  /* Note: if we send extra options in the EDNS0 header, we can't recreate</div><div>     the query from the reply. */</div><div>  if (RCODE(header) == REFUSED &&</div><div>     <font size="4"> </font>option_bool(OPT_ORDER) &&</div><div>      forward->forwardall == 0 &&</div><div>      !(forward->flags & FREC_HAS_EXTRADATA))</div><div>    /* for broken servers, attempt to send to another one. */</div><div>    {</div></div><div><br></div><div><br></div><div>I beg your help or comments on this issue.</div><div><br></div><div><br></div>-- <br><div class="gmail_signature"><div>Best Regards and Many Thanks</div>
<div>Bear Mi</div></div>
</div>