Browse Source

dns.lookup uses cares_wrap::GetAddrInfo

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
c83dda89a4
  1. 8
      doc/api/dns.markdown
  2. 50
      lib/dns.js
  3. 35
      src/cares_wrap.cc

8
doc/api/dns.markdown

@ -1,6 +1,12 @@
## DNS ## 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 Here is an example which resolves `'www.google.com'` then reverse
resolves the IP addresses which are returned. resolves the IP addresses which are returned.

50
lib/dns.js

@ -29,6 +29,12 @@ function errnoException(errorno, syscall) {
// Once all of Node is using this function the ErrnoException from // Once all of Node is using this function the ErrnoException from
// src/node.cc should be removed. // src/node.cc should be removed.
var e = new Error(syscall + ' ' + errorno); 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.errno = e.code = errorno;
e.syscall = syscall; e.syscall = syscall;
return e; return e;
@ -123,46 +129,26 @@ exports.lookup = function(domain, family, callback) {
return {}; return {};
} }
/* TODO function onanswer(addresses) {
if (/\w\.local\.?$/.test(domain)) { if (addresses) {
// ANNOYING: In the case of mDNS domains use NSS in the thread pool. if (family) {
// I wish c-ares had better support. callback(null, addresses[0], family);
process.binding('net').getaddrinfo(domain, 4, function(err, domains4) { } else {
callback(err, domains4[0], 4); callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
}); }
callback.immediately = true;
return {};
} */
function onanswer(status, addresses, familySym) {
if (!status) {
callback(null, addresses[0], symToFamily(familySym));
} else { } else {
callback(errnoException(errno, 'getHostByName')); callback(errnoException(errno, 'getaddrinfo'));
} }
} }
var wrap; var wrap = cares.getaddrinfo(domain, family);
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);
}
});
}
if (!wrap) { if (!wrap) {
throw errnoException(errno, 'getHostByName'); throw errnoException(errno, 'getaddrinfo');
} }
wrap.oncomplete = onanswer;
callback.immediately = true; callback.immediately = true;
return wrap; return wrap;
}; };

35
src/cares_wrap.cc

@ -632,17 +632,20 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
address = res; address = res;
while (address) { while (address) {
assert(address->ai_socktype == SOCK_STREAM); assert(address->ai_socktype == SOCK_STREAM);
assert(address->ai_family == AF_INET || address->ai_family == AF_INET6);
// Juggle pointers // Ignore random ai_family types.
addr = (address->ai_family == AF_INET ? if (address->ai_family == AF_INET || address->ai_family == AF_INET6) {
(char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr : // Juggle pointers
(char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr); addr = (address->ai_family == AF_INET ?
const char* c = uv_inet_ntop(address->ai_family, addr, ip, INET6_ADDRSTRLEN); (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 // Create JavaScript string
Local<String> s = String::New(c); Local<String> s = String::New(c);
results->Set(n, s); results->Set(n, s);
}
// Increment // Increment
n++; n++;
@ -666,9 +669,17 @@ static Handle<Value> GetAddrInfo(const Arguments& args) {
String::Utf8Value hostname(args[0]->ToString()); String::Utf8Value hostname(args[0]->ToString());
int fam = AF_INET; int fam = AF_UNSPEC;
if (args[1]->IsInt32() && args[1]->Int32Value() == 6) { if (args[1]->IsInt32()) {
fam = AF_INET6; switch (args[1]->Int32Value()) {
case 6:
fam = AF_INET6;
break;
case 4:
fam = AF_INET;
break;
}
} }
GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(); GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap();

Loading…
Cancel
Save