Skip to content

Commit 6349b1d

Browse files
szmarczakcodebytere
authored andcommitted
dns: add a cancel() method to the promise Resolver
PR-URL: #33099 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Juan José Arboleda <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 9405cdd commit 6349b1d

File tree

4 files changed

+110
-13
lines changed

4 files changed

+110
-13
lines changed

‎doc/api/dns.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,14 @@ The following methods from the `dnsPromises` API are available:
730730
*[`resolver.reverse()`][`dnsPromises.reverse()`]
731731
*[`resolver.setServers()`][`dnsPromises.setServers()`]
732732

733+
### `resolver.cancel()`
734+
<!-- YAML
735+
added: REPLACEME
736+
-->
737+
738+
Cancel all outstanding DNS queries made by this resolver. The corresponding
739+
promises will be rejected with an error with code `ECANCELLED`.
740+
733741
### `dnsPromises.getServers()`
734742
<!-- YAML
735743
added: v10.6.0

‎lib/internal/dns/promises.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ class Resolver{
217217

218218
Resolver.prototype.getServers=CallbackResolver.prototype.getServers;
219219
Resolver.prototype.setServers=CallbackResolver.prototype.setServers;
220+
Resolver.prototype.cancel=CallbackResolver.prototype.cancel;
220221
Resolver.prototype.setLocalAddress=CallbackResolver.prototype.setLocalAddress;
221222
Resolver.prototype.resolveAny=resolveMap.ANY=resolver('queryAny');
222223
Resolver.prototype.resolve4=resolveMap.A=resolver('queryA');
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
const{promises: dnsPromises}=require('dns');
4+
constassert=require('assert');
5+
constdgram=require('dgram');
6+
7+
constserver=dgram.createSocket('udp4');
8+
constresolver=newdnsPromises.Resolver();
9+
10+
constaddMessageListener=()=>{
11+
server.removeAllListeners('message');
12+
13+
server.once('message',()=>{
14+
server.once('message',common.mustNotCall);
15+
16+
resolver.cancel();
17+
});
18+
};
19+
20+
server.bind(0,common.mustCall(async()=>{
21+
resolver.setServers([`127.0.0.1:${server.address().port}`]);
22+
23+
addMessageListener();
24+
25+
// Single promise
26+
{
27+
consthostname='example0.org';
28+
29+
awaitassert.rejects(
30+
resolver.resolve4(hostname),
31+
{
32+
code: 'ECANCELLED',
33+
syscall: 'queryA',
34+
hostname
35+
}
36+
);
37+
}
38+
39+
addMessageListener();
40+
41+
// Multiple promises
42+
{
43+
constassertions=[];
44+
constassertionCount=10;
45+
46+
for(leti=1;i<=assertionCount;i++){
47+
consthostname=`example${i}.org`;
48+
49+
assertions.push(
50+
assert.rejects(
51+
resolver.resolve4(hostname),
52+
{
53+
code: 'ECANCELLED',
54+
syscall: 'queryA',
55+
hostname: hostname
56+
}
57+
)
58+
);
59+
}
60+
61+
awaitPromise.all(assertions);
62+
}
63+
64+
server.close();
65+
}));
Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,51 @@
11
'use strict';
22
constcommon=require('../common');
3-
constdnstools=require('../common/dns');
43
const{ Resolver }=require('dns');
54
constassert=require('assert');
65
constdgram=require('dgram');
76

87
constserver=dgram.createSocket('udp4');
98
constresolver=newResolver();
109

11-
server.bind(0,common.mustCall(()=>{
10+
constdesiredQueries=11;
11+
letfinishedQueries=0;
12+
13+
constaddMessageListener=()=>{
14+
server.removeAllListeners('message');
15+
16+
server.once('message',()=>{
17+
server.once('message',common.mustNotCall);
18+
19+
resolver.cancel();
20+
});
21+
};
22+
23+
server.bind(0,common.mustCall(async()=>{
1224
resolver.setServers([`127.0.0.1:${server.address().port}`]);
13-
resolver.resolve4('example.org',common.mustCall((err,res)=>{
25+
26+
constcallback=common.mustCall((err,res)=>{
1427
assert.strictEqual(err.code,'ECANCELLED');
1528
assert.strictEqual(err.syscall,'queryA');
16-
assert.strictEqual(err.hostname,'example.org');
17-
server.close();
18-
}));
19-
}));
29+
assert.strictEqual(err.hostname,`example${finishedQueries}.org`);
30+
31+
finishedQueries++;
32+
if(finishedQueries===desiredQueries){
33+
server.close();
34+
}
35+
},desiredQueries);
36+
37+
constnext=(...args)=>{
38+
callback(...args);
39+
40+
addMessageListener();
2041

21-
server.on('message',common.mustCall((msg,{ address, port })=>{
22-
constparsed=dnstools.parseDNSPacket(msg);
23-
constdomain=parsed.questions[0].domain;
24-
assert.strictEqual(domain,'example.org');
42+
// Multiple queries
43+
for(leti=1;i<desiredQueries;i++){
44+
resolver.resolve4(`example${i}.org`,callback);
45+
}
46+
};
2547

26-
// Do not send a reply.
27-
resolver.cancel();
48+
// Single query
49+
addMessageListener();
50+
resolver.resolve4('example0.org',next);
2851
}));

0 commit comments

Comments
(0)