[CSHARP-2518] Dns resolver only uses first DNS server. Created: 14/Feb/19  Updated: 28/Oct/23  Resolved: 19/Apr/21

Status: Closed
Project: C# Driver
Component/s: Connectivity
Affects Version/s: 2.7.3
Fix Version/s: 2.10.3

Type: New Feature Priority: Major - P3
Reporter: Bas Assignee: Robert Stam
Resolution: Fixed Votes: 0
Labels: dns
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

all


Issue Links:
Related
is related to CSHARP-2968 Exception occurs when using mongodb+s... Closed
is related to PYTHON-3630 SRV resolution uses only the first na... Closed

 Description   

when connecting, the c# client uses the System.DnsClient.LookupClient to resolve srv records.

When you have multiple dns servers configured, it only uses the first.

This is the default behavior of the LookupClient.

Correct way to do it would be something like:

var lookupClient = new LookupClient();
 
foreach (var dnsserver in lookupClient.NameServers)
{
    var response = lookupClient.Query("_mongodb._tcp." + host, QueryType.SRV, QueryClass.IN);
    if (!response.HasError)
        break;
}



 Comments   
Comment by Robert Stam [ 19/Apr/21 ]

CSHARP-2968 is linked to this ticket because it was while fixing that ticket that we upgraded our dependency on DnsClient from 1.2.0 to 1.3.1.

Comment by Robert Stam [ 19/Apr/21 ]

The version of DnsClient we depend on was upgraded on the following dates:

2021-02-18 Upgraded from 1.3.. to 1.4

2020-04-03 Upgraded from 1.2.0 to 1.3.1 as part of work on CSHARP-2968

Since CSHARP-2968 has a fix version of 2.10.3 I am going to give this ticket the same fix version.

Comment by Robert Stam [ 07/Apr/21 ]

DnsClient issue 64 states that starting with version 1.3 the LookupClient.Query method will try all available DNS servers.

Looking at the DnsClient source code confirms this:

https://github.com/MichaCo/DnsClient.NET/blob/dev/src/DnsClient/LookupClient.cs#L764

We use DnsClient version1.4, so the version we use includes this feature.

I think we can close this as Fixed (i.e. the issue was fixed by upgrading to a newer version of DnsClient).

Comment by Michael Conrad [ 14/Mar/20 ]

I decided to add another feature to DnsClient which will allow LookupClient to query other configured servers in case the response doesn't have an answer for the question, if there are more than one servers resolved/configured.

See https://github.com/MichaCo/DnsClient.NET/issues/64

Not sure if this will resolve this issue, but maybe you could give it a try and let me know

Comment by Michael Conrad [ 12/Mar/20 ]

Hi, 

Although that issue is already a bit old, I'd still like to clarify a couple things.

If multiple servers are configured in DnsClient it will try to get a response trying the servers in random order (in 1.3.0 the order will be "more" random btw. ^^), unless the client is configured to always use the servers in order.

In general, the assumption of the client is that all your DNS servers return the same result. And if the server returns a valid response, there is no need to spam the network with more requests.

If the response does have an error code though, it WILL ask every server until it gets a response without an error code or runs out of servers.
Possible error codes are here: https://tools.ietf.org/html/rfc6895#section-2.3

I'm not sure @Bas what error you exactly got back from the client, "could not resolve host" is not an error coming from LookupClient - that text doesn't exist in my source at least.

Version 1.3.0 will have a little bit better error handling and also some logging feature. So, if you still have issues with that, try that version and post the Trace outputs, that could help.

But, in general, the safest way would be to only use the DNS server you want to use instead of having DnsClient guess what it should use to resolve questions.
When instantiating LookupClient without any specific servers, it will try to iterate all network adapters to find any DNS servers. 

You can pass one or more NameServers when instantiating LookupClient, that would be the safest way... As far as I can tell that's not an option provided by the driver though.

 Also, feel free to suggest changes/improvements on the DnsClient github repo

Comment by Robert Stam [ 05/Mar/19 ]

I'm a little surprised that DnsClient doesn't handle this scenario correctly.

I've changed the status of the ticket from Investigating to Open so that it can be scheduled for a future release.

Comment by Robert Stam [ 05/Mar/19 ]

Thanks for the additional information on why different name servers could legitimately return different responses. That is very helpful.

Regarding DnsClient trying the name servers one by one in order, that is apparently the actual implementation when LookupClient UseRandomNameServer is true (so not actually so random after all). That would explain the behavior you are seeing when calling Query 3 times in a row.

 

Comment by Bas [ 05/Mar/19 ]

no i got an 'could not resolve host' error from the lookupclient. It is a normal response, but without an ip adres..

Calling it again gave me a response, after investigating i noticed that the first response contained the used dns server. It was my primary, the second response had my second dns server.
Calling it 3 times resulted in 1st, 2nd, and 1st again.. and so on..

I'm confused, if one name server returns 'not found' wouldn't the next name server return the same result? Are the name servers misconfigured?

no, if you use vpn, and only route specific routes trought the vpn, you need to be able to resolve both on vpn (with their local dns server) and the internet (with your own dns server)

In cases like that you have 2 active dns servers. But there are other scenario's. The whole reason you can (and most of use do) configure more then 1 dns server is for cases like this, but also, because dns servers don't actively query the internet. They know only their neighbors.

See also these links:
https://superuser.com/questions/187046/why-does-ipconfig-show-multiple-dns-servers
https://www.quora.com/Why-are-there-two-DNS-servers-primary-and-secondary

 

Comment by Robert Stam [ 05/Mar/19 ]

Thanks for the additional information in your edited changes to your previous comment.

I'm confused, if one name server returns 'not found' wouldn't the next name server return the same result? Are the name servers misconfigured?

Comment by Robert Stam [ 05/Mar/19 ]

So what problem exactly did you encounter that you are attempting to address?

Did you get an exception? Do you have a stack trace?

Comment by Bas [ 05/Mar/19 ]

did you try it? cause I did..

 

Also the problem is not with retrying, it got a result back from the first nameserver. The problem is that the first nameserver returns a 'not found' back.

Any networking protocol (ping in example) then tries the next nameserver.. Mongo doesn't.

Comment by Robert Stam [ 05/Mar/19 ]

I don't think DnsClient works the way you think it does.

As far as I can tell by looking at the source code the implementation of Query already has retry logic and will attempt to use all configured name servers.

Comment by Bas [ 05/Mar/19 ]

that's how the lookup client works.. you should dive into it..

the first dns request you do, goes to your first dns server, if i then do the command in the loop again (same command, same parameters) it resolves using the second dns server.
Do it again, it tries the first again. (if you have 2; if you have 3, it goes to the 3th)

I itterate the list just to make sure i query all the dns servers, and no, i don't use the value

Comment by Ian Whalen (Inactive) [ 25/Feb/19 ]

basiep: your sample for-loop doesn't actually use dnsserver. Did you intend something else?

Comment by Jeffrey Yemin [ 15/Feb/19 ]

But please note that we are currently changing this code pretty radically in scope of CSHARP-2430, so it may be best to hold off for a bit.

Comment by Jeffrey Yemin [ 15/Feb/19 ]

Hi basiep,

 

Thanks for volunteering to submit a pull request.  Instructions for creating one can be found at https://github.com/mongodb/mongo-csharp-driver/blob/master/CONTRIBUTING.md

 

Regards,
Jeff

Comment by Bas [ 15/Feb/19 ]

Anyone even active here?

I can create a pull-request if you like?

Comment by Bas [ 14/Feb/19 ]

is there a way to create a pullrequest

Generated at Wed Feb 07 21:42:47 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.