dns: support max timeout · nodejs/node@c52aaac

1+

'use strict';

2+

const common = require('../common');

3+

const dnstools = require('../common/dns');

4+

const dns = require('dns');

5+

const assert = require('assert');

6+

const dgram = require('dgram');

7+8+

[

9+

-1,

10+

1.1,

11+

NaN,

12+

undefined,

13+

{},

14+

[],

15+

null,

16+

function() {},

17+

Symbol(),

18+

true,

19+

Infinity,

20+

].forEach((maxTimeout) => {

21+

try {

22+

new dns.Resolver({ maxTimeout });

23+

} catch (e) {

24+

assert.ok(/ERR_OUT_OF_RANGE|ERR_INVALID_ARG_TYPE/i.test(e.code));

25+

}

26+

});

27+28+

const server = dgram.createSocket('udp4');

29+

const nxdomain = 'nxdomain.org';

30+

const domain = 'example.org';

31+

const answers = [{ type: 'A', address: '1.2.3.4', ttl: 123, domain }];

32+33+

server.on('message', common.mustCallAtLeast((msg, { address, port }) => {

34+

const parsed = dnstools.parseDNSPacket(msg);

35+

if (parsed.questions[0].domain === nxdomain) {

36+

return;

37+

}

38+

assert.strictEqual(parsed.questions[0].domain, domain);

39+

server.send(dnstools.writeDNSPacket({

40+

id: parsed.id,

41+

questions: parsed.questions,

42+

answers: answers,

43+

}), port, address);

44+

}), 1);

45+46+

server.bind(0, common.mustCall(async () => {

47+

const address = server.address();

48+

// Test if the Resolver works as before.

49+

const resolver = new dns.promises.Resolver({ timeout: 1000, tries: 1, maxTimeout: 1000 });

50+

resolver.setServers([`127.0.0.1:${address.port}`]);

51+

const res = await resolver.resolveAny('example.org');

52+

assert.strictEqual(res.length, 1);

53+

assert.strictEqual(res.length, answers.length);

54+

assert.strictEqual(res[0].address, answers[0].address);

55+56+

// Test that maxTimeout is effective.

57+

// Without maxTimeout, the timeout will keep increasing when retrying.

58+

const timeout1 = await timeout(address, { timeout: 500, tries: 3 });

59+

// With maxTimeout, the timeout will always be 500 when retrying.

60+

const timeout2 = await timeout(address, { timeout: 500, tries: 3, maxTimeout: 500 });

61+

console.log(`timeout1: ${timeout1}, timeout2: ${timeout2}`);

62+

assert.strictEqual(timeout1 !== undefined && timeout2 !== undefined, true);

63+

assert.strictEqual(timeout1 > timeout2, true);

64+

server.close();

65+

}));

66+67+

async function timeout(address, options) {

68+

const start = Date.now();

69+

const resolver = new dns.promises.Resolver(options);

70+

resolver.setServers([`127.0.0.1:${address.port}`]);

71+

try {

72+

await resolver.resolveAny(nxdomain);

73+

} catch (e) {

74+

assert.strictEqual(e.code, 'ETIMEOUT');

75+

return Date.now() - start;

76+

}

77+

}