|
|
@ -91,6 +91,40 @@ var channel = new dns.Channel({SOCK_STATE_CB: function(socket, read, write) { |
|
|
|
updateTimer(); |
|
|
|
}}); |
|
|
|
|
|
|
|
// c-ares invokes a callback either synchronously or asynchronously,
|
|
|
|
// but the dns API should always invoke a callback asynchronously.
|
|
|
|
//
|
|
|
|
// This function makes sure that the callback is invoked asynchronously.
|
|
|
|
// It returns a function that invokes the callback within nextTick().
|
|
|
|
//
|
|
|
|
// To avoid invoking unnecessary nextTick(), `immediately` property of
|
|
|
|
// returned function should be set to true after c-ares returned.
|
|
|
|
//
|
|
|
|
// Usage:
|
|
|
|
//
|
|
|
|
// function someAPI(callback) {
|
|
|
|
// callback = makeAsync(callback);
|
|
|
|
// channel.someAPI(..., callback);
|
|
|
|
// callback.immediately = true;
|
|
|
|
// }
|
|
|
|
function makeAsync(callback) { |
|
|
|
if (typeof callback !== 'function') { |
|
|
|
return callback; |
|
|
|
} |
|
|
|
return function asyncCallback() { |
|
|
|
if (asyncCallback.immediately) { |
|
|
|
// The API already returned, we can invoke the callback immediately.
|
|
|
|
callback.apply(null, arguments); |
|
|
|
} else { |
|
|
|
var args = arguments; |
|
|
|
process.nextTick(function() { |
|
|
|
callback.apply(null, args); |
|
|
|
}); |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
exports.resolve = function(domain, type_, callback_) { |
|
|
|
var type, callback; |
|
|
|
if (typeof(type_) == 'string') { |
|
|
@ -121,13 +155,17 @@ function familyToSym(family) { |
|
|
|
|
|
|
|
exports.getHostByName = function(domain, family/*=4*/, callback) { |
|
|
|
if (typeof family === 'function') { callback = family; family = null; } |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.getHostByName(domain, familyToSym(family), callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.getHostByAddr = function(address, family/*=4*/, callback) { |
|
|
|
if (typeof family === 'function') { callback = family; family = null; } |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.getHostByAddr(address, familyToSym(family), callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -148,6 +186,7 @@ exports.lookup = function(domain, family, callback) { |
|
|
|
throw new Error('invalid argument: "family" must be 4 or 6'); |
|
|
|
} |
|
|
|
} |
|
|
|
callback = makeAsync(callback); |
|
|
|
|
|
|
|
if (!domain) { |
|
|
|
callback(null, null, family === 6 ? 6 : 4); |
|
|
@ -166,6 +205,7 @@ exports.lookup = function(domain, family, callback) { |
|
|
|
process.binding('net').getaddrinfo(domain, 4, function(err, domains4) { |
|
|
|
callback(err, domains4[0], 4); |
|
|
|
}); |
|
|
|
callback.immediately = true; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
@ -183,6 +223,7 @@ exports.lookup = function(domain, family, callback) { |
|
|
|
callback(err, []); |
|
|
|
} |
|
|
|
}); |
|
|
|
callback.immediately = true; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
@ -200,46 +241,63 @@ exports.lookup = function(domain, family, callback) { |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.resolve4 = function(domain, callback) { |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.query(domain, dns.A, callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.resolve6 = function(domain, callback) { |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.query(domain, dns.AAAA, callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.resolveMx = function(domain, callback) { |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.query(domain, dns.MX, callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.resolveTxt = function(domain, callback) { |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.query(domain, dns.TXT, callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.resolveSrv = function(domain, callback) { |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.query(domain, dns.SRV, callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.reverse = function(domain, callback) { |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.query(domain, dns.PTR, callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.resolveNs = function(domain, callback) { |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.query(domain, dns.NS, callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
exports.resolveCname = function(domain, callback) { |
|
|
|
callback = makeAsync(callback); |
|
|
|
channel.query(domain, dns.CNAME, callback); |
|
|
|
callback.immediately = true; |
|
|
|
}; |
|
|
|
|
|
|
|
var resolveMap = { A: exports.resolve4, |
|
|
|