-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch refactors the DNS default resolver code to make it easier to be included in a snapshot: - The code specific for the callback-based DNS resolver are not in a separate module to make the dependency clearer (it's not actually needed if the user only ever loads `dns/promises`) - The common part of the callback-based resolver and the promise- based resolver is now ResolverBase. The other two user-facing resolvers are now subclasses of ResolverBase. The default Resolver is constructed with just ResolverBase. This would be fine as the default resolver is never actually exposed to the user-land and it has been working using duck-typing anyway. - Move the construction of Resolver subclasses into a common method `createResolverClass()` to reduce code duplication. The two subclasses now also share the same base constructor. This would make it possible for them to also share code for snapshot support later. - `--dns-result-order` is now queried and refreshed during pre-execution. To avoid loading the cares_wrap binding unnecessarily the loading of the binding is also made lazy. PR-URL: #44541 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Zeyu "Alex" Yang <himself65@outlook.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
- Loading branch information
1 parent
2d87b6f
commit 0f232e9
Showing
7 changed files
with
191 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
'use strict'; | ||
|
||
const { | ||
ObjectDefineProperty, | ||
ReflectApply, | ||
ArrayPrototypeMap, | ||
Symbol | ||
} = primordials; | ||
|
||
const { toASCII } = require('internal/idna'); | ||
|
||
const { | ||
codes: { | ||
ERR_INVALID_ARG_TYPE, | ||
ERR_INVALID_ARG_VALUE, | ||
}, | ||
dnsException | ||
} = require('internal/errors'); | ||
|
||
const { | ||
createResolverClass, | ||
} = require('internal/dns/utils'); | ||
|
||
const { | ||
validateFunction, | ||
validateString, | ||
} = require('internal/validators'); | ||
|
||
const { | ||
QueryReqWrap, | ||
} = internalBinding('cares_wrap'); | ||
|
||
const { | ||
hasObserver, | ||
startPerf, | ||
stopPerf, | ||
} = require('internal/perf/observe'); | ||
|
||
const kPerfHooksDnsLookupResolveContext = Symbol('kPerfHooksDnsLookupResolveContext'); | ||
|
||
function onresolve(err, result, ttls) { | ||
if (ttls && this.ttl) | ||
result = ArrayPrototypeMap( | ||
result, (address, index) => ({ address, ttl: ttls[index] })); | ||
|
||
if (err) | ||
this.callback(dnsException(err, this.bindingName, this.hostname)); | ||
else { | ||
this.callback(null, result); | ||
if (this[kPerfHooksDnsLookupResolveContext] && hasObserver('dns')) { | ||
stopPerf(this, kPerfHooksDnsLookupResolveContext, { detail: { result } }); | ||
} | ||
} | ||
} | ||
|
||
function resolver(bindingName) { | ||
function query(name, /* options, */ callback) { | ||
let options; | ||
if (arguments.length > 2) { | ||
options = callback; | ||
callback = arguments[2]; | ||
} | ||
|
||
validateString(name, 'name'); | ||
validateFunction(callback, 'callback'); | ||
|
||
const req = new QueryReqWrap(); | ||
req.bindingName = bindingName; | ||
req.callback = callback; | ||
req.hostname = name; | ||
req.oncomplete = onresolve; | ||
req.ttl = !!(options && options.ttl); | ||
const err = this._handle[bindingName](req, toASCII(name)); | ||
if (err) throw dnsException(err, bindingName, name); | ||
if (hasObserver('dns')) { | ||
startPerf(req, kPerfHooksDnsLookupResolveContext, { | ||
type: 'dns', | ||
name: bindingName, | ||
detail: { | ||
host: name, | ||
ttl: req.ttl, | ||
}, | ||
}); | ||
} | ||
return req; | ||
} | ||
ObjectDefineProperty(query, 'name', { __proto__: null, value: bindingName }); | ||
return query; | ||
} | ||
|
||
// This is the callback-based resolver. There is another similar | ||
// resolver in dns/promises.js with resolve methods that are based | ||
// on promises instead. | ||
const { Resolver, resolveMap } = createResolverClass(resolver); | ||
Resolver.prototype.resolve = resolve; | ||
|
||
function resolve(hostname, rrtype, callback) { | ||
let resolver; | ||
if (typeof rrtype === 'string') { | ||
resolver = resolveMap[rrtype]; | ||
} else if (typeof rrtype === 'function') { | ||
resolver = resolveMap.A; | ||
callback = rrtype; | ||
} else { | ||
throw new ERR_INVALID_ARG_TYPE('rrtype', 'string', rrtype); | ||
} | ||
|
||
if (typeof resolver === 'function') { | ||
return ReflectApply(resolver, this, [hostname, callback]); | ||
} | ||
throw new ERR_INVALID_ARG_VALUE('rrtype', rrtype); | ||
} | ||
|
||
module.exports = { | ||
Resolver | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.