Skip to content

Commit 5aa630f

Browse files
committed
add dns over tls supports, and fix #88
1 parent a9d3400 commit 5aa630f

File tree

1 file changed

+39
-25
lines changed

1 file changed

+39
-25
lines changed

client/tcp.js

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,48 @@
1+
const tls = require('tls');
12
const tcp = require('net');
23
const Packet = require('../packet');
34

4-
module.exports = ({ dns = '1.1.1.1', port = 53 } = {}) => {
5-
return async(name, type = 'A', cls = Packet.CLASS.IN, { clientIp, recursive = true } = {}) => {
6-
const packet = new Packet();
5+
const makeQuery = ({ name, type = 'A', cls = Packet.CLASS.IN, clientIp, recursive = true }) => {
6+
const packet = new Packet();
7+
packet.header.rd = recursive ? 1 : 0;
8+
9+
if (clientIp) {
10+
packet.additionals.push(Packet.Resource.EDNS([
11+
Packet.Resource.EDNS.ECS(clientIp)
12+
]));
13+
}
14+
15+
packet.questions.push({ name, class: cls, type: Packet.TYPE[type] });
16+
return packet.toBuffer();
17+
};
18+
19+
const sendQuery = (client, message) => {
20+
const len = Buffer.alloc(2);
21+
len.writeUInt16BE(message.length);
22+
client.end(Buffer.concat([len, message]));
23+
};
724

8-
// see https://github.com/song940/node-dns/issues/29
9-
if (recursive) {
10-
packet.header.rd = 1;
11-
}
12-
if (clientIp) {
13-
packet.additionals.push(Packet.Resource.EDNS([
14-
Packet.Resource.EDNS.ECS(clientIp),
15-
]));
16-
}
25+
const protocols = {
26+
'tcp:': (host, port) => tcp.connect({ host, port }),
27+
'tls:': (host, port) => tls.connect({ host, port, servername: host })
28+
};
29+
30+
const TCPClient = ({ dns, protocol = 'tcp:', port = protocol === 'tls:' ? 853 : 53 } = {}) => {
31+
if (!protocols[protocol]) {
32+
throw new Error('Protocol must be tcp: or tls:');
33+
}
1734

18-
packet.questions.push({
19-
name,
20-
class : cls,
21-
type : Packet.TYPE[type],
22-
});
23-
const message = packet.toBuffer();
24-
const len = Buffer.alloc(2);
25-
len.writeUInt16BE(message.length);
26-
const client = tcp.connect({ host: dns, port });
27-
client.end(Buffer.concat([ len, message ]));
35+
return async (name, type, cls, options = {}) => {
36+
const message = makeQuery({ name, type, cls, ...options });
37+
const [host] = dns.split(':');
38+
const client = protocols[protocol](host, port);
39+
40+
sendQuery(client, message);
2841
const data = await Packet.readStream(client);
29-
if (!data.length) {
30-
throw new Error('Empty TCP response');
31-
}
42+
43+
if (!data.length) throw new Error('Empty response');
3244
return Packet.parse(data);
3345
};
3446
};
47+
48+
module.exports = TCPClient;

0 commit comments

Comments
 (0)