272 lines
8.0 KiB
Markdown
272 lines
8.0 KiB
Markdown
[![Build Status](https://secure.travis-ci.org/tjfontaine/node-dns.png)](http://travis-ci.org/tjfontaine/node-dns)
|
|
|
|
native-dns -- A replacement DNS stack for node.js
|
|
=================================================
|
|
|
|
Installation
|
|
------------
|
|
|
|
`npm install native-dns` and then `var dns = require('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](http://nodejs.org/docs/latest/api/dns.html)
|
|
it should behave similarly. If it doesn't please file an [issue](https://github.com/tjfontaine/node-dns/issues/new)
|
|
|
|
Request
|
|
-------
|
|
|
|
Beyond matching the upstream module, native-dns also provides a method for
|
|
customizing queries.
|
|
|
|
```javascript
|
|
var dns = require('../dns'),
|
|
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 indicating `udp` or `tcp` (optional, default `udp`)
|
|
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 an `EDNSPacket` (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 of `Packet`
|
|
* `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 for `lookup` and `resolve`,
|
|
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
|
|
|
|
```javascript
|
|
var dns = require('../dns'),
|
|
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` and `createUDPServer` -- both create a `UDP` based server,
|
|
they accept an optional object for configuration,
|
|
- `{ dgram_type: 'udp4' }` is the default option, the other is `udp6`
|
|
* `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` and `response` are instances of `Packet` 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 (see `consts.NAME_TO_RCODE`)
|
|
* `question` -- array of `Question`s
|
|
* `answer` -- array of `ResourceRecord`s
|
|
* `authority` -- array of `ResourceRecord`s
|
|
* `additional` -- array of `ResourceRecord`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, see `consts.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` and `AAAA`
|
|
- `address` -- string
|
|
* `MX`
|
|
- `priority` -- number
|
|
- `exchange` -- string
|
|
* `TXT`
|
|
- `data` -- string
|
|
* `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
|