doh-js-client
Version:
DNS-over-HTTPS/DNS-over-TLS client for nodejs.
101 lines (100 loc) • 3.06 kB
JavaScript
;
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;