dns: add channel.cancel()

This can be used to implement custom timeouts.

Fixes: https://github.com/nodejs/node/issues/7231
PR-URL: https://github.com/nodejs/node/pull/14518
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
Anna Henningsen 2017-07-27 19:03:11 +02:00
parent 6e05970494
commit 732658e4cf
No known key found for this signature in database
GPG Key ID: D8B9F5AEAE84E4CF
4 changed files with 49 additions and 0 deletions

View File

@ -95,6 +95,14 @@ The following methods from the `dns` module are available:
* [`resolver.resolveTxt()`][`dns.resolveTxt()`]
* [`resolver.reverse()`][`dns.reverse()`]
### resolver.cancel()
<!-- YAML
added: REPLACEME
-->
Cancel all outstanding DNS queries made by this resolver. The corresponding
callbacks will be called with an error with code `ECANCELLED`.
## dns.getServers()
<!-- YAML
added: v0.11.3

View File

@ -247,6 +247,10 @@ class Resolver {
constructor() {
this._handle = new ChannelWrap();
}
cancel() {
this._handle.cancel();
}
}
function resolver(bindingName) {

View File

@ -2131,6 +2131,13 @@ void SetServers(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(err);
}
void Cancel(const FunctionCallbackInfo<Value>& args) {
ChannelWrap* channel;
ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());
ares_cancel(channel->cares_channel());
}
void StrError(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
@ -2215,6 +2222,7 @@ void Initialize(Local<Object> target,
env->SetProtoMethod(channel_wrap, "getServers", GetServers);
env->SetProtoMethod(channel_wrap, "setServers", SetServers);
env->SetProtoMethod(channel_wrap, "cancel", Cancel);
channel_wrap->SetClassName(
FIXED_ONE_BYTE_STRING(env->isolate(), "ChannelWrap"));

View File

@ -0,0 +1,29 @@
'use strict';
const common = require('../common');
const dnstools = require('../common/dns');
const { Resolver } = require('dns');
const assert = require('assert');
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
const resolver = new Resolver();
server.bind(0, common.mustCall(() => {
resolver.setServers([`127.0.0.1:${server.address().port}`]);
resolver.resolve4('example.org', common.mustCall((err, res) => {
assert.strictEqual(err.code, 'ECANCELLED');
assert.strictEqual(err.errno, 'ECANCELLED');
assert.strictEqual(err.syscall, 'queryA');
assert.strictEqual(err.hostname, 'example.org');
server.close();
}));
}));
server.on('message', common.mustCall((msg, { address, port }) => {
const parsed = dnstools.parseDNSPacket(msg);
const domain = parsed.questions[0].domain;
assert.strictEqual(domain, 'example.org');
// Do not send a reply.
resolver.cancel();
}));