Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

dns.lookup uses cares_wrap::GetAddrInfo

  • Loading branch information...
commit c83dda89a4bc12925e2dd83db9ef978fe4efae12 1 parent fb3cccc
@ry ry authored
Showing with 48 additions and 45 deletions.
  1. +7 −1 doc/api/dns.markdown
  2. +18 −32 lib/dns.js
  3. +23 −12 src/cares_wrap.cc
View
8 doc/api/dns.markdown
@@ -1,6 +1,12 @@
## DNS
-Use `require('dns')` to access this module.
+Use `require('dns')` to access this module. All methods in the dns module
+use C-Ares except for `dns.lookup` which uses `getaddrinfo(3)` in a thread
+pool. C-Ares is much faster than `getaddrinfo` but the system resolver is
+more constant with how other programs operate. When a user does
+`net.connect(80, 'google.com')` or `http.get({ host: 'google.com' })` the
+`dns.lookup` method is used. Users who need to do a large number of look ups
+quickly should use the methods that go through C-Ares.
Here is an example which resolves `'www.google.com'` then reverse
resolves the IP addresses which are returned.
View
50 lib/dns.js
@@ -29,6 +29,12 @@ function errnoException(errorno, syscall) {
// Once all of Node is using this function the ErrnoException from
// src/node.cc should be removed.
var e = new Error(syscall + ' ' + errorno);
+
+ // For backwards compatibility. libuv returns ENOENT on NXDOMAIN.
+ if (errorno == 'ENOENT') {
+ errorno = 'EBADNAME'
@koichik Owner
koichik added a note

'ENOTFOUND'?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
e.errno = e.code = errorno;
e.syscall = syscall;
return e;
@@ -123,46 +129,26 @@ exports.lookup = function(domain, family, callback) {
return {};
}
- /* TODO
- if (/\w\.local\.?$/.test(domain)) {
- // ANNOYING: In the case of mDNS domains use NSS in the thread pool.
- // I wish c-ares had better support.
- process.binding('net').getaddrinfo(domain, 4, function(err, domains4) {
- callback(err, domains4[0], 4);
- });
- callback.immediately = true;
- return {};
- } */
-
- function onanswer(status, addresses, familySym) {
- if (!status) {
- callback(null, addresses[0], symToFamily(familySym));
+ function onanswer(addresses) {
+ if (addresses) {
+ if (family) {
+ callback(null, addresses[0], family);
+ } else {
+ callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
+ }
} else {
- callback(errnoException(errno, 'getHostByName'));
+ callback(errnoException(errno, 'getaddrinfo'));
}
}
- var wrap;
-
- if (family) {
- // resolve names for explicit address family
- var af = familyToSym(family);
- wrap = cares.getHostByName(domain, af, onanswer);
- } else {
- // first resolve names for v4 and if that fails, try v6
- wrap = cares.getHostByName(domain, cares.AF_INET, function(err, domains4) {
- if (domains4 && domains4.length) {
- callback(null, domains4[0], 4);
- } else {
- cares.getHostByName(domain, cares.AF_INET6, onanswer);
- }
- });
- }
+ var wrap = cares.getaddrinfo(domain, family);
if (!wrap) {
- throw errnoException(errno, 'getHostByName');
+ throw errnoException(errno, 'getaddrinfo');
}
+ wrap.oncomplete = onanswer;
+
callback.immediately = true;
return wrap;
};
View
35 src/cares_wrap.cc
@@ -632,17 +632,20 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
address = res;
while (address) {
assert(address->ai_socktype == SOCK_STREAM);
- assert(address->ai_family == AF_INET || address->ai_family == AF_INET6);
- // Juggle pointers
- addr = (address->ai_family == AF_INET ?
- (char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr :
- (char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr);
- const char* c = uv_inet_ntop(address->ai_family, addr, ip, INET6_ADDRSTRLEN);
+ // Ignore random ai_family types.
+ if (address->ai_family == AF_INET || address->ai_family == AF_INET6) {
+ // Juggle pointers
+ addr = (address->ai_family == AF_INET ?
+ (char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr :
+ (char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr);
+ const char* c = uv_inet_ntop(address->ai_family, addr, ip,
+ INET6_ADDRSTRLEN);
- // Create JavaScript string
- Local<String> s = String::New(c);
- results->Set(n, s);
+ // Create JavaScript string
+ Local<String> s = String::New(c);
+ results->Set(n, s);
+ }
// Increment
n++;
@@ -666,9 +669,17 @@ static Handle<Value> GetAddrInfo(const Arguments& args) {
String::Utf8Value hostname(args[0]->ToString());
- int fam = AF_INET;
- if (args[1]->IsInt32() && args[1]->Int32Value() == 6) {
- fam = AF_INET6;
+ int fam = AF_UNSPEC;
+ if (args[1]->IsInt32()) {
+ switch (args[1]->Int32Value()) {
+ case 6:
+ fam = AF_INET6;
+ break;
+
+ case 4:
+ fam = AF_INET;
+ break;
+ }
}
GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap();

3 comments on commit c83dda8

@koichik
Owner

@ry - This commit breaks test/simple/test-dgram-pingpong.js in my environment (Ubuntu).

...
client got: PONG from 127.0.0.1:20990
client has closed, closing server

dgram.js:179
      var req = self._handle.send(buffer, offset, length, port, ip);
                             ^
TypeError: Cannot call method 'send' of null
    at dgram.js:179:30
    at asyncCallback (dns.js:84:16)
    at Object.onanswer [as oncomplete] (dns.js:135:9)
@ry

@koichik thanks for pointing that out. It seems there was a race condition in test-dgram-pingpong. Fixed in fafb584.

@koichik
Owner

@ry - Confirmed, test-dgram-pingpong has succeeded.
But test-http-dns-fail failed.

~/git/joyent/node$ ./node test/simple/test-http-dns-fail
getaddrinfo ENOENT

node.js:202
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
AssertionError: "EBADNAME" === "ENOTFOUND"
    at ClientRequest.<anonymous> (/home/koichik/git/joyent/node/test/simple/test-http-dns-fail.js:48:12)
    at ClientRequest.emit (events.js:67:17)
    at Socket.<anonymous> (http.js:1106:11)
    at Socket.emit (events.js:67:17)
    at Array.<anonymous> (net.js:518:16)
    at EventEmitter._tickCallback (node.js:194:26)
Please sign in to comment.
Something went wrong with that request. Please try again.