Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

split packet parsing into its own library

  • Loading branch information...
commit 313df7b850b61f89e579c234262642e730a9911d 1 parent 8123c37
@tjfontaine authored
View
1  ChangeLog
@@ -1,6 +1,7 @@
2013-03-23 Timothy J Fontaine <tjfontaine@gmail.com>
* Add SPF record type, same as TXT
* Emit platform ready on windows (Oleg Elifantiev)
+ * Split packet parsing into its own library
2013-03-03 Timothy J Fontaine <tjfontaine@gmail.com>
* Assert missing fields
View
2  dns.js
@@ -38,7 +38,7 @@ exports.resolveNs = client.resolveNs;
exports.resolveCname = client.resolveCname;
exports.reverse = client.reverse;
-var consts = require('./lib/consts');
+var consts = require('native-dns-packet').consts;
exports.BADNAME = consts.BADNAME;
exports.BADRESP = consts.BADRESP;
exports.CONNREFUSED = consts.CONNREFUSED;
View
2  examples/client.js
@@ -42,7 +42,7 @@ request = dns.resolveNs('linode.com', function (err, results) {
});
});
-request = dns.resolveCname('www.google.com', function (err, results) {
+request = dns.resolveCname('www.nodejs.org', function (err, results) {
results.forEach(function (result) {
console.log('www.google.com -->', result);
});
View
32 lib/client.js
@@ -26,7 +26,7 @@ var ipaddr = require('ipaddr.js'),
EventEmitter = require('events').EventEmitter,
PendingRequests = require('./pending'),
Packet = require('./packet'),
- consts = require('./consts'),
+ consts = require('native-dns-packet').consts,
utils = require('./utils'),
platform = require('./platform');
@@ -109,7 +109,7 @@ Request.prototype.handleTimeout = function() {
Request.prototype.error = function(err) {
if (!this.fired) {
- debug('request error', this.id, this.question);
+ debug('request error', err, this.id, this.question);
this.emit('error', err);
this.done();
}
@@ -179,7 +179,20 @@ var Resolve = function(opts) {
this._started = false;
this._current_server = undefined;
+
this._server_list = [];
+ if (opts.remote) {
+ this._server_list.push({
+ address: opts.remote,
+ port: 53,
+ type: 'tcp',
+ });
+ this._server_list.push({
+ address: opts.remote,
+ port: 53,
+ type: 'udp',
+ });
+ }
this._request = undefined;
this._type = 'getHostByName';
@@ -258,7 +271,8 @@ Resolve.prototype._preStart = function() {
this._started = new Date().getTime();
this.try_edns = platform.edns;
- this._fillServers();
+ if (!this._server_list.length)
+ this._fillServers();
}
};
@@ -376,15 +390,20 @@ Resolve.prototype._handleTimeout = function() {
}
};
-var resolve = function(domain, rrtype, callback) {
+var resolve = function(domain, rrtype, ip, callback) {
var res;
if (!callback) {
+ callback = ip;
+ ip = undefined;
+ }
+
+ if (!callback) {
callback = rrtype;
rrtype = undefined;
}
- rrtype = consts.NAME_TO_QTYPE[rrtype || A];
+ rrtype = consts.NAME_TO_QTYPE[rrtype || 'A'];
if (rrtype === PTR) {
return reverse(domain, callback);
@@ -392,7 +411,8 @@ var resolve = function(domain, rrtype, callback) {
var opts = {
domain: domain,
- rrtype: rrtype
+ rrtype: rrtype,
+ remote: ip,
};
res = new Resolve(opts);
View
167 lib/consts.js
@@ -1,167 +0,0 @@
-// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com>
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE
-
-'use strict';
-
-function reverse_map(src) {
- var dst = {},
- k;
-
- for (k in src) {
- if (src.hasOwnProperty(k)) {
- dst[src[k]] = k;
- }
- }
- return dst;
-}
-
-/* http://www.iana.org/assignments/dns-parameters */
-var NAME_TO_QTYPE = exports.NAME_TO_QTYPE = {
- A: 1,
- NS: 2,
- MD: 3,
- MF: 4,
- CNAME: 5,
- SOA: 6,
- MB: 7,
- MG: 8,
- MR: 9,
- 'NULL': 10,
- WKS: 11,
- PTR: 12,
- HINFO: 13,
- MINFO: 14,
- MX: 15,
- TXT: 16,
- RP: 17,
- AFSDB: 18,
- X25: 19,
- ISDN: 20,
- RT: 21,
- NSAP: 22,
- 'NSAP-PTR': 23,
- SIG: 24,
- KEY: 25,
- PX: 26,
- GPOS: 27,
- AAAA: 28,
- LOC: 29,
- NXT: 30,
- EID: 31,
- NIMLOC: 32,
- SRV: 33,
- ATMA: 34,
- NAPTR: 35,
- KX: 36,
- CERT: 37,
- A6: 38,
- DNAME: 39,
- SINK: 40,
- OPT: 41,
- APL: 42,
- DS: 43,
- SSHFP: 44,
- IPSECKEY: 45,
- RRSIG: 46,
- NSEC: 47,
- DNSKEY: 48,
- DHCID: 49,
- NSEC3: 50,
- NSEC3PARAM: 51,
- HIP: 55,
- NINFO: 56,
- RKEY: 57,
- TALINK: 58,
- CDS: 59,
- SPF: 99,
- UINFO: 100,
- UID: 101,
- GID: 102,
- UNSPEC: 103,
- TKEY: 249,
- TSIG: 250,
- IXFR: 251,
- AXFR: 252,
- MAILB: 253,
- MAILA: 254,
- ANY: 255,
- URI: 256,
- CAA: 257,
- TA: 32768,
- DLV: 32769
-};
-exports.QTYPE_TO_NAME = reverse_map(NAME_TO_QTYPE);
-
-exports.nameToQtype = function(n) {
- return NAME_TO_QTYPE[n.toUpperCase()];
-};
-
-exports.qtypeToName = function(t) {
- return exports.QTYPE_TO_NAME[t];
-};
-
-var NAME_TO_QCLASS = exports.NAME_TO_QCLASS = {
- IN: 1
-};
-exports.QCLASS_TO_NAME = reverse_map(NAME_TO_QCLASS);
-
-exports.FAMILY_TO_QTYPE = {
- 4: NAME_TO_QTYPE.A,
- 6: NAME_TO_QTYPE.AAAA
-};
-exports.QTYPE_TO_FAMILY = {};
-exports.QTYPE_TO_FAMILY[exports.NAME_TO_QTYPE.A] = 4;
-exports.QTYPE_TO_FAMILY[exports.NAME_TO_QTYPE.AAAA] = 6;
-
-exports.NAME_TO_RCODE = {
- NOERROR: 0,
- FORMERR: 1,
- SERVFAIL: 2,
- NOTFOUND: 3,
- NOTIMP: 4,
- REFUSED: 5,
- YXDOMAIN: 6, //Name Exists when it should not
- YXRRSET: 7, //RR Set Exists when it should not
- NXRRSET: 8, //RR Set that should exist does not
- NOTAUTH: 9,
- NOTZONE: 10,
- BADVERS: 16,
- BADSIG: 16, // really?
- BADKEY: 17,
- BADTIME: 18,
- BADMODE: 19,
- BADNAME: 20,
- BADALG: 21,
- BADTRUNC: 22
-};
-exports.RCODE_TO_NAME = reverse_map(exports.NAME_TO_RCODE);
-
-exports.BADNAME = 'EBADNAME';
-exports.BADRESP = 'EBADRESP';
-exports.CONNREFUSED = 'ECONNREFUSED';
-exports.DESTRUCTION = 'EDESTRUCTION';
-exports.REFUSED = 'EREFUSED';
-exports.FORMERR = 'EFORMERR';
-exports.NODATA = 'ENODATA';
-exports.NOMEM = 'ENOMEM';
-exports.NOTFOUND = 'ENOTFOUND';
-exports.NOTIMP = 'ENOTIMP';
-exports.SERVFAIL = 'ESERVFAIL';
-exports.TIMEOUT = 'ETIMEOUT';
View
574 lib/packet.js
@@ -20,41 +20,15 @@
'use strict';
-var consts = require('./consts'),
- BufferCursor = require('buffercursor'),
- BufferCursorOverflow = BufferCursor.BufferCursorOverflow,
- ipaddr = require('ipaddr.js'),
- assert = require('assert'),
+var NDP = require('native-dns-packet'),
util = require('util');
-function assertUndefined(val, msg) {
- assert(typeof val != 'undefined', msg);
-}
-
var Packet = module.exports = function(socket) {
- this.header = {
- id: 0,
- qr: 0,
- opcode: 0,
- aa: 0,
- tc: 0,
- rd: 1,
- ra: 0,
- res1: 0,
- res2: 0,
- res3: 0,
- rcode: 0
- };
- this.question = [];
- this.answer = [];
- this.authority = [];
- this.additional = [];
- this.edns_options = [];
- this.payload = undefined;
+ NDP.call(this);
this.address = undefined;
-
this._socket = socket;
};
+util.inherits(Packet, NDP);
Packet.prototype.send = function() {
var buff, len, size;
@@ -70,540 +44,10 @@ Packet.prototype.send = function() {
this._socket.send(len);
};
-var LABEL_POINTER = 0xC0;
-
-var isPointer = function(len) {
- return (len & LABEL_POINTER) === LABEL_POINTER;
-};
-
-var name_unpack = function(buff, index) {
- var parts, len, start, pos, i, part, combine = [];
-
- start = buff.tell();
-
- parts = [];
- len = buff.readUInt8();
-
- while (len !== 0) {
- if (isPointer(len)) {
- len -= LABEL_POINTER;
- len = len << 8;
- pos = len + buff.readUInt8();
- parts.push({
- pos: pos,
- value: index[pos]
- });
- len = 0;
- } else {
- parts.push({
- pos: buff.tell() - 1,
- value: buff.toString('ascii', len)
- });
- len = buff.readUInt8();
- }
- }
-
- for (i = parts.length - 1; i >= 0; i--) {
- part = parts[i];
- combine.splice(0, 0, part.value);
- index[part.pos] = combine.join('.');
- }
-
- return combine.join('.');
-};
-
-var name_pack = function(str, buff, index) {
- var offset, dot, part;
-
- while (str) {
- if (index[str]) {
- offset = (LABEL_POINTER << 8) + index[str];
- buff.writeUInt16BE(offset);
- break;
- } else {
- index[str] = buff.tell();
- dot = str.indexOf('.');
- if (dot > -1) {
- part = str.slice(0, dot);
- str = str.slice(dot + 1);
- } else {
- part = str;
- str = undefined;
- }
- buff.writeUInt8(part.length);
- buff.write(part, part.length, 'ascii');
- }
- }
-
- if (!str) {
- buff.writeUInt8(0);
- }
-};
-
-Packet.write = function(buff, packet) {
- var state,
- next,
- name,
- val,
- section,
- count,
- pos,
- rdata_pos,
- last_resource,
- label_index = {};
-
- buff = BufferCursor(buff);
-
- if (typeof(packet.edns_version) !== 'undefined') {
- state = 'EDNS';
- } else {
- state = 'HEADER';
- }
-
- while (true) {
- try {
- switch (state) {
- case 'EDNS':
- val = {
- name: '',
- type: consts.NAME_TO_QTYPE.OPT,
- class: packet.payload
- };
- pos = packet.header.rcode;
- val.ttl = packet.header.rcode >> 4;
- packet.header.rcode = pos - (val.ttl << 4);
- val.ttl = (val.ttl << 8) + packet.edns_version;
- val.ttl = (val.ttl << 16) + (packet.do << 15) & 0x8000;
- packet.additional.splice(0, 0, val);
- state = 'HEADER';
- break;
- case 'HEADER':
- assert(packet.header, 'Packet requires "header"');
- buff.writeUInt16BE(packet.header.id & 0xFFFF);
- val = 0;
- val += (packet.header.qr << 15) & 0x8000;
- val += (packet.header.opcode << 11) & 0x7800;
- val += (packet.header.aa << 10) & 0x400;
- val += (packet.header.tc << 9) & 0x200;
- val += (packet.header.rd << 8) & 0x100;
- val += (packet.header.ra << 7) & 0x80;
- val += (packet.header.res1 << 6) & 0x40;
- val += (packet.header.res1 << 5) & 0x20;
- val += (packet.header.res1 << 4) & 0x10;
- val += packet.header.rcode & 0xF;
- buff.writeUInt16BE(val & 0xFFFF);
- // TODO assert on question.length > 1, in practice multiple questions
- // aren't used
- buff.writeUInt16BE(1);
- // answer offset 6
- buff.writeUInt16BE(packet.answer.length & 0xFFFF);
- // authority offset 8
- buff.writeUInt16BE(packet.authority.length & 0xFFFF);
- // additional offset 10
- buff.writeUInt16BE(packet.additional.length & 0xFFFF);
- state = 'QUESTION';
- break;
- case 'TRUNCATE':
- buff.seek(2);
- val = buff.readUInt16BE();
- val |= (1 << 9) & 0x200;
- buff.seek(2);
- buff.writeUInt16BE(val);
- switch (section) {
- case 'answer':
- pos = 6;
- // seek to authority and clear it and additional out
- buff.seek(8);
- buff.writeUInt16BE(0);
- buff.writeUInt16BE(0);
- break;
- case 'authority':
- pos = 8;
- // seek to additional and clear it out
- buff.seek(10);
- buff.writeUInt16BE(0);
- break;
- case 'additional':
- pos = 10;
- break;
- }
- buff.seek(pos);
- buff.writeUInt16BE(count - 1);
- buff.seek(last_resource);
- state = 'END';
- break;
- case 'NAME_PACK':
- name_pack(name, buff, label_index);
- state = next;
- break;
- case 'QUESTION':
- val = packet.question[0];
- assert(val, 'Packet requires a question');
- assertUndefined(val.name, 'Question requires a "name"');
- name = val.name;
- state = 'NAME_PACK';
- next = 'QUESTION_NEXT';
- break;
- case 'QUESTION_NEXT':
- assertUndefined(val.type, 'Question requires a "type"');
- assertUndefined(val.class, 'Questionn requires a "class"');
- buff.writeUInt16BE(val.type & 0xFFFF);
- buff.writeUInt16BE(val.class & 0xFFFF);
- state = 'RESOURCE_RECORD';
- section = 'answer';
- count = 0;
- break;
- case 'RESOURCE_RECORD':
- last_resource = buff.tell();
- if (packet[section].length == count) {
- switch (section) {
- case 'answer':
- section = 'authority';
- state = 'RESOURCE_RECORD';
- break;
- case 'authority':
- section = 'additional';
- state = 'RESOURCE_RECORD';
- break;
- case 'additional':
- state = 'END';
- break;
- }
- count = 0;
- } else {
- state = 'RESOURCE_WRITE';
- }
- break;
- case 'RESOURCE_WRITE':
- val = packet[section][count];
- assertUndefined(val.name, 'Resource record requires "name"');
- name = val.name;
- state = 'NAME_PACK';
- next = 'RESOURCE_WRITE_NEXT';
- break;
- case 'RESOURCE_WRITE_NEXT':
- assertUndefined(val.type, 'Resource record requires "type"');
- assertUndefined(val.class, 'Resource record requires "class"');
- assertUndefined(val.ttl, 'Resource record requires "ttl"');
- buff.writeUInt16BE(val.type & 0xFFFF);
- buff.writeUInt16BE(val.class & 0xFFFF);
- buff.writeUInt32BE(val.ttl & 0xFFFFFFFF);
-
- // where the rdata length goes
- rdata_pos = buff.tell();
- buff.writeUInt16BE(0);
-
- state = consts.QTYPE_TO_NAME[val.type];
- break;
- case 'RESOURCE_DONE':
- pos = buff.tell();
- buff.seek(rdata_pos);
- buff.writeUInt16BE(pos - rdata_pos - 2);
- buff.seek(pos);
- count += 1;
- state = 'RESOURCE_RECORD';
- break;
- case 'A':
- case 'AAAA':
- //TODO XXX FIXME -- assert that address is of proper type
- assertUndefined(val.address, 'A/AAAA record requires "address"');
- val = ipaddr.parse(val.address).toByteArray();
- val.forEach(function(b) {
- buff.writeUInt8(b);
- });
- state = 'RESOURCE_DONE';
- break;
- case 'NS':
- case 'CNAME':
- case 'PTR':
- assertUndefined(val.data, 'NS/CNAME/PTR record requires "data"');
- name = val.data;
- state = 'NAME_PACK';
- next = 'RESOURCE_DONE';
- break;
- case 'SPF':
- case 'TXT':
- //TODO XXX FIXME -- split on max char string and loop
- assertUndefined(val.data, 'TXT record requires "data"');
- buff.writeUInt8(val.data.length);
- buff.write(val.data, val.data.length, 'ascii');
- state = 'RESOURCE_DONE';
- break;
- case 'MX':
- assertUndefined(val.priority, 'MX record requires "priority"');
- assertUndefined(val.exchange, 'MX record requires "exchange"');
- buff.writeUInt16BE(val.priority & 0xFFFF);
- name = val.exchange;
- state = 'NAME_PACK';
- next = 'RESOURCE_DONE';
- break;
- case 'SRV':
- assertUndefined(val.priority, 'SRV record requires "priority"');
- assertUndefined(val.weight, 'SRV record requires "weight"');
- assertUndefined(val.port, 'SRV record requires "port"');
- assertUndefined(val.target, 'SRV record requires "target"');
- buff.writeUInt16BE(val.priority & 0xFFFF);
- buff.writeUInt16BE(val.weight & 0xFFFF);
- buff.writeUInt16BE(val.port & 0xFFFF);
- name = val.target;
- state = 'NAME_PACK';
- next = 'RESOURCE_DONE';
- break;
- case 'SOA':
- assertUndefined(val.primary, 'SOA record requires "primary"');
- name = val.primary;
- state = 'NAME_PACK';
- next = 'SOA_ADMIN';
- break;
- case 'SOA_ADMIN':
- assertUndefined(val.admin, 'SOA record requires "admin"');
- name = val.admin;
- state = 'NAME_PACK';
- next = 'SOA_NEXT';
- break;
- case 'SOA_NEXT':
- assertUndefined(val.serial, 'SOA record requires "serial"');
- assertUndefined(val.refresh, 'SOA record requires "refresh"');
- assertUndefined(val.retry, 'SOA record requires "retry"');
- assertUndefined(val.expiration, 'SOA record requires "expiration"');
- assertUndefined(val.minimum, 'SOA record requires "minimum"');
- buff.writeUInt32BE(val.serial & 0xFFFFFFFF);
- buff.writeInt32BE(val.refresh & 0xFFFFFFFF);
- buff.writeInt32BE(val.retry & 0xFFFFFFFF);
- buff.writeInt32BE(val.expiration & 0xFFFFFFFF);
- buff.writeInt32BE(val.minimum & 0xFFFFFFFF);
- state = 'RESOURCE_DONE';
- break;
- case 'OPT':
- while (packet.edns_options.length) {
- val = packet.edns_options.pop();
- buff.writeUInt16BE(val.code);
- buff.writeUInt16BE(val.data.length);
- for (pos = 0; pos < val.data.length; pos++) {
- buff.writeUInt8(val.data.readUInt8(pos));
- }
- }
- state = 'RESOURCE_DONE';
- break;
- case 'NAPTR':
- assertUndefined(val.order, 'NAPTR record requires "order"');
- assertUndefined(val.preference, 'NAPTR record requires "preference"');
- assertUndefined(val.flags, 'NAPTR record requires "flags"');
- assertUndefined(val.service, 'NAPTR record requires "service"');
- assertUndefined(val.regexp, 'NAPTR record requires "regexp"');
- assertUndefined(val.replacement, 'NAPTR record requires "replacement"');
- buff.writeUInt16BE(val.order & 0xFFFF);
- buff.writeUInt16BE(val.preference & 0xFFFF);
- buff.writeUInt8(val.flags.length);
- buff.write(val.flags, val.flags.length, 'ascii');
- buff.writeUInt8(val.service.length);
- buff.write(val.service, val.service.length, 'ascii');
- buff.writeUInt8(val.regexp.length);
- buff.write(val.regexp, val.regexp.length, 'ascii');
- buff.writeUInt8(val.replacement.length);
- buff.write(val.replacement, val.replacement.length, 'ascii');
- state = 'RESOURCE_DONE';
- break;
- case 'END':
- return buff.tell();
- break;
- default:
- throw new Error('WTF No State While Writing');
- break;
- }
- } catch (e) {
- if (e instanceof BufferCursorOverflow) {
- state = 'TRUNCATE';
- } else {
- throw e;
- }
- }
- }
-};
-
-Packet.parse = function(msg, socket) {
- var state,
- len,
- pos,
- val,
- rdata_len,
- rdata,
- label_index = {},
- counts = {},
- section,
- count;
-
- var packet = new Packet(socket);
-
- pos = 0;
- state = 'HEADER';
-
- msg = BufferCursor(msg);
- len = msg.length;
+Packet.parse = function (msg, socket) {
+ var p = NDP.parse(msg);
+ p._socket = socket;
+ return p;
+}
- while (true) {
- switch (state) {
- case 'HEADER':
- packet.header.id = msg.readUInt16BE();
- val = msg.readUInt16BE();
- packet.header.qr = (val & 0x8000) >> 15;
- packet.header.opcode = (val & 0x7800) >> 11;
- packet.header.aa = (val & 0x400) >> 10;
- packet.header.tc = (val & 0x200) >> 9;
- packet.header.rd = (val & 0x100) >> 8;
- packet.header.ra = (val & 0x80) >> 7;
- packet.header.res1 = (val & 0x40) >> 6;
- packet.header.res2 = (val & 0x20) >> 5;
- packet.header.res3 = (val & 0x10) >> 4;
- packet.header.rcode = (val & 0xF);
- counts.qdcount = msg.readUInt16BE();
- counts.ancount = msg.readUInt16BE();
- counts.nscount = msg.readUInt16BE();
- counts.arcount = msg.readUInt16BE();
- state = 'QUESTION';
- break;
- case 'QUESTION':
- val = {};
- val.name = name_unpack(msg, label_index);
- val.type = msg.readUInt16BE();
- val.class = msg.readUInt16BE();
- packet.question.push(val);
- // TODO handle qdcount > 0 in practice no one sends this
- state = 'RESOURCE_RECORD';
- section = 'answer';
- count = 'ancount';
- break;
- case 'RESOURCE_RECORD':
- if (counts[count] === packet[section].length) {
- switch (section) {
- case 'answer':
- section = 'authority';
- count = 'nscount';
- break;
- case 'authority':
- section = 'additional';
- count = 'arcount';
- break;
- case 'additional':
- state = 'END';
- break;
- }
- } else {
- state = 'RR_UNPACK';
- }
- break;
- case 'RR_UNPACK':
- val = {};
- val.name = name_unpack(msg, label_index);
- val.type = msg.readUInt16BE();
- val.class = msg.readUInt16BE();
- val.ttl = msg.readUInt32BE();
- rdata_len = msg.readUInt16BE();
- rdata = msg.slice(rdata_len);
- state = consts.QTYPE_TO_NAME[val.type];
- break;
- case 'RESOURCE_DONE':
- packet[section].push(val);
- state = 'RESOURCE_RECORD';
- break;
- case 'A':
- val.address = new ipaddr.IPv4(rdata.toByteArray());
- val.address = val.address.toString();
- state = 'RESOURCE_DONE';
- break;
- case 'AAAA':
- val.address = new ipaddr.IPv6(rdata.toByteArray('readUInt16BE'));
- val.address = val.address.toString();
- state = 'RESOURCE_DONE';
- break;
- case 'NS':
- case 'CNAME':
- case 'PTR':
- pos = msg.tell();
- msg.seek(pos - rdata_len);
- val.data = name_unpack(msg, label_index);
- msg.seek(pos);
- state = 'RESOURCE_DONE';
- break;
- case 'SPF':
- case 'TXT':
- val.data = '';
- while (!rdata.eof()) {
- val.data += rdata.toString('ascii', rdata.readUInt8());
- }
- state = 'RESOURCE_DONE';
- break;
- case 'MX':
- val.priority = rdata.readUInt16BE();
- pos = msg.tell();
- msg.seek(pos - rdata_len + rdata.tell());
- val.exchange = name_unpack(msg, label_index);
- msg.seek(pos);
- state = 'RESOURCE_DONE';
- break;
- case 'SRV':
- val.priority = rdata.readUInt16BE();
- val.weight = rdata.readUInt16BE();
- val.port = rdata.readUInt16BE();
- pos = msg.tell();
- msg.seek(pos - rdata_len + rdata.tell());
- val.target = name_unpack(msg, label_index);
- msg.seek(pos);
- state = 'RESOURCE_DONE';
- break;
- case 'SOA':
- pos = msg.tell();
- msg.seek(pos - rdata_len + rdata.tell());
- val.primary = name_unpack(msg, label_index);
- val.admin = name_unpack(msg, label_index);
- rdata.seek(msg.tell() - (pos - rdata_len + rdata.tell()));
- msg.seek(pos);
- val.serial = rdata.readUInt32BE();
- val.refresh = rdata.readInt32BE();
- val.retry = rdata.readInt32BE();
- val.expiration = rdata.readInt32BE();
- val.minimum = rdata.readInt32BE();
- state = 'RESOURCE_DONE';
- break;
- case 'OPT':
- // assert first entry in additional
- counts[count] -= 1;
- packet.payload = val.class;
- pos = msg.tell();
- msg.seek(pos - 6);
- packet.header.rcode = (msg.readUInt8() << 4) + packet.header.rcode;
- packet.edns_version = msg.readUInt8();
- val = msg.readUInt16BE();
- msg.seek(pos);
- packet.do = (val & 0x8000) << 15;
- while (!rdata.eof()) {
- packet.edns_options.push({
- code: rdata.readUInt16BE(),
- data: rdata.slice(rdata.readUInt16BE()).buffer
- });
- }
- state = 'RESOURCE_RECORD';
- break;
- case 'NAPTR':
- val.order = rdata.readUInt16BE();
- val.preference = rdata.readUInt16BE();
- pos = rdata.readUInt8();
- val.flags = rdata.toString('ascii', pos);
- pos = rdata.readUInt8();
- val.service = rdata.toString('ascii', pos);
- pos = rdata.readUInt8();
- val.regexp = rdata.toString('ascii', pos);
- pos = rdata.readUInt8();
- val.replacement = rdata.toString('ascii', pos);
- state = 'RESOURCE_DONE';
- break;
- case 'END':
- return packet;
- break;
- default:
- //console.log(state, val);
- state = 'RESOURCE_DONE';
- break;
- }
- }
-};
+Packet.write = NDP.write;
View
2  lib/pending.js
@@ -24,7 +24,7 @@ var net = require('net'),
util = require('util'),
EventEmitter = require('events').EventEmitter,
Packet = require('./packet'),
- consts = require('./consts'),
+ consts = require('native-dns-packet').consts,
UDPSocket = require('./utils').UDPSocket,
TCPSocket = require('./utils').TCPSocket;
View
2  lib/platform.js
@@ -26,7 +26,7 @@ var fs = require('fs'),
os = require('os'),
util = require('util'),
Cache = require('./cache'),
- consts = require('./consts'),
+ consts = require('native-dns-packet').consts,
path = require('path'),
utils = require('./utils');
View
2  lib/utils.js
@@ -208,7 +208,7 @@ var ensure_absolute = exports.ensure_absolute = function (f) {
return f;
};
-var CNAME = require('./consts').NAME_TO_QTYPE.CNAME;
+var CNAME = require('native-dns-packet').consts.NAME_TO_QTYPE.CNAME;
var Lookup = exports.Lookup = function (store, zone, question, cb) {
if (!(this instanceof Lookup))
View
6 package.json
@@ -1,6 +1,6 @@
{
"name": "native-dns",
- "version": "0.4.1",
+ "version": "0.5.0",
"author": "Timothy J Fontaine <tjfontaine@gmail.com> (http://atxconsulting.com)",
"description": "Replacement for the core DNS module, includes server implementation",
"keywords": [
@@ -24,9 +24,9 @@
"test": "nodeunit test"
},
"dependencies": {
- "buffercursor": ">= 0.0.5",
"binaryheap": ">= 0.0.2",
- "ipaddr.js": ">= 0.1.1"
+ "ipaddr.js": ">= 0.1.1",
+ "native-dns-packet": ">= 0.0.1"
},
"devDependencies": {
"optimist": "",
Please sign in to comment.
Something went wrong with that request. Please try again.