dig.js/dns-request.js

102 lines
2.6 KiB
JavaScript

'use strict';
var dnsjs = require('dns-suite');
var crypto = require('crypto');
var dgram = require('dgram');
function request(queryAb, opts) {
var handlers = {};
var nameservers;
var nameserver = opts.nameserver;
var index;
var udpType;
var receivedMessage;
if (!nameserver) {
nameservers = require('dns').getServers();
index = crypto.randomBytes(2).readUInt16BE(0) % nameservers.length;
nameserver = nameservers[index];
}
udpType = /:/.test(nameserver) ? 'udp6' : 'udp4';
var server = dgram.createSocket({
type: udpType
, reuseAddr: true
});
server.nameserver = nameserver;
handlers.onError = function (err) {
if (opts.onError) { opts.onError(err); } else { throw err; }
server.close();
};
handlers.onMessage = function (bin) {
receivedMessage = true;
if (!opts.mdns) {
clearTimeout(server._timeoutToken);
server.close();
}
if (opts.onMessage) { opts.onMessage(bin); }
};
handlers.onListening = function () {
/*jshint validthis:true*/
var server = this;
if (opts.mdns || '224.0.0.251' === server.nameserver) {
server.setBroadcast(true);
server.addMembership(server.nameserver || '224.0.0.251');
}
if (opts.onListening) { opts.onListening.apply(server); }
server.send(Buffer.from(queryAb), opts.port, server.nameserver, function () {
if (opts.onSent) { opts.onSent({ port: opts.port, nameserver: server.nameserver }); }
});
};
handlers.onClose = function () {
if (opts.onClose) { opts.onClose(); }
};
server.on('error', handlers.onError);
server.on('message', handlers.onMessage);
server.on('listening', handlers.onListening);
server.on('close', handlers.onClose);
// 0 dns request
// 53 dns server
// 5353 mdns
if (opts.mdns) {
server.bind(opts.port /*5353*/);
}
else {
server.bind(0);
}
var ms = opts.timeout || (5 * 1000);
server._timeoutToken = setTimeout(function () {
if (!receivedMessage && opts.onTimeout) { opts.onTimeout({ timeout: ms }); }
server.close();
}, ms);
}
function requestJson(query, opts) {
var queryAb = dnsjs.DNSPacket.write(query);
var options = {
onError: opts.onError
, onMessage: function (nb) {
var packet = dnsjs.DNSPacket.parse(nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength));
opts.onMessage(packet);
}
, onListening: opts.onListening
, onSent: opts.onSent
, mdns: opts.mdns
, nameserver: opts.nameserver
, port: opts.port
, timeout: opts.timeout
};
return request(queryAb, options);
}
module.exports.resolve = request;
module.exports.request = request;
module.exports.requestJson = requestJson;