Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dns.resolve fails when the io/node process starts without an active network connection #1644

Closed
johnthedebs opened this issue May 6, 2015 · 14 comments
Labels
confirmed-bug Issues with confirmed bugs. dns Issues and PRs related to the dns subsystem.

Comments

@johnthedebs
Copy link

To reproduce:

  1. Disable your Internet connection (this needs to be done first)

  2. Start a io/node repl

  3. Enter the following into the repl and note that it fails with ECONNREFUSED:

    var dns = require("dns");
    dns.resolve("google.com", function(err) { if (err) { console.log(err); } else { console.log("online"); }})

  4. Re-enable your Internet connection

  5. Run dns.resolve("google.com", function(err) { if (err) { console.log(err); } else { console.log("online"); }}) again, and note that it still fails

If the process starts before the Internet connection is disabled, it will work as expected once the connection is re-enabled.

For what it's worth, this bug doesn't affect dns.lookup (which according to the docs is implemented differently than dns.resolve).

@Fishrock123 Fishrock123 added the dns Issues and PRs related to the dns subsystem. label May 6, 2015
@bnoordhuis
Copy link
Member

I speculate that's because c-ares (the C library that powers dns.resolve()) reads /etc/resolv.conf once at start-up. If you start iojs when the network is disabled, /etc/resolv.conf is going to be empty.

I'm not sure if it's fixable. iojs doesn't know when the network comes back up and even if it did, it may not be trivial to reinitialize c-ares.

@silverwind
Copy link
Contributor

I thought that /etc/resolv.conf thing was OS X only (in removes the symlink when network is down). Does Linux/BSD do that too?

@johnthedebs
Copy link
Author

@silverwind Just tested on Ubuntu 14.04 64-bit with the same failure (original test was OS X 10.10.3).

@silverwind
Copy link
Contributor

@johnthedebs What's the content of /etc/resolv.confwhen all interfaces are down? Does that file even exist?

@johnthedebs
Copy link
Author

@silverwind It exists when all interfaces are disconnected, the contents are:

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

@silverwind
Copy link
Contributor

Right, thanks!

@imyller
Copy link
Member

imyller commented May 7, 2015

ares_reinit() has been on c-ares TODO list for a while (c-ares/c-ares@d2f21d3)

ares_reinit()
To allow an app to force a re-read of /etc/resolv.conf etc, pretty much
like the res_init() resolver function offers

@silverwind
Copy link
Contributor

This might be another motivation for #1013

@yorkie
Copy link
Contributor

yorkie commented May 7, 2015

ares_reinit might not address this issue, the problem is when we need to update the servers from resolv.conf file.

@imyller
Copy link
Member

imyller commented May 7, 2015

Yes, someone would have to call ares_reinit and know when to do it. By itself it solves nothing but is a prequisite feature for complete solution.

@yorkie
Copy link
Contributor

yorkie commented May 7, 2015

Yup, without implemented ares_reinit() by current c-ares, we just can use setServers() to update servers for now, so it might be necessary :)

@silverwind
Copy link
Contributor

Yeah, poll /etc/resolv.conf and use setServers if it's empty (Linux) or not there (OSX). I'm pretty sure such a hack wouldn't be accepted into core ;)

@bnoordhuis
Copy link
Member

Correct, because parsing /etc/resolv.conf is not the only thing c-ares does.

@imyller
Copy link
Member

imyller commented May 12, 2015

I just published a package resolvmon to partially address this issue (https://www.npmjs.com/package/resolvmon, https://github.com/imyller/node-resolvmon).

It can be used to automatically monitor /etc/resolv.conf changes and updates Node runtime DNS server configuration accordingly. The package has no dependencies and requires io.js or Node.js 0.12+.

var resolvmon = require('resolvmon');
resolvmon.start(); // start monitoring
resolvmon.update(); // trigger manual update

Some features of resolvmon:

  • Configurable location of resolv.conf (defaults to /etc/resolv.conf)
  • Detect create, delete, modify/append, rename of resolv.conf
  • Allows triggering manual update of DNS configuration with update() function
  • The resolv.conf file does not have to exist at startup (for OSX) (missing file = no servers)
  • All functions can be used synchrononously or asychronously (supports callback fns)
  • resolvmon instance is also EventEmitter (emits any, update, error, stop, start events)

Obviously this does not replace full c-ares resolver configuration during ares_init(), but is helpful when running io.js in some cloud server instances with slow /etc/resolv.conf initialization after boot.

/cc @johnthedebs

@Trott Trott added the confirmed-bug Issues with confirmed bugs. label Mar 2, 2016
XadillaX added a commit to XadillaX/node that referenced this issue May 20, 2017
Fix the bug that you start process without network at first, but it
connected lately, `dns.resolve` will stay failed with ECONNREFUSED
because c-ares servers fallback to 127.0.0.1 at the very beginning.

If c-ares servers "127.0.0.1" is detected and its not set by user self,
and last query is not OK, recreating `ares_channel` operation will be
triggered to reload servers.

Fixes: nodejs#1644
XadillaX added a commit to XadillaX/node that referenced this issue Jul 23, 2017
Fix the bug that you start process without network at first, but it
connected lately, `dns.resolve` will stay failed with ECONNREFUSED
because c-ares servers fallback to 127.0.0.1 at the very beginning.

If c-ares servers "127.0.0.1" is detected and its not set by user self,
and last query is not OK, recreating `ares_channel` operation will be
triggered to reload servers.

Fixes: nodejs#1644
PR-URL: nodejs#13076
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
XadillaX added a commit to XadillaX/node that referenced this issue Aug 10, 2017
Fix the bug that you start process without network at first, but it
connected lately, `dns.resolve` will stay failed with ECONNREFUSED
because c-ares servers fallback to 127.0.0.1 at the very beginning.

If c-ares servers "127.0.0.1" is detected and its not set by user self,
and last query is not OK, recreating `ares_channel` operation will be
triggered to reload servers.

Fixes: nodejs#1644
MylesBorins pushed a commit that referenced this issue Aug 14, 2017
Fix the bug that you start process without network at first, but it
connected lately, `dns.resolve` will stay failed with ECONNREFUSED
because c-ares servers fallback to 127.0.0.1 at the very beginning.

If c-ares servers "127.0.0.1" is detected and its not set by user self,
and last query is not OK, recreating `ares_channel` operation will be
triggered to reload servers.

Fixes: #1644
Backport-PR-URL: #14434
PR-URL: #13076
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
MylesBorins pushed a commit that referenced this issue Aug 14, 2017
Fix the bug that you start process without network at first, but it
connected lately, `dns.resolve` will stay failed with ECONNREFUSED
because c-ares servers fallback to 127.0.0.1 at the very beginning.

If c-ares servers "127.0.0.1" is detected and its not set by user self,
and last query is not OK, recreating `ares_channel` operation will be
triggered to reload servers.

Fixes: #1644
Backport-PR-URL: #14434
PR-URL: #13076
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
MylesBorins pushed a commit that referenced this issue Aug 16, 2017
Fix the bug that you start process without network at first, but it
connected lately, `dns.resolve` will stay failed with ECONNREFUSED
because c-ares servers fallback to 127.0.0.1 at the very beginning.

If c-ares servers "127.0.0.1" is detected and its not set by user self,
and last query is not OK, recreating `ares_channel` operation will be
triggered to reload servers.

Fixes: #1644
Backport-PR-URL: #14434
PR-URL: #13076
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. dns Issues and PRs related to the dns subsystem.
Projects
None yet
7 participants