dns.lookup uses cares_wrap::GetAddrInfo
authorRyan Dahl <ry@tinyclouds.org>
Fri, 21 Oct 2011 00:52:50 +0000 (17:52 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Fri, 21 Oct 2011 01:03:02 +0000 (18:03 -0700)
doc/api/dns.markdown
lib/dns.js
src/cares_wrap.cc

index 9212cc051d38879dd21468934fe29be281135f4c..caca9e4826c8c860a9af56b633e49945597acce8 100644 (file)
@@ -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.
index caaf50d7894164dd2f11c6464b0f28f86f74ee31..c149646981eee12305063552ca799e95d01e2725 100644 (file)
@@ -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'
+  }
+
   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;
 };
index 88c9d4137ac8bb06ac7f50e0802c119a06e7b41c..6c36c780c95456c080297e29de92a58afcd89eb1 100644 (file)
@@ -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();