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

Comments

@johnthedebs
Copy link

commented May 6, 2015

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 label May 6, 2015

@bnoordhuis

This comment has been minimized.

Copy link
Member

commented May 6, 2015

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

This comment has been minimized.

Copy link
Contributor

commented May 6, 2015

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

This comment has been minimized.

Copy link
Author

commented May 6, 2015

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

@silverwind

This comment has been minimized.

Copy link
Contributor

commented May 6, 2015

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

@johnthedebs

This comment has been minimized.

Copy link
Author

commented May 6, 2015

@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

This comment has been minimized.

Copy link
Contributor

commented May 6, 2015

Right, thanks!

@imyller

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Contributor

commented May 7, 2015

This might be another motivation for #1013

@yorkie

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Contributor

commented May 7, 2015

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

This comment has been minimized.

Copy link
Member

commented May 7, 2015

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

@imyller

This comment has been minimized.

Copy link
Member

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 label Mar 2, 2016

XadillaX added a commit to XadillaX/node that referenced this issue May 20, 2017

dns: fix `resolve` failed starts without network
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

@addaleax addaleax closed this in 2b54147 May 21, 2017

XadillaX added a commit to XadillaX/node that referenced this issue Jul 23, 2017

dns: fix `resolve` failed starts without network
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

dns: fix `resolve` failed starts without network
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 added a commit that referenced this issue Aug 14, 2017

dns: fix `resolve` failed starts without network
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

MylesBorins added a commit that referenced this issue Aug 14, 2017

dns: fix `resolve` failed starts without network
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 added a commit that referenced this issue Aug 14, 2017

dns: fix `resolve` failed starts without network
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 added a commit that referenced this issue Aug 16, 2017

dns: fix `resolve` failed starts without network
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>
@SirR4T SirR4T referenced this issue Aug 30, 2018
4 of 4 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants
You can’t perform that action at this time.