diff --git a/lib/dns.js b/lib/dns.js index 04cc58755142ce..0796c880b00b65 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -1,6 +1,5 @@ 'use strict'; -const net = require('net'); const util = require('util'); const cares = process.binding('cares_wrap'); @@ -11,7 +10,7 @@ const GetAddrInfoReqWrap = cares.GetAddrInfoReqWrap; const GetNameInfoReqWrap = cares.GetNameInfoReqWrap; const QueryReqWrap = cares.QueryReqWrap; -const isIp = net.isIP; +const isIp = cares.isIP; const isLegalPort = internalNet.isLegalPort; @@ -25,7 +24,7 @@ function errnoException(err, syscall, hostname) { } var ex = null; if (typeof err === 'string') { // c-ares error code. - ex = new Error(syscall + ' ' + err + (hostname ? ' ' + hostname : '')); + ex = new Error(`${syscall} ${err} ${(hostname ? ' ' + hostname : '')}`); ex.code = err; ex.errno = err; ex.syscall = syscall; @@ -38,7 +37,6 @@ function errnoException(err, syscall, hostname) { return ex; } - // c-ares invokes a callback either synchronously or asynchronously, // but the dns API should always invoke a callback asynchronously. // @@ -66,8 +64,9 @@ function makeAsync(callback) { } else { var args = new Array(arguments.length + 1); args[0] = callback; - for (var i = 1, a = 0; a < arguments.length; ++i, ++a) + for (var i = 1, a = 0; a < arguments.length; ++i, ++a) { args[i] = arguments[a]; + } process.nextTick.apply(null, args); } }; @@ -76,8 +75,10 @@ function makeAsync(callback) { function onlookup(err, addresses) { if (err) { - return this.callback(errnoException(err, 'getaddrinfo', this.hostname)); + this.callback(errnoException(err, 'getaddrinfo', this.hostname)); + return; } + if (this.family) { this.callback(null, addresses[0], this.family); } else { @@ -87,16 +88,18 @@ function onlookup(err, addresses) { function onlookupall(err, addresses) { - var results = []; if (err) { - return this.callback(errnoException(err, 'getaddrinfo', this.hostname)); + this.callback(errnoException(err, 'getaddrinfo', this.hostname)); + return; } + const results = new Array(addresses.length); + for (var i = 0; i < addresses.length; i++) { - results.push({ + results[i] = { address: addresses[i], family: this.family || (addresses[i].indexOf(':') >= 0 ? 6 : 4) - }); + }; } this.callback(null, results); @@ -134,8 +137,10 @@ exports.lookup = function lookup(hostname, options, callback) { family = options >>> 0; } - if (family !== 0 && family !== 4 && family !== 6) - throw new TypeError('Invalid argument: family must be 4 or 6'); + if (family !== 0 && family !== 4 && family !== 6) { + const msg = `Invalid argument: family must be 4 or 6, got ${family}`; + throw new TypeError(msg); + } callback = makeAsync(callback); @@ -148,7 +153,7 @@ exports.lookup = function lookup(hostname, options, callback) { return {}; } - var matchedFamily = net.isIP(hostname); + var matchedFamily = isIP(hostname); if (matchedFamily) { if (all) { callback(null, [{address: hostname, family: matchedFamily}]); @@ -176,8 +181,10 @@ exports.lookup = function lookup(hostname, options, callback) { function onlookupservice(err, host, service) { - if (err) - return this.callback(errnoException(err, 'getnameinfo', this.host)); + if (err) { + this.callback(errnoException(err, 'getnameinfo', this.host)); + return; + } this.callback(null, host, service); } @@ -185,16 +192,19 @@ function onlookupservice(err, host, service) { // lookupService(address, port, callback) exports.lookupService = function(host, port, callback) { - if (arguments.length !== 3) - throw new Error('Invalid arguments'); + if (arguments.length !== 3) { + throw new TypeError(`Expected 3 arguments, got ${arguments.length}`); + } - if (cares.isIP(host) === 0) + if (isIP(host) === 0) { throw new TypeError('"host" argument needs to be a valid IP address'); + } - if (port == null || !isLegalPort(port)) + if (port == null || !isLegalPort(port)) { throw new TypeError(`"port" should be >= 0 and < 65536, got "${port}"`); + } - port = +port; + port = Number(port); callback = makeAsync(callback); var req = new GetNameInfoReqWrap(); @@ -204,7 +214,9 @@ exports.lookupService = function(host, port, callback) { req.oncomplete = onlookupservice; var err = cares.getnameinfo(req, host, port); - if (err) throw errnoException(err, 'getnameinfo', host); + if (err) { + throw errnoException(err, 'getnameinfo', host); + } callback.immediately = true; return req; @@ -212,10 +224,11 @@ exports.lookupService = function(host, port, callback) { function onresolve(err, result) { - if (err) + if (err) { this.callback(errnoException(err, this.bindingName, this.hostname)); - else + } else { this.callback(null, result); + } } @@ -224,9 +237,10 @@ function resolver(bindingName) { return function query(name, callback) { if (typeof name !== 'string') { - throw new Error('"name" argument must be a string'); + const msg = `"name" argument must be a string, got ${typeof name}`; + throw new TypeError(msg); } else if (typeof callback !== 'function') { - throw new Error('"callback" argument must be a function'); + throw new TypeError('"callback" argument must be a function'); } callback = makeAsync(callback); @@ -236,14 +250,17 @@ function resolver(bindingName) { req.hostname = name; req.oncomplete = onresolve; var err = binding(req, name); - if (err) throw errnoException(err, bindingName); + if (err) { + throw errnoException(err, bindingName); + } + callback.immediately = true; return req; }; } -var resolveMap = {}; +var resolveMap = Object.create(null); exports.resolve4 = resolveMap.A = resolver('queryA'); exports.resolve6 = resolveMap.AAAA = resolver('queryAaaa'); exports.resolveCname = resolveMap.CNAME = resolver('queryCname'); @@ -257,7 +274,7 @@ exports.resolveSoa = resolveMap.SOA = resolver('querySoa'); exports.reverse = resolver('getHostByAddr'); -exports.resolve = function(hostname, type_, callback_) { +exports.resolve = (hostname, type_, callback_) => { var resolver, callback; if (typeof type_ === 'string') { resolver = resolveMap[type_]; @@ -272,12 +289,12 @@ exports.resolve = function(hostname, type_, callback_) { if (typeof resolver === 'function') { return resolver(hostname, callback); } else { - throw new Error('Unknown type "' + type_ + '"'); + throw new Error(`Unknown type ${type_}`); } }; -exports.getServers = function() { +exports.getServers = () => { return cares.getServers(); }; @@ -285,43 +302,42 @@ exports.getServers = function() { exports.setServers = function(servers) { // cache the original servers because in the event of an error setting the // servers cares won't have any servers available for resolution - var orig = cares.getServers(); + var originalServers = cares.getServers(); - var newSet = []; + const newSet = servers.map((serv) => { + var ipVersion = isIp(serv); - servers.forEach(function(serv) { - var ver = isIp(serv); - - if (ver) - return newSet.push([ver, serv]); - - var match = serv.match(/\[(.*)\](:\d+)?/); + if (ipVersion !== 0) { + return [ver, serv]; + } + const match = serv.match(/\[(.*)\](:\d+)?/); // we have an IPv6 in brackets if (match) { - ver = isIp(match[1]); - if (ver) - return newSet.push([ver, match[1]]); + ipVersion = isIp(match[1]); + if (ipVersion !== 0) { + return [ver, match[1]]; + } } var s = serv.split(/:\d+$/)[0]; - ver = isIp(s); + ipVersion = isIp(s); - if (ver) - return newSet.push([ver, s]); + if (ipVersion !== 0) { + return [ver, s]; + } - throw new Error('IP address is not properly formatted: ' + serv); + throw new Error(`IP address is not properly formatted: ${serv}`); }); - var r = cares.setServers(newSet); + const errorNumber = cares.setServers(newSet); - if (r) { + if (errorNumber !== 0) { // reset the servers to the old servers, because ares probably unset them - cares.setServers(orig.join(',')); + cares.setServers(originalServers.join(',')); var err = cares.strerror(r); - throw new Error('c-ares failed to set servers: "' + err + - '" [' + servers + ']'); + throw new Error(`c-ares failed to set servers: ${err} [${servers}]`); } };