Bug 3431 - DNS resolution not working on some Windows systems
: DNS resolution not working on some Windows systems
Status: CLOSED FIXED
Product: Logitech Media Server
Classification: Unclassified
Component: Misc
: 6.3.0
: PC Windows XP
: P3 critical (vote)
: ---
Assigned To: Andy Grundman
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2006-05-19 07:23 UTC by Hanno Stock
Modified: 2008-09-15 14:38 UTC (History)
1 user (show)

See Also:
Category: ---


Attachments
send udp to all nameservers (bgsend) (5.12 KB, patch)
2006-05-19 10:45 UTC, Hanno Stock
Details | Diff
recognize nameservice order under win2k/xp (1.14 KB, patch)
2006-05-19 12:47 UTC, Hanno Stock
Details | Diff
recognize nameservice order (right patch) (1.67 KB, patch)
2006-05-19 12:55 UTC, Hanno Stock
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Hanno Stock 2006-05-19 07:23:15 UTC
First a quote from the Net::DNS::Resolver manpage:

"On UNIX systems the 
defaults are read from the following files, in the order indicated:

    /etc/resolv.conf
    $HOME/.resolv.conf
    ./.resolv.conf

[...]
On Windows systems, an attempt is made to determine the system defaults
using the registry.  This is still a work in progress; systems with many
dynamically configured network interfaces may confuse Net::DNS."

I have exactly this problem on my system. All attempts to access any
internet resources from slimserver result in a DNS error.

I was able to solve this by specifying a nameserver explicitely in
Slim::Networking::AsyncHTTP::new():

my $resolver = Net::DNS::Resolver->new(nameservers => [qw(192.168.1.253)]);

I think we should at least have a configuration option for manually
specifying nameservers - which is still not very userfriendly for people
with affected systems.

However before the new AsyncHTTP code in 6.3 was introduced, there was never
a problem with DNS. So maybe there is another solution.

I have put "Severity" to "critical" because I think this problem can
be very annoying to the novice user, if it occurs. It breaks a lot
of functionality.
Comment 1 Andy Grundman 2006-05-19 07:46:23 UTC
Good find, you are right we need to find a way around this.  It used to work because it used the system resolver libraries (which block).  I wonder if any of the Win32 modules can find the current DNS server...
Comment 2 Andy Grundman 2006-05-19 08:25:12 UTC
Upgraded Net::DNS to 0.57 in both 6.3 and 6.5.  Several win32-related fixes were made that should help, especially on XP with DHCP.  If tonight's nightly still has problems, please reopen.

More info: https://rt.cpan.org/Public/Bug/Display.html?id=11931
Comment 3 Hanno Stock 2006-05-19 09:01:04 UTC
I checked out the Subversion changes and the problem still appears on my system.

I also found the problem, causing the DNS resolution to fail.
Net::DNS::Resolver::Base::bgsend() only uses the first DNS server
from the DNS servers list. When a network interface with a DNS server
is not active and it is the first in the list, the DNS resolution
will fail.
I have this situation, since I have VPN interfaces that are not connected
all the time.

In contrast send_tcp() uses all nameservers. This is a bug in Net::DNS, I think.
Comment 4 Andy Grundman 2006-05-19 09:10:12 UTC
Having a primary DNS server that isn't valid is probably a bad idea and certainly can't be a common setup.  Shouldn't your DNS server list change dynamically when you connect to your VPN?  That's how my VPN connections have always worked.

In the RT discussion there's a link to some SpamAssassin code that works around this issue.  I think we can steal some of that code.

Bumping sev down to normal as this won't affect very many people.
Comment 5 Hanno Stock 2006-05-19 10:07:55 UTC
(In reply to comment #4)
> Having a primary DNS server that isn't valid is probably a bad idea and
> certainly can't be a common setup.  Shouldn't your DNS server list change
> dynamically when you connect to your VPN?

It seems to be a problem of how Net::DNS retrieves the server list from the
registry. I have no control over which is the primary DNS server. It just
takes the first DNS server that appears in the registry.
So it even takes DNS servers from interfaces that are down.

> In the RT discussion there's a link to some SpamAssassin code that works around
> this issue.  I think we can steal some of that code.

Will have a look into this.

> Bumping sev down to normal as this won't affect very many people.

Ok. Would have proposed that anyway ;)

Comment 6 Andy Grundman 2006-05-19 10:18:49 UTC
Ah, I misunderstood.  I thought it was pulling them in order but you had an invalid one set as your primary DNS.
Comment 7 Hanno Stock 2006-05-19 10:45:39 UTC
Created attachment 1245 [details]
send udp to all nameservers (bgsend)

This patch changes bgsend in a way that it sends UDP requests to all nameservers that share the same socket type as the first nameserver.

The first answer is taken.

Solves the problem - but not the elegant way.
Comment 8 Andy Grundman 2006-05-19 10:48:55 UTC
Can you post your patch to RT to see what the maintainer thinks?  

My idea is to query all nameservers at startup-time to build a list of valid NS's that can be used for all async queries.
Comment 9 Hanno Stock 2006-05-19 10:59:06 UTC
(In reply to comment #8)
> Can you post your patch to RT to see what the maintainer thinks?  

I am currently looking into a better way to find disabled network devices or
use the TCP linkage information form the registry.
I have a bad feeling about the patch because it fixes a Win32-issue in
platform independent code. However I will ask at RT what they think about it.

> My idea is to query all nameservers at startup-time to build a list of valid
> NS's that can be used for all async queries.

I think that is the way the ppl at SpamAssassin do it. Seems a better approach to
me.

Comment 10 Hanno Stock 2006-05-19 12:47:55 UTC
Created attachment 1246 [details]
recognize nameservice order under win2k/xp

This patch extracts the information about DNS search order from the
registry and sorts the nameservers appropriately.

AFAIR there is a UI option in Win2k/XP where to specify the global
search order (not per interface). But I can't find it right away.
Most of the time it should be right automatically.

Will submit this patch to RT discussion, also.
Comment 11 Hanno Stock 2006-05-19 12:52:46 UTC
Comment on attachment 1246 [details]
recognize nameservice order under win2k/xp

Index: G:/Programme/SlimServer/server/CPAN/Net/DNS/Resolver/Win32.pm
===================================================================
--- G:/Programme/SlimServer/server/CPAN/Net/DNS/Resolver/Win32.pm	(revision 7602)
+++ G:/Programme/SlimServer/server/CPAN/Net/DNS/Resolver/Win32.pm	(revision 7605)
@@ -14,10 +14,15 @@
 use Win32::Registry;
 
 sub init {
+  
 	my ($class) = @_;
 	
 	my $defaults = $class->defaults;
 	
+	# my $self = bless({ %{$class->defaults} }, $class);
+	# 
+	# $self->{'debug'} = 1;
+	
 	my ($resobj, %keys);
 
 	my $root = 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters';
@@ -83,13 +88,33 @@
 #	}
 
 
+  my $bind_linkage;
+  my @sorted_interfaces;
+  print ";; DNS: Getting sorted interface list\n" if $self->{'debug'};
+  $main::HKEY_LOCAL_MACHINE->Open('SYSTEM\CurrentControlSet\Services\Tcpip\Linkage',
+   $bind_linkage);
+  if($bind_linkage){
+    my $bind_linkage_list;
+    my $type;
+    $bind_linkage->QueryValueEx('Bind', $type, $bind_linkage_list);
+    if($bind_linkage_list){
+      @sorted_interfaces = split(m/[^\w{}\\-]+/s, $bind_linkage_list);
+    }
+    foreach my $interface (@sorted_interfaces){
+      $interface =~ s/^\\device\\//i;
+      print ";; DNS:Interface: $interface\n" if $self->{'debug'};
+    }
+  }
 
-
 	my $interfaces;
 	$resobj->Open("Interfaces", $interfaces);
 	if ($interfaces) {
 	    my @ifacelist;
-	    $interfaces->GetKeys(\@ifacelist);
+	    if(@sorted_interfaces){
+	       @ifacelist = @sorted_interfaces;
+	    }else{
+         $interfaces->GetKeys(\@ifacelist);
+      }
 	    foreach my $iface (@ifacelist) {
 		my $regiface;
 		$interfaces->Open($iface, $regiface);
Comment 12 Hanno Stock 2006-05-19 12:55:45 UTC
Created attachment 1247 [details]
recognize nameservice order (right patch)

sorry, I submitted the wrong patch. Was also a bit confused about the "edit attachment as comment" option. Sorry about the mess - here is the right patch.
Comment 13 Andy Grundman 2006-05-19 14:43:22 UTC
I haven't tested your patch, but I manually added 3 nameservers to my main interface, and they show up in the registry as a comma-separated list at Tcpip/Parameters/Interfaces/$GUID/NameServer.  I have XP SP2 by the way.

All 3 servers are also found by Net::DNS::Resolver::Win32 and are in the correct order.  So that brings us back to the problem that bgsend only uses the first one.
Comment 14 Andy Grundman 2006-05-19 15:40:54 UTC
I've committed a patch that checks for a working nameserver at startup.  Please test.
Comment 16 Hanno Stock 2006-05-20 06:50:33 UTC
(In reply to comment #13) 
> All 3 servers are also found by Net::DNS::Resolver::Win32 and are in the
> correct order.

Yes, the order is correct, when you use multiple dns servers on ONE interface,
however as windows stores the nameservers per interface, the current code
just takes the nameservers from MULTIPLE interfaces in the order, the interfaces
appear in the registry. (sorted by GUID)
The patch also recognizes the order of the tcpip\Linkage\Bind entries that specifies
the order in which several interfaces should be tried.

Your change looks good - I will give it a try. But I think, the nameservice order
patch should be applied, also. As the user can specify a nameservice order
on other operating systems, this should also be the case for Win32.
But maybe this will make it into CPAN.
Comment 17 Hanno Stock 2006-05-20 07:12:08 UTC
It works with your patch. However without the "nameservice order patch" the server takes longer to start - because of the first nameserver timing out.

I just saw that the line

	# my $self = bless({ %{$class->defaults} }, $class);

in my patch should not be commented out. The variable $self will be missing later.
Comment 18 Andy Grundman 2006-05-22 12:42:17 UTC
Marking closed.  When you get your patch applied upstream (Net::DNS), remind me, and we'll use it.
Comment 19 Hanno Stock 2006-05-22 14:42:28 UTC
(In reply to comment #18)
> Marking closed.  When you get your patch applied upstream (Net::DNS), remind
> me, and we'll use it.

According to Olaf Kolkman, the Patch is now applied to the trunk (Net::DNS).

I have also sent a patch to the author of Win32::IPHelper with the necessary
function to get the Dns Servers directly from the windows api - which may be
a much better approach.

So keep watching Net::DNS, as it might use it. (Usage of GetNetworkParams() was discussed on RT/CPAN)