272 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			272 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| [](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
 |