Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0f232e9

Browse filesBrowse files
joyeecheungRafaelGSS
authored andcommitted
dns: refactor default resolver
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>
1 parent 2d87b6f commit 0f232e9
Copy full SHA for 0f232e9

File tree

Expand file treeCollapse file tree

7 files changed

+191
-141
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

7 files changed

+191
-141
lines changed
Open diff view settings
Collapse file

‎lib/dns.js‎

Copy file name to clipboardExpand all lines: lib/dns.js
+4-93Lines changed: 4 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@
2222
'use strict';
2323

2424
const {
25-
ArrayPrototypeMap,
26-
ObjectCreate,
2725
ObjectDefineProperties,
2826
ObjectDefineProperty,
29-
ReflectApply,
3027
Symbol,
3128
} = primordials;
3229

@@ -37,15 +34,16 @@ const { customPromisifyArgs } = require('internal/util');
3734
const errors = require('internal/errors');
3835
const {
3936
bindDefaultResolver,
40-
getDefaultResolver,
4137
setDefaultResolver,
42-
Resolver,
4338
validateHints,
4439
emitInvalidHostnameWarning,
4540
getDefaultVerbatim,
4641
setDefaultResultOrder,
4742
errorCodes: dnsErrorCodes,
4843
} = require('internal/dns/utils');
44+
const {
45+
Resolver
46+
} = require('internal/dns/callback_resolver');
4947
const {
5048
NODATA,
5149
FORMERR,
@@ -89,12 +87,10 @@ const {
8987
const {
9088
GetAddrInfoReqWrap,
9189
GetNameInfoReqWrap,
92-
QueryReqWrap,
9390
} = cares;
9491

9592
const kPerfHooksDnsLookupContext = Symbol('kPerfHooksDnsLookupContext');
9693
const kPerfHooksDnsLookupServiceContext = Symbol('kPerfHooksDnsLookupServiceContext');
97-
const kPerfHooksDnsLookupResolveContext = Symbol('kPerfHooksDnsLookupResolveContext');
9894

9995
const {
10096
hasObserver,
@@ -293,91 +289,6 @@ function lookupService(address, port, callback) {
293289
ObjectDefineProperty(lookupService, customPromisifyArgs,
294290
{ __proto__: null, value: ['hostname', 'service'], enumerable: false });
295291

296-
297-
function onresolve(err, result, ttls) {
298-
if (ttls && this.ttl)
299-
result = ArrayPrototypeMap(
300-
result, (address, index) => ({ address, ttl: ttls[index] }));
301-
302-
if (err)
303-
this.callback(dnsException(err, this.bindingName, this.hostname));
304-
else {
305-
this.callback(null, result);
306-
if (this[kPerfHooksDnsLookupResolveContext] && hasObserver('dns')) {
307-
stopPerf(this, kPerfHooksDnsLookupResolveContext, { detail: { result } });
308-
}
309-
}
310-
}
311-
312-
function resolver(bindingName) {
313-
function query(name, /* options, */ callback) {
314-
let options;
315-
if (arguments.length > 2) {
316-
options = callback;
317-
callback = arguments[2];
318-
}
319-
320-
validateString(name, 'name');
321-
validateFunction(callback, 'callback');
322-
323-
const req = new QueryReqWrap();
324-
req.bindingName = bindingName;
325-
req.callback = callback;
326-
req.hostname = name;
327-
req.oncomplete = onresolve;
328-
req.ttl = !!(options && options.ttl);
329-
const err = this._handle[bindingName](req, toASCII(name));
330-
if (err) throw dnsException(err, bindingName, name);
331-
if (hasObserver('dns')) {
332-
startPerf(req, kPerfHooksDnsLookupResolveContext, {
333-
type: 'dns',
334-
name: bindingName,
335-
detail: {
336-
host: name,
337-
ttl: req.ttl,
338-
},
339-
});
340-
}
341-
return req;
342-
}
343-
ObjectDefineProperty(query, 'name', { __proto__: null, value: bindingName });
344-
return query;
345-
}
346-
347-
const resolveMap = ObjectCreate(null);
348-
Resolver.prototype.resolveAny = resolveMap.ANY = resolver('queryAny');
349-
Resolver.prototype.resolve4 = resolveMap.A = resolver('queryA');
350-
Resolver.prototype.resolve6 = resolveMap.AAAA = resolver('queryAaaa');
351-
Resolver.prototype.resolveCaa = resolveMap.CAA = resolver('queryCaa');
352-
Resolver.prototype.resolveCname = resolveMap.CNAME = resolver('queryCname');
353-
Resolver.prototype.resolveMx = resolveMap.MX = resolver('queryMx');
354-
Resolver.prototype.resolveNs = resolveMap.NS = resolver('queryNs');
355-
Resolver.prototype.resolveTxt = resolveMap.TXT = resolver('queryTxt');
356-
Resolver.prototype.resolveSrv = resolveMap.SRV = resolver('querySrv');
357-
Resolver.prototype.resolvePtr = resolveMap.PTR = resolver('queryPtr');
358-
Resolver.prototype.resolveNaptr = resolveMap.NAPTR = resolver('queryNaptr');
359-
Resolver.prototype.resolveSoa = resolveMap.SOA = resolver('querySoa');
360-
Resolver.prototype.reverse = resolver('getHostByAddr');
361-
362-
Resolver.prototype.resolve = resolve;
363-
364-
function resolve(hostname, rrtype, callback) {
365-
let resolver;
366-
if (typeof rrtype === 'string') {
367-
resolver = resolveMap[rrtype];
368-
} else if (typeof rrtype === 'function') {
369-
resolver = resolveMap.A;
370-
callback = rrtype;
371-
} else {
372-
throw new ERR_INVALID_ARG_TYPE('rrtype', 'string', rrtype);
373-
}
374-
375-
if (typeof resolver === 'function') {
376-
return ReflectApply(resolver, this, [hostname, callback]);
377-
}
378-
throw new ERR_INVALID_ARG_VALUE('rrtype', rrtype);
379-
}
380-
381292
function defaultResolverSetServers(servers) {
382293
const resolver = new Resolver();
383294

@@ -429,7 +340,7 @@ module.exports = {
429340
CANCELLED,
430341
};
431342

432-
bindDefaultResolver(module.exports, getDefaultResolver());
343+
bindDefaultResolver(module.exports, Resolver.prototype);
433344

434345
ObjectDefineProperties(module.exports, {
435346
promises: {
Collapse file
+116Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
'use strict';
2+
3+
const {
4+
ObjectDefineProperty,
5+
ReflectApply,
6+
ArrayPrototypeMap,
7+
Symbol
8+
} = primordials;
9+
10+
const { toASCII } = require('internal/idna');
11+
12+
const {
13+
codes: {
14+
ERR_INVALID_ARG_TYPE,
15+
ERR_INVALID_ARG_VALUE,
16+
},
17+
dnsException
18+
} = require('internal/errors');
19+
20+
const {
21+
createResolverClass,
22+
} = require('internal/dns/utils');
23+
24+
const {
25+
validateFunction,
26+
validateString,
27+
} = require('internal/validators');
28+
29+
const {
30+
QueryReqWrap,
31+
} = internalBinding('cares_wrap');
32+
33+
const {
34+
hasObserver,
35+
startPerf,
36+
stopPerf,
37+
} = require('internal/perf/observe');
38+
39+
const kPerfHooksDnsLookupResolveContext = Symbol('kPerfHooksDnsLookupResolveContext');
40+
41+
function onresolve(err, result, ttls) {
42+
if (ttls && this.ttl)
43+
result = ArrayPrototypeMap(
44+
result, (address, index) => ({ address, ttl: ttls[index] }));
45+
46+
if (err)
47+
this.callback(dnsException(err, this.bindingName, this.hostname));
48+
else {
49+
this.callback(null, result);
50+
if (this[kPerfHooksDnsLookupResolveContext] && hasObserver('dns')) {
51+
stopPerf(this, kPerfHooksDnsLookupResolveContext, { detail: { result } });
52+
}
53+
}
54+
}
55+
56+
function resolver(bindingName) {
57+
function query(name, /* options, */ callback) {
58+
let options;
59+
if (arguments.length > 2) {
60+
options = callback;
61+
callback = arguments[2];
62+
}
63+
64+
validateString(name, 'name');
65+
validateFunction(callback, 'callback');
66+
67+
const req = new QueryReqWrap();
68+
req.bindingName = bindingName;
69+
req.callback = callback;
70+
req.hostname = name;
71+
req.oncomplete = onresolve;
72+
req.ttl = !!(options && options.ttl);
73+
const err = this._handle[bindingName](req, toASCII(name));
74+
if (err) throw dnsException(err, bindingName, name);
75+
if (hasObserver('dns')) {
76+
startPerf(req, kPerfHooksDnsLookupResolveContext, {
77+
type: 'dns',
78+
name: bindingName,
79+
detail: {
80+
host: name,
81+
ttl: req.ttl,
82+
},
83+
});
84+
}
85+
return req;
86+
}
87+
ObjectDefineProperty(query, 'name', { __proto__: null, value: bindingName });
88+
return query;
89+
}
90+
91+
// This is the callback-based resolver. There is another similar
92+
// resolver in dns/promises.js with resolve methods that are based
93+
// on promises instead.
94+
const { Resolver, resolveMap } = createResolverClass(resolver);
95+
Resolver.prototype.resolve = resolve;
96+
97+
function resolve(hostname, rrtype, callback) {
98+
let resolver;
99+
if (typeof rrtype === 'string') {
100+
resolver = resolveMap[rrtype];
101+
} else if (typeof rrtype === 'function') {
102+
resolver = resolveMap.A;
103+
callback = rrtype;
104+
} else {
105+
throw new ERR_INVALID_ARG_TYPE('rrtype', 'string', rrtype);
106+
}
107+
108+
if (typeof resolver === 'function') {
109+
return ReflectApply(resolver, this, [hostname, callback]);
110+
}
111+
throw new ERR_INVALID_ARG_VALUE('rrtype', rrtype);
112+
}
113+
114+
module.exports = {
115+
Resolver
116+
};
Collapse file

‎lib/internal/dns/promises.js‎

Copy file name to clipboardExpand all lines: lib/internal/dns/promises.js
+8-36Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22
const {
33
ArrayPrototypeMap,
4-
ObjectCreate,
54
ObjectDefineProperty,
65
Promise,
76
ReflectApply,
@@ -10,16 +9,15 @@ const {
109

1110
const {
1211
bindDefaultResolver,
13-
Resolver: CallbackResolver,
12+
createResolverClass,
1413
validateHints,
15-
validateTimeout,
16-
validateTries,
1714
emitInvalidHostnameWarning,
1815
getDefaultVerbatim,
1916
errorCodes: dnsErrorCodes,
2017
setDefaultResultOrder,
2118
setDefaultResolver,
2219
} = require('internal/dns/utils');
20+
2321
const {
2422
NODATA,
2523
FORMERR,
@@ -52,7 +50,6 @@ const { isIP } = require('internal/net');
5250
const {
5351
getaddrinfo,
5452
getnameinfo,
55-
ChannelWrap,
5653
GetAddrInfoReqWrap,
5754
GetNameInfoReqWrap,
5855
QueryReqWrap
@@ -305,36 +302,7 @@ function resolver(bindingName) {
305302
return query;
306303
}
307304

308-
309-
const resolveMap = ObjectCreate(null);
310-
311-
// Resolver instances correspond 1:1 to c-ares channels.
312-
class Resolver {
313-
constructor(options = undefined) {
314-
const timeout = validateTimeout(options);
315-
const tries = validateTries(options);
316-
this._handle = new ChannelWrap(timeout, tries);
317-
}
318-
}
319-
320-
Resolver.prototype.getServers = CallbackResolver.prototype.getServers;
321-
Resolver.prototype.setServers = CallbackResolver.prototype.setServers;
322-
Resolver.prototype.cancel = CallbackResolver.prototype.cancel;
323-
Resolver.prototype.setLocalAddress = CallbackResolver.prototype.setLocalAddress;
324-
Resolver.prototype.resolveAny = resolveMap.ANY = resolver('queryAny');
325-
Resolver.prototype.resolve4 = resolveMap.A = resolver('queryA');
326-
Resolver.prototype.resolve6 = resolveMap.AAAA = resolver('queryAaaa');
327-
Resolver.prototype.resolveCaa = resolveMap.CAA = resolver('queryCaa');
328-
Resolver.prototype.resolveCname = resolveMap.CNAME = resolver('queryCname');
329-
Resolver.prototype.resolveMx = resolveMap.MX = resolver('queryMx');
330-
Resolver.prototype.resolveNs = resolveMap.NS = resolver('queryNs');
331-
Resolver.prototype.resolveTxt = resolveMap.TXT = resolver('queryTxt');
332-
Resolver.prototype.resolveSrv = resolveMap.SRV = resolver('querySrv');
333-
Resolver.prototype.resolvePtr = resolveMap.PTR = resolver('queryPtr');
334-
Resolver.prototype.resolveNaptr = resolveMap.NAPTR = resolver('queryNaptr');
335-
Resolver.prototype.resolveSoa = resolveMap.SOA = resolver('querySoa');
336-
Resolver.prototype.reverse = resolver('getHostByAddr');
337-
Resolver.prototype.resolve = function resolve(hostname, rrtype) {
305+
function resolve(hostname, rrtype) {
338306
let resolver;
339307

340308
if (rrtype !== undefined) {
@@ -349,7 +317,11 @@ Resolver.prototype.resolve = function resolve(hostname, rrtype) {
349317
}
350318

351319
return ReflectApply(resolver, this, [hostname]);
352-
};
320+
}
321+
322+
// Promise-based resolver.
323+
const { Resolver, resolveMap } = createResolverClass(resolver);
324+
Resolver.prototype.resolve = resolve;
353325

354326
function defaultResolverSetServers(servers) {
355327
const resolver = new Resolver();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.