UNPKG

doh-js-client

Version:

DNS-over-HTTPS/DNS-over-TLS client for nodejs.

101 lines (100 loc) 3.06 kB
"use strict"; exports.__esModule = true; var tls = require("tls"); var fs = require("fs"); var Packet = require("native-dns-packet"); var Util = require("./util"); function DoT(provider, keyPath, certPath) { Object.defineProperties(this, { providers: { value: { google: 'dns.google', cloudflare: '1.1.1.1', cleanbrowsing: '185.228.169.154', quad9: 'dns.quad9.net' }, writable: false }, key: { writable: true }, cert: { writable: true } }); if (typeof this.providers[provider] === 'undefined') { throw new Error('We only support these provider: google, cleanbrowsing, cloudflare'); } var key = fs.readFileSync(keyPath); var cert = fs.readFileSync(certPath); this.provider = provider; this.uri = this.providers[this.provider]; this.key = key; this.cert = cert; } DoT.prototype.getProviders = function () { return Object.keys(this.providers); }; DoT.prototype.setProvider = function (provider) { if (this.provider === provider) { return; } if (typeof this.providers[provider] === 'undefined') { throw new Error('We only support these provider: ' + this.getProviders().join(', ')); } this.provider = provider; this.uri = this.providers[this.provider]; }; // TODO: refactor socket and provider, multiple query and keepalive connection DoT.prototype.resolve = function (domainName, domainType) { var type = Util.getDomainType(domainType); var dnsPacket = new Packet(); var dnsBuf = Util.newBuffer(128); var msgBuf = Util.newBuffer(130); dnsPacket.question.push({ name: domainName, type: type, "class": 1 }); Packet.write(dnsBuf, dnsPacket); msgBuf[1] = 128; // copy dns buffer to message buffer dnsBuf.copy(msgBuf, 2, 0); var uri = this.uri; var key = this.key; var cert = this.cert; return new Promise(function (resolve, reject) { var options = { key: key, cert: cert, // ca: [], checkServerIdentity: function () { return null; } }; var socket = tls.connect(853, uri, options, function () { if (socket.authorized) { socket.write(msgBuf); } else { reject(new Error('socket authorized')); } }); socket.on('data', function (data) { var sign = data[0] & (1 << 7); var totalLength = (data & 0xFF) << 8 | data[1] & 0xFF; if (sign) { totalLength = 0xFFFF0000 | totalLength; } var result = Packet.parse(data.slice(2)); resolve(result.answer); }); socket.on('error', function (err) { reject(err); }); socket.on('end', function () { // finish query }); }); }; module.exports = DoT;