node-dns
node-dns copied to clipboard
Replacement dns module in pure javascript for node.js
native-dns -- A replacement DNS stack for node.js
DEAD. See forks!
This project is dead.
Please see this issue: https://github.com/tjfontaine/node-dns/issues/111
Some forks have been created:
- Fork by @FrancisTurner: https://github.com/FrancisTurner/native-node-dns (relevant comment & other repos)
- Fork by @EduardoRuizM: https://github.com/EduardoRuizM/native-dnssec-dns (relevant comment)
- Tangerine by @titanism: https://github.com/forwardemail/tangerine (relevant comment)
Disclaimer: I, @taoeffect, have not revied the code in this fork, and am not responsible for any issues you may or may not run into. May it be a success!
(Below follows original README)
Installation
npm install native-dns
Client
native-dns exports what should be a 1:1 mapping of the upstream node.js dns module. That is to say if it's listed in the docs it should behave similarly. If it doesn't please file an issue.
Request
Beyond matching the upstream module, native-dns also provides a method for customizing queries.
var dns = require('native-dns');
var util = require('util');
var question = dns.Question({
name: 'www.google.com',
type: 'A',
});
var start = Date.now();
var req = dns.Request({
question: question,
server: { address: '8.8.8.8', port: 53, type: 'udp' },
timeout: 1000,
});
req.on('timeout', function () {
console.log('Timeout in making request');
});
req.on('message', function (err, answer) {
answer.answer.forEach(function (a) {
console.log(a.address);
});
});
req.on('end', function () {
var delta = (Date.now()) - start;
console.log('Finished processing request: ' + delta.toString() + 'ms');
});
req.send();
Request creation takes an object with the following fields
-
question
-- an instance of Question (required) -
server
-- defines the remote end point (required)
- as an object it should be
-
address
-- a string ip address (required) -
port
-- a number for the remote port (optional, default 53) -
type
-- a string indicatingudp
ortcp
(optional, defaultudp
) You do not need to indicate ipv4 or ipv6, the backend will handle that
-
- a string ip address
-
timeout
-- a number in milliseconds indicating how long to wait for the request to finish. (optional, default 4000) -
try_edns
-- a boolean indicating whether to use anEDNSPacket
(optional) -
cache
-- can be false to disable caching, or implement the cache model, or an instance of Cache but with a different store (optional, default platform.cache)
There are only two methods
-
send
-- sends the actual request to the remote endpoint -
cancel
-- cancels the request and ignores any responses
Request emits the following events
-
message
-- This is where you get a response, passes(err, answer)
where answer is an instance ofPacket
-
timeout
-- Fired when the timeout is reached -
cancelled
-- Fired if the request is cancelled -
end
-- Always fired after a request finished, regardless of disposition
Platform
If you want to customize all resolve
or lookup
s with the replacement client
stack you can modify the platform settings accessible in the top level platform
object.
Methods:
-
reload
-- Re-read system configuration files to populate name servers and hosts
Properties:
-
ready
-- Boolean whether requests are safe to transit, true after hosts and name servers are filled -
watching
-- Boolean indicating if system configuration files are watched for changes, default to false (currently can only be enabled on !win32) -
name_servers
-- An array of servers used for resolving queries against
- Each entry is an object of
{ address: <string ip>, port: 53 }
- On win32 this is hard coded to be google dns until there's a sane way to get the data
-
search_path
-- An array of domains to try and append after a failed lookup -
attempts
-- The number of retries for a failed lookup/timeout (default: 5) -
timeout
-- The time each query is allowed to take before trying another server. (in milliseconds, default: 5000 (5 seconds)) -
edns
-- Whether to try and send edns queries first (default: false) -
cache
-- The system wide cache used by default forlookup
andresolve
, set this to false to disable caching
Events:
-
ready
-- Emitted after hosts and name servers have been loaded -
unready
-- Emitted when hosts and name servers configuration is being reloaded.
Server
There is also a rudimentary server implementation
var dns = require('native-dns');
var server = dns.createServer();
server.on('request', function (request, response) {
//console.log(request)
response.answer.push(dns.A({
name: request.question[0].name,
address: '127.0.0.1',
ttl: 600,
}));
response.answer.push(dns.A({
name: request.question[0].name,
address: '127.0.0.2',
ttl: 600,
}));
response.additional.push(dns.A({
name: 'hostA.example.org',
address: '127.0.0.3',
ttl: 600,
}));
response.send();
});
server.on('error', function (err, buff, req, res) {
console.log(err.stack);
});
server.serve(15353);
Server creation
-
createServer
andcreateUDPServer
-- both create aUDP
based server, they accept an optional object for configuration,
-
{ dgram_type: 'udp4' }
is the default option, the other isudp6
-
createTCPServer
-- creates a TCP based server
Server methods
-
serve(port, [address])
-- specify which port and optional address to listen on -
close()
-- stop the server/close sockets.
Server events
-
listening
-- emitted when underlying socket is listening -
close
-- emitted when the underlying socket is closed -
request
-- emitted when a dns message is received, and the packet was successfully unpacked, passes(request, response)
- Both
request
andresponse
are instances ofPacket
when you're finished creating the response, you merely need to call.send()
and the packet will DoTheRightThing
-
error
-- emitted when unable to properly unpack the packet, passed(err, msg, response)
-
socketError
-- remap of the underlying socket for the server, passes(err, socket)
Packet
Properties:
-
header
-
id
-- request id -
qdcount
-- the number of questions (inferred from array size) -
ancount
-- the number of questions (inferred from array size) -
nscount
-- the number of questions (inferred from array size) -
arcount
-- the number of questions (inferred from array size) -
qr
-- is a query response -
opcode
-
aa
-- Authoritative Answer -
tc
-- Truncation bit -
rd
-- Recursion Desired -
ra
-- Recursion Available -
res1
-- Reserved field -
res2
-- Reserved field -
res3
-- Reserved field -
rcode
-- Response Code (seeconsts.NAME_TO_RCODE
)
-
question
-- array ofQuestion
s -
answer
-- array ofResourceRecord
s -
authority
-- array ofResourceRecord
s -
additional
-- array ofResourceRecord
s
Methods:
-
send()
-- Handles sending the packet to the right end point
Question
A Question
is instantiated by passing an object like:
-
name
-- i.e. 'www.google.com' (required) -
type
-- Either the string representation of the record type, or the integer value, seeconsts.NAME_TO_QTYPE
(default: 'A') -
class
-- The class of service, default to 1 meaning internet
ResourceRecord
ResourceRecords are what populate answer
, authority
, and additional
.
This is a generic type, and each derived type inherits the following properties:
-
name
-- The name of the resource -
type
-- The numerical representation of the resource record type -
class
-- The numerical representation of the class of service (usually 1 for internet) -
ttl
-- The Time To Live for the record, in seconds
Available Types:
-
SOA
-
primary
-- string -
admin
-- string -
serial
-- number -
refresh
-- number -
retry
-- number -
expiration
-- number -
minimum
-- number
-
A
andAAAA
-
address
-- string
-
MX
-
priority
-- number -
exchange
-- string
-
TXT
-
data
-- array of strings
-
SRV
-
priority
-- number -
weight
-- number -
port
-- number -
target
-- string
-
NS
-
data
-- string
-
CNAME
-
data
-- string
-
PTR
-
data
-- string
-
NAPTR
-
order
-- number -
preference
-- number -
flags
-- string -
service
-- string -
regexp
-- string -
replacement
-- string