Skip to content

Instantly share code, notes, and snippets.

@commadelimited
Last active December 16, 2015 03:40
Show Gist options
  • Save commadelimited/5a564b1fa1bec2b44540 to your computer and use it in GitHub Desktop.
Save commadelimited/5a564b1fa1bec2b44540 to your computer and use it in GitHub Desktop.
Node.js dns.resolve "bug"?

I'm pulling company data from a file server, simon.int (dataDomain). While connected to our network via ethernet cable, or our internal wireless network I can access the file server via both browser, and via Node.js dns.resolve. If I'm outside our network I can't connect via either browser or Node's dns.resolve method (as expected). The problem arises when I connect to our internal network via VPN. I can open simon.int in a browser, I can ping it, etc. yet dns.resolve returns an error when trying to connect to it.

I feel that this is a bug, but I can't find documentation of any sort of expectation of how it should work. I'm trying to determine whether I should report it as a bug, or if my expectation of it is incorrect. I ended up getting around it by making a jQuery AJAX HEAD request just to see if the server was available or not (works great).

I'd love input on this subject, or a pointer in the right direction.

A fellow developer suggested that perhaps it amounted to the user that Node was running as vs "me" accessing simon.int via ping or the browser.

FYI my version of Node:

$ node --version
v0.10.26
publicMethods.checkConnection = function(success, failure, bypass) {
/*
Checks to make sure application has an active connection
to the domain hosting the data file
*/
var dataDomain = 'simon.int';
$.ajax('http://' + dataDomain, {type: 'HEAD'})
.done(function(d){
success();
})
.fail(function(e){
if (publicMethods.checkExistingDataFile()) {
bypass();
} else {
failure();
}
});
// the code below is the desired implementation but for some reason
// Node.js' dns.resolve method fails when connecting to simon.int
// Is it our implementation or a bug in Node? Either way, good old jQuery
// saves the day. Would be nice to revert to this method at some point
// in the future.
// var dns = require("dns");
// dns.resolve(dataDomain, function(error, addr){
// if (error) {
// if (publicMethods.checkExistingDataFile()) {
// bypass();
// } else {
// failure();
// }
// } else {
// success();
// }
// });
};
@commadelimited
Copy link
Author

FYI, this is on OSX Mavericks.

@commadelimited
Copy link
Author

I've confirmed that this appears to be a Node DNS issue. Using the following code to test:

var dataDomain = 'simon.int',
    dns = require("dns");

dns.resolve(dataDomain, function(error, addr){
    console.log(addr);
    console.log(error);
});

I did the following:

  • Connected to our internal wireless, ran the command:
[ '10.0.23.180' ]
null
  • Connected to our external wireless (no connection to internal networks)
undefined
{ [Error: queryA ENOTFOUND] code: 'ENOTFOUND', errno: 'ENOTFOUND', syscall: 'queryA' }
  • Connected to our VPN
undefined
{ [Error: queryA ENOTFOUND] code: 'ENOTFOUND', errno: 'ENOTFOUND', syscall: 'queryA' }

As a control I also took the same steps using Python as a control subject. I used the following code:

import socket
socket.getaddrinfo('simon.int', socket.AF_INET)

Then I did the following:

I did the following:

  • Connected to our internal wireless, ran the command:
[(2, 2, 17, '', ('10.0.23.180', 2)), (2, 1, 6, '', ('10.0.23.180', 2))]
  • Connected to our external wireless (no connection to internal networks)
gaierror                                  Traceback (most recent call last)
<ipython-input-4-13aab12af869> in <module>()
----> 1 socket.getaddrinfo('simon.int', socket.AF_INET)

gaierror: [Errno 8] nodename nor servname provided, or not known
  • Connected to our VPN
[(2, 2, 17, '', ('10.0.23.180', 2)), (2, 1, 6, '', ('10.0.23.180', 2))]

@commadelimited
Copy link
Author

FYI. It turns out that I should have been using dns.lookup instead of dns.resolve.

@jorendorff
Copy link

Hmm. Nothing in the docs really explains what's going on here. Still curious, though not quite curious enough to pursue. :)

@jorendorff
Copy link

The docs say: “All methods in the dns module use C-Ares except for dns.lookup which uses getaddrinfo(3) in a thread pool.”

I wonder, though, why C-Ares is not working properly here. If your computer changes networks, it seems to me caches should be flushed, and subsequent DNS requests would go to the new DNS server. ...Unless DNS isn’t expected to work when you’re connected to a VPN?

@jorendorff
Copy link

I suspect this is a bug.

C-Ares has to query Windows to ask “What DNS server should I use?” which most likely ends up here: https://github.com/bagder/c-ares/blob/master/ares_init.c#L914

Maybe it's not correctly interpreting the result when VPN is enabled, and connecting to the wrong DNS server as a result. Wireshark would tell the story, I bet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment