UNPKG

1.44 kBJavaScriptView Raw
1const https = require('https');
2const http = require('http');
3const Packet = require('../packet');
4
5const get = url => new Promise((resolve, reject) => {
6 const headers = {
7 accept: 'application/dns-message',
8 };
9 const base = url.startsWith('https') ? https : http;
10 const req = base.get(url, { headers }, resolve);
11 req.on('error', reject);
12});
13
14const readStream = stream => {
15 const buffer = [];
16 return new Promise((resolve, reject) => {
17 stream
18 .on('error', reject)
19 .on('data', chunk => buffer.push(chunk))
20 .on('end', () => resolve(Buffer.concat(buffer)));
21 });
22};
23
24/**
25 * @docs https://tools.ietf.org/html/rfc8484
26 * @param {*} param0
27 */
28const DOHClient = ({ dns, http } = {}) => {
29 return (name, type = 'A', cls = Packet.CLASS.IN, { clientIp, recursive = true } = {}) => {
30 const packet = new Packet();
31 // see https://github.com/song940/node-dns/issues/29
32 if (recursive) {
33 packet.header.rd = 1;
34 }
35 if (clientIp) {
36 packet.additionals.push(Packet.Resource.EDNS([
37 Packet.Resource.EDNS.ECS(clientIp),
38 ]));
39 }
40 packet.questions.push({
41 name,
42 class : cls,
43 type : Packet.TYPE[type],
44 });
45 const query = packet.toBase64URL();
46 return Promise
47 .resolve()
48 .then(() => get(`http${http ? '' : 's'}://${dns}/dns-query?dns=${query}`))
49 .then(readStream)
50 .then(Packet.parse);
51 };
52};
53
54module.exports = DOHClient;