not provided, then IP v4 and v6 addresses are both valid. If `options` is
an integer, then it must be `4` or `6`.
-Alternatively, `options` can be an object containing two properties,
-`family` and `hints`. Both properties are optional. If `family` is provided,
-it must be the integer `4` or `6`. If `family` is not provided then IP v4
-and v6 addresses are accepted. The `hints` field, if present, should be one
-or more of the supported `getaddrinfo` flags. If `hints` is not provided,
-then no flags are passed to `getaddrinfo`. Multiple flags can be passed
-through `hints` by logically `OR`ing their values. An example usage of
-`options` is shown below.
+Alternatively, `options` can be an object containing these properties:
+
+* `family` {Number} - The record family. If present, must be the integer
+ `4` or `6`. If not provided, both IP v4 and v6 addresses are accepted.
+* `hints`: {Number} - If present, it should be one or more of the supported
+ `getaddrinfo` flags. If `hints` is not provided, then no flags are passed to
+ `getaddrinfo`. Multiple flags can be passed through `hints` by logically
+ `OR`ing their values.
+ See [supported `getaddrinfo` flags](#dns_supported_getaddrinfo_flags) below
+ for more information on supported flags.
+* `all`: {Boolean} - When `true`, the callback returns all resolved addresses
+ in an array, otherwise returns a single address. Defaults to `false`.
+
+All properties are optional. An example usage of options is shown below.
```
{
family: 4,
hints: dns.ADDRCONFIG | dns.V4MAPPED
+ all: true
}
```
-See [supported `getaddrinfo` flags](#dns_supported_getaddrinfo_flags) below for
-more information on supported flags.
+The callback has arguments `(err, address, family)`. `address` is a string
+representation of a IP v4 or v6 address. `family` is either the integer 4 or 6
+and denotes the family of `address` (not necessarily the value initially passed
+to `lookup`).
-The callback has arguments `(err, address, family)`. The `address` argument
-is a string representation of a IP v4 or v6 address. The `family` argument
-is either the integer 4 or 6 and denotes the family of `address` (not
-necessarily the value initially passed to `lookup`).
+With the `all` option set, the arguments change to `(err, addresses)`, with
+`addresses` being an array of objects with the properties `address` and
+`family`.
On error, `err` is an `Error` object, where `err.code` is the error code.
Keep in mind that `err.code` will be set to `'ENOENT'` not only when
}
+function onlookupall(err, addresses) {
+ var results = [];
+ if (err) {
+ return this.callback(errnoException(err, 'getaddrinfo', this.hostname));
+ }
+
+ for (var i = 0; i < addresses.length; i++) {
+ results.push({
+ address: addresses[i],
+ family: this.family || (addresses[i].indexOf(':') >= 0 ? 6 : 4)
+ });
+ }
+
+ this.callback(null, results);
+}
+
+
// Easy DNS A/AAAA look up
// lookup(hostname, [options,] callback)
exports.lookup = function lookup(hostname, options, callback) {
var hints = 0;
var family = -1;
+ var all = false;
// Parse arguments
if (hostname && typeof hostname !== 'string') {
} else if (options !== null && typeof options === 'object') {
hints = options.hints >>> 0;
family = options.family >>> 0;
+ all = options.all === true;
if (hints !== 0 &&
hints !== exports.ADDRCONFIG &&
callback = makeAsync(callback);
if (!hostname) {
- callback(null, null, family === 6 ? 6 : 4);
+ if (all) {
+ callback(null, []);
+ } else {
+ callback(null, null, family === 6 ? 6 : 4);
+ }
return {};
}
var matchedFamily = net.isIP(hostname);
if (matchedFamily) {
- callback(null, hostname, matchedFamily);
+ if (all) {
+ callback(null, [{address: hostname, family: matchedFamily}]);
+ } else {
+ callback(null, hostname, matchedFamily);
+ }
return {};
}
req.callback = callback;
req.family = family;
req.hostname = hostname;
- req.oncomplete = onlookup;
+ req.oncomplete = all ? onlookupall : onlookup;
var err = cares.getaddrinfo(req, hostname, family, hints);
if (err) {
TEST(function test_resolveSoa(done) {
var req = dns.resolveSoa('nodejs.org', function(err, result) {
if (err) throw err;
-
+
assert.ok(result);
assert.ok(typeof result === 'object');
-
+
assert.ok(typeof result.nsname === 'string');
assert.ok(result.nsname.length > 0);
-
+
assert.ok(typeof result.hostmaster === 'string');
assert.ok(result.hostmaster.length > 0);
-
+
assert.ok(typeof result.serial === 'number');
assert.ok((result.serial > 0) && (result.serial < 4294967295));
-
+
assert.ok(typeof result.refresh === 'number');
- assert.ok((result.refresh > 0) && (result.refresh < 2147483647));
-
+ assert.ok((result.refresh > 0) && (result.refresh < 2147483647));
+
assert.ok(typeof result.retry === 'number');
assert.ok((result.retry > 0) && (result.retry < 2147483647));
-
+
assert.ok(typeof result.expire === 'number');
assert.ok((result.expire > 0) && (result.expire < 2147483647));
-
+
assert.ok(typeof result.minttl === 'number');
assert.ok((result.minttl >= 0) && (result.minttl < 2147483647));
done();
});
-
+
checkWrap(req);
});
});
+TEST(function test_lookup_ip_all(done) {
+ var req = dns.lookup('127.0.0.1', {all: true}, function(err, ips, family) {
+ if (err) throw err;
+ assert.ok(Array.isArray(ips));
+ assert.ok(ips.length > 0);
+ assert.strictEqual(ips[0].address, '127.0.0.1');
+ assert.strictEqual(ips[0].family, 4);
+
+ done();
+ });
+
+ checkWrap(req);
+});
+
+
+TEST(function test_lookup_null_all(done) {
+ var req = dns.lookup(null, {all: true}, function(err, ips, family) {
+ if (err) throw err;
+ assert.ok(Array.isArray(ips));
+ assert.strictEqual(ips.length, 0);
+
+ done();
+ });
+
+ checkWrap(req);
+});
+
+
+TEST(function test_lookup_all_ipv4(done) {
+ var req = dns.lookup('www.google.com', {all: true, family: 4}, function(err, ips) {
+ if (err) throw err;
+ assert.ok(Array.isArray(ips));
+ assert.ok(ips.length > 0);
+
+ ips.forEach(function(ip) {
+ assert.ok(isIPv4(ip.address));
+ assert.strictEqual(ip.family, 4);
+ });
+
+ done();
+ });
+
+ checkWrap(req);
+});
+
+
+TEST(function test_lookup_all_ipv6(done) {
+ var req = dns.lookup('www.google.com', {all: true, family: 6}, function(err, ips) {
+ if (err) throw err;
+ assert.ok(Array.isArray(ips));
+ assert.ok(ips.length > 0);
+
+ ips.forEach(function(ip) {
+ assert.ok(isIPv6(ip.address));
+ assert.strictEqual(ip.family, 6);
+ });
+
+ done();
+ });
+
+ checkWrap(req);
+});
+
+
+TEST(function test_lookup_all_mixed(done) {
+ var req = dns.lookup('www.google.com', {all: true}, function(err, ips) {
+ if (err) throw err;
+ assert.ok(Array.isArray(ips));
+ assert.ok(ips.length > 0);
+
+ ips.forEach(function(ip) {
+ if (isIPv4(ip.address))
+ assert.equal(ip.family, 4);
+ else if (isIPv6(ip.address))
+ assert.equal(ip.family, 6);
+ else
+ assert(false);
+ });
+
+ done();
+ });
+
+ checkWrap(req);
+});
+
+
TEST(function test_lookupservice_ip_ipv4(done) {
var req = dns.lookupService('127.0.0.1', 80, function(err, host, service) {
if (err) throw err;