From 4e3cf05d29805560ebe30c063978e23ffd983cde Mon Sep 17 00:00:00 2001 From: Fabian Stamm Date: Thu, 17 May 2018 10:01:56 +0200 Subject: [PATCH] Refactoring and adding Question class --- lib/request.d.ts | 137 +++++------------- lib/request.js | 287 ++++++++++++++++---------------------- lib/request.js.map | 2 +- lib/types.d.ts | 102 +++++++++++++- lib/types.js | 99 ++++++++++++-- lib/types.js.map | 2 +- src/request.ts | 335 ++++++++++++++++++--------------------------- src/types.ts | 133 ++++++++++++++++-- 8 files changed, 597 insertions(+), 500 deletions(-) diff --git a/lib/request.d.ts b/lib/request.d.ts index e3bc2eb..ce27890 100644 --- a/lib/request.d.ts +++ b/lib/request.d.ts @@ -1,113 +1,49 @@ /// -import { Message, MessageHeader, MessageQuestion, MessageRecourceRecord, ErrorCodes } from "./types"; -export declare enum QueryTypes { - /** - * IPv4 address - */ - A = 1, - /** - * Nameserver - */ - NS = 2, - /** - * Obsolete - */ - MD = 3, - /** - * Obsolete - */ - MF = 4, - /** - * Alias - */ - CNAME = 5, - /** - * Start of authority - */ - SOA = 6, - /** - * Experimental - */ - MB = 7, - /** - * Experimental - */ - MG = 8, - /** - * Experimental - */ - MR = 9, - /** - * Experimental - */ - NULL = 10, - /** - * Service description - */ - WKS = 11, - /** - * Reverse entry (inaddr.arpa) - */ - PTR = 12, - /** - * Host information - */ - HINFO = 13, - /** - * Mailbox / Mail-list information - */ - MINFO = 14, - /** - * Mail exchange - */ - MX = 15, - /** - * Text strings - */ - TXT = 16, - /** - * IPv6 address - */ - AAAA = 28, - /** - * SRV records - */ - SRV = 33, - /** - * Request to transfer entire zone - */ - AXFR = 252, - /** - * Request for mailbox related records - */ - MAILA = 254, - /** - * Request for mail agend RRs - */ - MAILB = 253, - /** - * Any class - */ - ANY = 255, -} -export declare function SerializeName(name: string): Buffer; -export declare class Request implements Message { +import { IMessage, IMessageHeader, IMessageQuestion, MessageRecourceRecord, ErrorCodes } from "./types"; +export declare function parseHeader(data: Buffer): IMessageHeader; +export declare function parseQuestions(count: number, packet: Buffer): IMessageQuestion[]; +export declare function serializeName(name: string): Buffer; +export declare class Request implements IMessage { private sendCallback; + private max_size; private _header; - readonly header: MessageHeader; + readonly header: Header; private _questions; - readonly questions: MessageQuestion[]; + readonly questions: Question[]; answers: RecourceRecord[]; authorities: RecourceRecord[]; additionals: RecourceRecord[]; - constructor(packet: Buffer, sendCallback: (packet: Buffer) => any); + constructor(packet: Buffer, sendCallback: (packet: Buffer) => any, max_size?: number); error(error: ErrorCodes): void; noRecursion(): void; send(): void; - serialize(truncate?: boolean, rcode?: 0 | 1 | 2 | 3 | 4 | 5): Buffer; - private serializeHeader(); - private serializeQuestion(question); - private serializeResourceRecord(record); + serialize(): Buffer; +} +export declare class Header implements IMessageHeader { + ID: number; + QR: 0 | 1; + OPCODE: number; + AA: 0 | 1; + TC: 0 | 1; + RD: 0 | 1; + RA: 0 | 1; + Z: 0 | 1; + AD: 0 | 1; + CD: 0 | 1; + RCODE: ErrorCodes; + QDCOUNT: number; + ANCOUNT: number; + NSCOUNT: number; + ARCOUNT: number; + constructor(header: IMessageHeader); + serialize(): Buffer; +} +export declare class Question implements IMessageQuestion { + QNAME: string; + QTYPE: number; + QCLASS: number; + constructor(question: IMessageQuestion); + serialize(): Buffer; } export declare class RecourceRecord implements MessageRecourceRecord { /** @@ -123,4 +59,5 @@ export declare class RecourceRecord implements MessageRecourceRecord { TTL: number; RDATA: Buffer; readonly RDLENGTH: number; + serialize(): Buffer; } diff --git a/lib/request.js b/lib/request.js index 2dd7857..21983cd 100644 --- a/lib/request.js +++ b/lib/request.js @@ -2,98 +2,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); const binary_parser_1 = require("binary-parser"); const types_1 = require("./types"); -const MAX_LABEL_SIZE = 63; -var QueryTypes; -(function (QueryTypes) { - /** - * IPv4 address - */ - QueryTypes[QueryTypes["A"] = 1] = "A"; - /** - * Nameserver - */ - QueryTypes[QueryTypes["NS"] = 2] = "NS"; - /** - * Obsolete - */ - QueryTypes[QueryTypes["MD"] = 3] = "MD"; - /** - * Obsolete - */ - QueryTypes[QueryTypes["MF"] = 4] = "MF"; - /** - * Alias - */ - QueryTypes[QueryTypes["CNAME"] = 5] = "CNAME"; - /** - * Start of authority - */ - QueryTypes[QueryTypes["SOA"] = 6] = "SOA"; - /** - * Experimental - */ - QueryTypes[QueryTypes["MB"] = 7] = "MB"; - /** - * Experimental - */ - QueryTypes[QueryTypes["MG"] = 8] = "MG"; - /** - * Experimental - */ - QueryTypes[QueryTypes["MR"] = 9] = "MR"; - /** - * Experimental - */ - QueryTypes[QueryTypes["NULL"] = 10] = "NULL"; - /** - * Service description - */ - QueryTypes[QueryTypes["WKS"] = 11] = "WKS"; - /** - * Reverse entry (inaddr.arpa) - */ - QueryTypes[QueryTypes["PTR"] = 12] = "PTR"; - /** - * Host information - */ - QueryTypes[QueryTypes["HINFO"] = 13] = "HINFO"; - /** - * Mailbox / Mail-list information - */ - QueryTypes[QueryTypes["MINFO"] = 14] = "MINFO"; - /** - * Mail exchange - */ - QueryTypes[QueryTypes["MX"] = 15] = "MX"; - /** - * Text strings - */ - QueryTypes[QueryTypes["TXT"] = 16] = "TXT"; - /** - * IPv6 address - */ - QueryTypes[QueryTypes["AAAA"] = 28] = "AAAA"; - /** - * SRV records - */ - QueryTypes[QueryTypes["SRV"] = 33] = "SRV"; - /** - * Request to transfer entire zone - */ - QueryTypes[QueryTypes["AXFR"] = 252] = "AXFR"; - /** - * Request for mailbox related records - */ - QueryTypes[QueryTypes["MAILA"] = 254] = "MAILA"; - /** - * Request for mail agend RRs - */ - QueryTypes[QueryTypes["MAILB"] = 253] = "MAILB"; - /** - * Any class - */ - QueryTypes[QueryTypes["ANY"] = 255] = "ANY"; -})(QueryTypes = exports.QueryTypes || (exports.QueryTypes = {})); const headerParser = new binary_parser_1.Parser() .endianess("big") .uint16("ID") @@ -111,6 +19,15 @@ const headerParser = new binary_parser_1.Parser() .uint16("ANCOUNT") .uint16("NSCOUNT") .uint16("ARCOUNT"); +function parseHeader(data) { + try { + return headerParser.parse(data); + } + catch (e) { + throw new Error("Header parsing failed" + e.message); + } +} +exports.parseHeader = parseHeader; const labelParser = new binary_parser_1.Parser() .endianess("big") .uint8("dataLength") @@ -133,14 +50,21 @@ const questionParser = new binary_parser_1.Parser() .uint16("QTYPE") .uint16("QCLASS"); function parseQuestions(count, packet) { - return new binary_parser_1.Parser() - .endianess("big") - .array("questions", { - type: questionParser, - length: count - }).parse(packet).questions; + try { + return new binary_parser_1.Parser() + .endianess("big") + .array("questions", { + type: questionParser, + length: count + }).parse(packet).questions; + } + catch (e) { + throw new Error("Question parsing failed" + e.message); + } } -function SerializeName(name) { +exports.parseQuestions = parseQuestions; +const MAX_LABEL_SIZE = 63; +function serializeName(name) { let length = 0; let parts = name.split("."); parts.forEach(e => { @@ -161,10 +85,11 @@ function SerializeName(name) { data.writeUInt8(0, offset); return data; } -exports.SerializeName = SerializeName; +exports.serializeName = serializeName; class Request { - constructor(packet, sendCallback) { + constructor(packet, sendCallback, max_size = 512) { this.sendCallback = sendCallback; + this.max_size = max_size; this.answers = []; this.authorities = []; this.additionals = []; @@ -172,17 +97,17 @@ class Request { packet.copy(headerData, 0, 0, 12); let bodyData = Buffer.alloc(packet.length - 12); packet.copy(bodyData, 0, 12, packet.length); - this._header = headerParser.parse(headerData); + this._header = new Header(parseHeader(headerData)); this._header.AD = 0; this._header.RCODE = types_1.ErrorCodes.NoError; this._header.RA = this._header.RD; - this._questions = parseQuestions(this._header.QDCOUNT, bodyData); + this._questions = parseQuestions(this._header.QDCOUNT, bodyData).map(e => new Question(e)); } get header() { return Object.assign({}, this._header); } get questions() { - return this._questions.map(e => e); + return this._questions.map(e => Object.assign({}, e)); } error(error) { if (this._header.RCODE === types_1.ErrorCodes.NoError) @@ -194,37 +119,43 @@ class Request { send() { this.sendCallback(this.serialize()); } - serialize(truncate = false, rcode = 0) { + serialize() { this._header.AA = 1; this._header.ANCOUNT = this.answers.length; this._header.ARCOUNT = this.additionals.length; this._header.NSCOUNT = this.authorities.length; this._header.QR = 1; - this._header.RCODE = rcode; - let questions = this.questions.map(this.serializeQuestion, this); - let answers = this.answers.map(this.serializeResourceRecord, this); - let authority = this.authorities.map(this.serializeResourceRecord, this); - let additional = this.additionals.map(this.serializeResourceRecord, this); - let questionsByteLength = 0; - questions.forEach(e => questionsByteLength += e.length); - let answersByteLength = 0; - answers.forEach(e => answersByteLength += e.length); - let authorityByteLength = 0; - authority.forEach(e => authorityByteLength += e.length); - let additionalByteLength = 0; - additional.forEach(e => additionalByteLength += e.length); - let length = 12 + questionsByteLength + answersByteLength + authorityByteLength + additionalByteLength; //Header is always 12 byte large - if (truncate && length > 512) { + let questions = this._questions.map(e => e.serialize()); + let answers = this.answers.map(e => e.serialize()); + let authority = this.authorities.map(e => e.serialize()); + let additional = this.additionals.map(e => e.serialize()); + let length = 12; + questions.forEach(e => length += e.length); + answers.forEach(e => length += e.length); + authority.forEach(e => length += e.length); + additional.forEach(e => length += e.length); + // let questionsByteLength = 0; + // questions.forEach(e => questionsByteLength += e.length); + // let answersByteLength = 0; + // answers.forEach(e => answersByteLength += e.length) + // let authorityByteLength = 0; + // authority.forEach(e => authorityByteLength += e.length) + // let additionalByteLength = 0; + // additional.forEach(e => additionalByteLength += e.length) + // let length = 12 + questionsByteLength + answersByteLength + authorityByteLength + additionalByteLength; //Header is always 12 byte large + if (length > this.max_size) { this._header.TC = 1; - //Buffer will ignore data that exeeds the max buffer length - length = 512; + //Will ignore data, that exceeds length + length = this.max_size; } - let header = this.serializeHeader(); + let header = this._header.serialize(); let data = Buffer.alloc(length); let offset = 0; let append = (buffer) => { - buffer.copy(data, offset, 0, buffer.length); - offset += buffer.length; + if (offset <= length) { + buffer.copy(data, offset, 0, buffer.length); + offset += buffer.length; + } }; append(header); questions.forEach(append); @@ -233,57 +164,55 @@ class Request { additional.forEach(append); return data; } - serializeHeader() { - let header = this.header; +} +exports.Request = Request; +class Header { + constructor(header) { + for (let k in header) { + this[k] = header[k]; + } + } + serialize() { let data = Buffer.alloc(12); - data.writeUInt16BE(header.ID, 0); + data.writeUInt16BE(this.ID, 0); var f = 0x0000; - f = f | (header.QR << 15); - f = f | (header.OPCODE << 11); - f = f | (header.AA << 10); - f = f | (header.TC << 9); - f = f | (header.RD << 8); - f = f | (header.RA << 7); - f = f | (header.Z << 6); - f = f | (header.AD << 5); - f = f | (header.CD << 4); - f = f | header.RCODE; + f = f | (this.QR << 15); + f = f | (this.OPCODE << 11); + f = f | (this.AA << 10); + f = f | (this.TC << 9); + f = f | (this.RD << 8); + f = f | (this.RA << 7); + f = f | (this.Z << 6); + f = f | (this.AD << 5); + f = f | (this.CD << 4); + f = f | this.RCODE; data.writeUInt16BE(f, 2); - data.writeUInt16BE(header.QDCOUNT, 4); - data.writeUInt16BE(header.ANCOUNT, 6); - data.writeUInt16BE(header.NSCOUNT, 8); - data.writeUInt16BE(header.ARCOUNT, 10); - return data; - } - serializeQuestion(question) { - let qname = SerializeName(question.QNAME); - let data = Buffer.alloc(qname.length + 4); - qname.copy(data, 0, 0, qname.length); - let offset = qname.length; - data.writeUInt16BE(question.QTYPE, offset); - offset += 2; - data.writeUInt16BE(question.QCLASS, offset); - return data; - } - serializeResourceRecord(record) { - // TODO: Implement compression - let name = SerializeName(record.NAME); - let data = Buffer.alloc(name.length + 10 + record.RDLENGTH); // For TYPE, CLASS, TTL, RLENGTH - name.copy(data, 0, 0, name.length); - let offset = name.length; - data.writeUInt16BE(record.TYPE, offset); - offset += 2; - data.writeUInt16BE(record.CLASS, offset); - offset += 2; - data.writeUInt32BE(record.TTL, offset); - offset += 4; - data.writeUInt16BE(record.RDLENGTH, offset); - offset += 2; - record.RDATA.copy(data, offset, 0, record.RDLENGTH); + data.writeUInt16BE(this.QDCOUNT, 4); + data.writeUInt16BE(this.ANCOUNT, 6); + data.writeUInt16BE(this.NSCOUNT, 8); + data.writeUInt16BE(this.ARCOUNT, 10); return data; } } -exports.Request = Request; +exports.Header = Header; +class Question { + constructor(question) { + for (let k in question) { + this[k] = question[k]; + } + } + serialize() { + let qname = serializeName(this.QNAME); + let data = Buffer.alloc(qname.length + 4); + qname.copy(data, 0, 0, qname.length); + let offset = qname.length; + data.writeUInt16BE(this.QTYPE, offset); + offset += 2; + data.writeUInt16BE(this.QCLASS, offset); + return data; + } +} +exports.Question = Question; class RecourceRecord { set TYPE(value) { if (value < 0 || value > 65535) @@ -304,6 +233,7 @@ class RecourceRecord { set TTL(value) { if (value < 0 || value > 4294967295) throw new TypeError("TTL Range: 0 - 4.294.967.295"); + this._TTL = value; } get TTL() { return this._TTL; @@ -311,6 +241,23 @@ class RecourceRecord { get RDLENGTH() { return this.RDATA.length; } + serialize() { + // TODO: Implement compression + let name = serializeName(this.NAME); + let data = Buffer.alloc(name.length + 10 + this.RDLENGTH); // For TYPE, CLASS, TTL, RLENGTH + name.copy(data, 0, 0, name.length); + let offset = name.length; + data.writeUInt16BE(this.TYPE, offset); + offset += 2; + data.writeUInt16BE(this.CLASS, offset); + offset += 2; + data.writeUInt32BE(this._TTL, offset); + offset += 4; + data.writeUInt16BE(this.RDLENGTH, offset); + offset += 2; + this.RDATA.copy(data, offset, 0, this.RDLENGTH); + return data; + } } exports.RecourceRecord = RecourceRecord; //# sourceMappingURL=request.js.map \ No newline at end of file diff --git a/lib/request.js.map b/lib/request.js.map index 2d1b5d4..f5c2f7d 100644 --- a/lib/request.js.map +++ b/lib/request.js.map @@ -1 +1 @@ -{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/lib/types.d.ts b/lib/types.d.ts index 1b022d4..934294c 100644 --- a/lib/types.d.ts +++ b/lib/types.d.ts @@ -25,7 +25,97 @@ export declare enum ErrorCodes { */ Refused = 5, } -export interface MessageHeader { +export declare enum QueryTypes { + /** + * IPv4 address + */ + A = 1, + /** + * Nameserver + */ + NS = 2, + /** + * Obsolete + */ + MD = 3, + /** + * Obsolete + */ + MF = 4, + /** + * Alias + */ + CNAME = 5, + /** + * Start of authority + */ + SOA = 6, + /** + * Experimental + */ + MB = 7, + /** + * Experimental + */ + MG = 8, + /** + * Experimental + */ + MR = 9, + /** + * Experimental + */ + NULL = 10, + /** + * Service description + */ + WKS = 11, + /** + * Reverse entry (inaddr.arpa) + */ + PTR = 12, + /** + * Host information + */ + HINFO = 13, + /** + * Mailbox / Mail-list information + */ + MINFO = 14, + /** + * Mail exchange + */ + MX = 15, + /** + * Text strings + */ + TXT = 16, + /** + * IPv6 address + */ + AAAA = 28, + /** + * SRV records + */ + SRV = 33, + /** + * Request to transfer entire zone + */ + AXFR = 252, + /** + * Request for mailbox related records + */ + MAILA = 254, + /** + * Request for mail agend RRs + */ + MAILB = 253, + /** + * Any class + */ + ANY = 255, +} +export interface IMessageHeader { /** * A 16 bit identifier assigned by the program that * generates any kind of query. This identifier is copied @@ -73,7 +163,7 @@ export interface MessageHeader { /** * Reserved for future usage, must be 0 in all queries */ - Z: 0; + Z: 0 | 1; AD: 0 | 1; CD: 0 | 1; /** @@ -109,7 +199,7 @@ export interface MessageHeader { */ ARCOUNT: number; } -export interface MessageQuestion { +export interface IMessageQuestion { /** * Domain name represented as sequence of labels * Each label consists of a length octed followed @@ -169,9 +259,9 @@ export interface MessageRecourceRecord { */ RDATA: Buffer; } -export interface Message { - header: MessageHeader; - questions: MessageQuestion[]; +export interface IMessage { + header: IMessageHeader; + questions: IMessageQuestion[]; answers: MessageRecourceRecord[]; authorities: MessageRecourceRecord[]; additionals: MessageRecourceRecord[]; diff --git a/lib/types.js b/lib/types.js index 42b880d..67db464 100644 --- a/lib/types.js +++ b/lib/types.js @@ -1,13 +1,5 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// 0 No error condition -// * 1 Format error - unable to interpret query -// * 2 Server failure - internal problem -// * 3 Name error - Only for authorative name server, domain name of query does not exist -// * 4 Not implemented - Request not supported -// * 5 Refused - Nameserver refuses request -// * 6 - 15 Reserved for future usage -// * var ErrorCodes; (function (ErrorCodes) { /** @@ -35,4 +27,95 @@ var ErrorCodes; */ ErrorCodes[ErrorCodes["Refused"] = 5] = "Refused"; })(ErrorCodes = exports.ErrorCodes || (exports.ErrorCodes = {})); +var QueryTypes; +(function (QueryTypes) { + /** + * IPv4 address + */ + QueryTypes[QueryTypes["A"] = 1] = "A"; + /** + * Nameserver + */ + QueryTypes[QueryTypes["NS"] = 2] = "NS"; + /** + * Obsolete + */ + QueryTypes[QueryTypes["MD"] = 3] = "MD"; + /** + * Obsolete + */ + QueryTypes[QueryTypes["MF"] = 4] = "MF"; + /** + * Alias + */ + QueryTypes[QueryTypes["CNAME"] = 5] = "CNAME"; + /** + * Start of authority + */ + QueryTypes[QueryTypes["SOA"] = 6] = "SOA"; + /** + * Experimental + */ + QueryTypes[QueryTypes["MB"] = 7] = "MB"; + /** + * Experimental + */ + QueryTypes[QueryTypes["MG"] = 8] = "MG"; + /** + * Experimental + */ + QueryTypes[QueryTypes["MR"] = 9] = "MR"; + /** + * Experimental + */ + QueryTypes[QueryTypes["NULL"] = 10] = "NULL"; + /** + * Service description + */ + QueryTypes[QueryTypes["WKS"] = 11] = "WKS"; + /** + * Reverse entry (inaddr.arpa) + */ + QueryTypes[QueryTypes["PTR"] = 12] = "PTR"; + /** + * Host information + */ + QueryTypes[QueryTypes["HINFO"] = 13] = "HINFO"; + /** + * Mailbox / Mail-list information + */ + QueryTypes[QueryTypes["MINFO"] = 14] = "MINFO"; + /** + * Mail exchange + */ + QueryTypes[QueryTypes["MX"] = 15] = "MX"; + /** + * Text strings + */ + QueryTypes[QueryTypes["TXT"] = 16] = "TXT"; + /** + * IPv6 address + */ + QueryTypes[QueryTypes["AAAA"] = 28] = "AAAA"; + /** + * SRV records + */ + QueryTypes[QueryTypes["SRV"] = 33] = "SRV"; + /** + * Request to transfer entire zone + */ + QueryTypes[QueryTypes["AXFR"] = 252] = "AXFR"; + /** + * Request for mailbox related records + */ + QueryTypes[QueryTypes["MAILA"] = 254] = "MAILA"; + /** + * Request for mail agend RRs + */ + QueryTypes[QueryTypes["MAILB"] = 253] = "MAILB"; + /** + * Any class + */ + QueryTypes[QueryTypes["ANY"] = 255] = "ANY"; +})(QueryTypes = exports.QueryTypes || (exports.QueryTypes = {})); //# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/lib/types.js.map b/lib/types.js.map index 53770c8..c280a31 100644 --- a/lib/types.js.map +++ b/lib/types.js.map @@ -1 +1 @@ -{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;AACA,uBAAuB;AACvB,kDAAkD;AAClD,8CAA8C;AAC9C,kGAAkG;AAClG,0DAA0D;AAC1D,0DAA0D;AAC1D,wCAAwC;AACxC,WAAW;AACX,IAAY,UA8BX;AA9BD,WAAY,UAAU;IACnB;;OAEG;IACH,iDAAW,CAAA;IAEX;;OAEG;IACH,yDAAW,CAAA;IAEX;;OAEG;IACH,6DAAa,CAAA;IAEb;;OAEG;IACH,qDAAS,CAAA;IAET;;OAEG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,iDAAO,CAAA;AACV,CAAC,EA9BW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QA8BrB"} \ No newline at end of file +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;AAAA,IAAY,UA8BX;AA9BD,WAAY,UAAU;IACnB;;OAEG;IACH,iDAAW,CAAA;IAEX;;OAEG;IACH,yDAAW,CAAA;IAEX;;OAEG;IACH,6DAAa,CAAA;IAEb;;OAEG;IACH,qDAAS,CAAA;IAET;;OAEG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,iDAAO,CAAA;AACV,CAAC,EA9BW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QA8BrB;AAED,IAAY,UA8GX;AA9GD,WAAY,UAAU;IACnB;;OAEG;IACH,qCAAQ,CAAA;IAER;;OAEG;IACH,uCAAS,CAAA;IAET;;OAEG;IACH,uCAAS,CAAA;IAET;;OAEG;IACH,uCAAS,CAAA;IAET;;OAEG;IACH,6CAAY,CAAA;IAEZ;;OAEG;IACH,yCAAU,CAAA;IAEV;;OAEG;IACH,uCAAS,CAAA;IAET;;OAEG;IACH,uCAAS,CAAA;IAET;;OAEG;IACH,uCAAS,CAAA;IAET;;OAEG;IACH,4CAAW,CAAA;IAEX;;OAEG;IACH,0CAAU,CAAA;IAEV;;OAEG;IACH,0CAAU,CAAA;IAEV;;OAEG;IACH,8CAAY,CAAA;IAEZ;;OAEG;IACH,8CAAY,CAAA;IAEZ;;OAEG;IACH,wCAAS,CAAA;IAET;;OAEG;IACH,0CAAU,CAAA;IAEV;;OAEG;IACH,4CAAW,CAAA;IAEX;;OAEG;IACH,0CAAU,CAAA;IAEV;;OAEG;IACH,6CAAW,CAAA;IAEX;;OAEG;IACH,+CAAY,CAAA;IAEZ;;OAEG;IACH,+CAAY,CAAA;IAEZ;;OAEG;IACH,2CAAU,CAAA;AACb,CAAC,EA9GW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QA8GrB"} \ No newline at end of file diff --git a/src/request.ts b/src/request.ts index e448790..2fea7ae 100644 --- a/src/request.ts +++ b/src/request.ts @@ -1,121 +1,7 @@ import { Parser } from "binary-parser" -import { Message, MessageHeader, MessageQuestion, MessageRecourceRecord, ErrorCodes } from "./types" +import { IMessage, IMessageHeader, IMessageQuestion, MessageRecourceRecord, ErrorCodes } from "./types" -const MAX_LABEL_SIZE = 63; - -export enum QueryTypes { - /** - * IPv4 address - */ - A = 0x01, - - /** - * Nameserver - */ - NS = 0x02, // nameserver - - /** - * Obsolete - */ - MD = 0x03, // obsolete - - /** - * Obsolete - */ - MF = 0x04, // obsolete - - /** - * Alias - */ - CNAME = 0x05, // alias - - /** - * Start of authority - */ - SOA = 0x06, // start of authority - - /** - * Experimental - */ - MB = 0x07, // experimental - - /** - * Experimental - */ - MG = 0x08, // experimental - - /** - * Experimental - */ - MR = 0x09, // experimental - - /** - * Experimental - */ - NULL = 0x0A, // experimental null RR - - /** - * Service description - */ - WKS = 0x0B, // service description - - /** - * Reverse entry (inaddr.arpa) - */ - PTR = 0x0C, // reverse entry (inaddr.arpa) - - /** - * Host information - */ - HINFO = 0x0D, // host information - - /** - * Mailbox / Mail-list information - */ - MINFO = 0x0E, // mailbox or mail list information - - /** - * Mail exchange - */ - MX = 0x0F, // mail exchange - - /** - * Text strings - */ - TXT = 0x10, // text strings - - /** - * IPv6 address - */ - AAAA = 0x1C, // ipv6 address - - /** - * SRV records - */ - SRV = 0x21, // srv records - - /** - * Request to transfer entire zone - */ - AXFR = 0xFC, // request to transfer entire zone - - /** - * Request for mailbox related records - */ - MAILA = 0xFE, // request for mailbox related records - - /** - * Request for mail agend RRs - */ - MAILB = 0xFD, // request for mail agent RRs - - /** - * Any class - */ - ANY = 0xFF, // any class -} - -const headerParser = new Parser() +const headerParser: Parser = new Parser() .endianess("big") .uint16("ID") .bit1("QR") @@ -133,6 +19,14 @@ const headerParser = new Parser() .uint16("NSCOUNT") .uint16("ARCOUNT") +export function parseHeader(data: Buffer): IMessageHeader { + try { + return headerParser.parse(data); + } catch (e) { + throw new Error("Header parsing failed" + e.message) + } +} + const labelParser = new Parser() .endianess("big") .uint8("dataLength") @@ -156,16 +50,22 @@ const questionParser = new Parser() .uint16("QTYPE") .uint16("QCLASS") -function parseQuestions(count: number, packet: Buffer): MessageQuestion[] { - return new Parser() - .endianess("big") - .array("questions", { - type: questionParser, - length: count - }).parse(packet).questions; +export function parseQuestions(count: number, packet: Buffer): IMessageQuestion[] { + try { + return new Parser() + .endianess("big") + .array("questions", { + type: questionParser, + length: count + }).parse(packet).questions; + } catch (e) { + throw new Error("Question parsing failed" + e.message) + } } -export function SerializeName(name: string) { +const MAX_LABEL_SIZE = 63; + +export function serializeName(name: string) { let length = 0; let parts = name.split("."); parts.forEach(e => { @@ -187,33 +87,32 @@ export function SerializeName(name: string) { return data; } -export class Request implements Message { - private _header: MessageHeader; +export class Request implements IMessage { + private _header: Header; get header() { return Object.assign({}, this._header); } - private _questions: MessageQuestion[]; + private _questions: Question[]; get questions() { - return this._questions.map(e => e); + return this._questions.map(e => Object.assign({}, e)); } answers: RecourceRecord[] = []; authorities: RecourceRecord[] = []; additionals: RecourceRecord[] = []; - constructor(packet: Buffer, private sendCallback: (packet: Buffer) => any) { + constructor(packet: Buffer, private sendCallback: (packet: Buffer) => any, private max_size = 512) { let headerData = Buffer.alloc(12); packet.copy(headerData, 0, 0, 12); let bodyData = Buffer.alloc(packet.length - 12); packet.copy(bodyData, 0, 12, packet.length); - this._header = headerParser.parse(headerData); + this._header = new Header(parseHeader(headerData)); this._header.AD = 0; this._header.RCODE = ErrorCodes.NoError; this._header.RA = this._header.RD; - - this._questions = parseQuestions(this._header.QDCOUNT, bodyData); + this._questions = parseQuestions(this._header.QDCOUNT, bodyData).map(e => new Question(e)); } error(error: ErrorCodes) { @@ -229,50 +128,53 @@ export class Request implements Message { this.sendCallback(this.serialize()); } - serialize(truncate: boolean = false, rcode: 0 | 1 | 2 | 3 | 4 | 5 = 0) { + serialize() { this._header.AA = 1; this._header.ANCOUNT = this.answers.length; this._header.ARCOUNT = this.additionals.length; this._header.NSCOUNT = this.authorities.length; this._header.QR = 1; - this._header.RCODE = rcode; + let questions = this._questions.map(e => e.serialize()) + let answers = this.answers.map(e => e.serialize()) + let authority = this.authorities.map(e => e.serialize()) + let additional = this.additionals.map(e => e.serialize()) - let questions = this.questions.map(this.serializeQuestion, this) - let answers = this.answers.map(this.serializeResourceRecord, this) - let authority = this.authorities.map(this.serializeResourceRecord, this) - let additional = this.additionals.map(this.serializeResourceRecord, this) + let length = 12; + questions.forEach(e => length += e.length); + answers.forEach(e => length += e.length) + authority.forEach(e => length += e.length) + additional.forEach(e => length += e.length) + // let questionsByteLength = 0; + // questions.forEach(e => questionsByteLength += e.length); - let questionsByteLength = 0; - questions.forEach(e => questionsByteLength += e.length); + // let answersByteLength = 0; + // answers.forEach(e => answersByteLength += e.length) - let answersByteLength = 0; - answers.forEach(e => answersByteLength += e.length) + // let authorityByteLength = 0; + // authority.forEach(e => authorityByteLength += e.length) - let authorityByteLength = 0; - authority.forEach(e => authorityByteLength += e.length) + // let additionalByteLength = 0; + // additional.forEach(e => additionalByteLength += e.length) - let additionalByteLength = 0; - additional.forEach(e => additionalByteLength += e.length) + // let length = 12 + questionsByteLength + answersByteLength + authorityByteLength + additionalByteLength; //Header is always 12 byte large - let length = 12 + questionsByteLength + answersByteLength + authorityByteLength + additionalByteLength; //Header is always 12 byte large - - if (truncate && length > 512) { + if (length > this.max_size) { this._header.TC = 1; - //Buffer will ignore data that exeeds the max buffer length - length = 512; + //Will ignore data, that exceeds length + length = this.max_size; } - - let header = this.serializeHeader() + let header = this._header.serialize(); let data = Buffer.alloc(length) let offset = 0; let append = (buffer: Buffer) => { - buffer.copy(data, offset, 0, buffer.length) - offset += buffer.length; + if (offset <= length) { + buffer.copy(data, offset, 0, buffer.length) + offset += buffer.length; + } } - append(header) questions.forEach(append) answers.forEach(append) @@ -280,57 +182,73 @@ export class Request implements Message { additional.forEach(append) return data; } +} - private serializeHeader() { - let header = this.header; - let data = Buffer.alloc(12); - data.writeUInt16BE(header.ID, 0); - var f = 0x0000; - f = f | (header.QR << 15); - f = f | (header.OPCODE << 11); - f = f | (header.AA << 10); - f = f | (header.TC << 9); - f = f | (header.RD << 8); - f = f | (header.RA << 7); - f = f | (header.Z << 6); - f = f | (header.AD << 5); - f = f | (header.CD << 4); - f = f | header.RCODE; - data.writeUInt16BE(f, 2); +export class Header implements IMessageHeader { + ID: number; + QR: 0 | 1; + OPCODE: number + AA: 0 | 1; + TC: 0 | 1; + RD: 0 | 1; + RA: 0 | 1; + Z: 0 | 1; + AD: 0 | 1; + CD: 0 | 1; + RCODE: ErrorCodes; + QDCOUNT: number; + ANCOUNT: number; + NSCOUNT: number; + ARCOUNT: number; - data.writeUInt16BE(header.QDCOUNT, 4) - data.writeUInt16BE(header.ANCOUNT, 6) - data.writeUInt16BE(header.NSCOUNT, 8) - data.writeUInt16BE(header.ARCOUNT, 10) - return data; + constructor(header: IMessageHeader) { + for (let k in header) { + this[k] = header[k]; + } } - private serializeQuestion(question: MessageQuestion) { - let qname = SerializeName(question.QNAME); + serialize() { + let data = Buffer.alloc(12); + data.writeUInt16BE(this.ID, 0); + var f = 0x0000; + f = f | (this.QR << 15); + f = f | (this.OPCODE << 11); + f = f | (this.AA << 10); + f = f | (this.TC << 9); + f = f | (this.RD << 8); + f = f | (this.RA << 7); + f = f | (this.Z << 6); + f = f | (this.AD << 5); + f = f | (this.CD << 4); + f = f | this.RCODE; + data.writeUInt16BE(f, 2); + data.writeUInt16BE(this.QDCOUNT, 4) + data.writeUInt16BE(this.ANCOUNT, 6) + data.writeUInt16BE(this.NSCOUNT, 8) + data.writeUInt16BE(this.ARCOUNT, 10) + return data; + } +} + +export class Question implements IMessageQuestion { + QNAME: string; + QTYPE: number; + QCLASS: number; + + constructor(question: IMessageQuestion) { + for (let k in question) { + this[k] = question[k] + } + } + + serialize() { + let qname = serializeName(this.QNAME); let data = Buffer.alloc(qname.length + 4); qname.copy(data, 0, 0, qname.length); let offset = qname.length; - data.writeUInt16BE(question.QTYPE, offset); + data.writeUInt16BE(this.QTYPE, offset); offset += 2; - data.writeUInt16BE(question.QCLASS, offset); - return data; - } - - private serializeResourceRecord(record: MessageRecourceRecord) { - // TODO: Implement compression - let name = SerializeName(record.NAME); - let data = Buffer.alloc(name.length + 10 + record.RDLENGTH) // For TYPE, CLASS, TTL, RLENGTH - name.copy(data, 0, 0, name.length); - let offset = name.length; - data.writeUInt16BE(record.TYPE, offset) - offset += 2 - data.writeUInt16BE(record.CLASS, offset) - offset += 2 - data.writeUInt32BE(record.TTL, offset) - offset += 4 - data.writeUInt16BE(record.RDLENGTH, offset) - offset += 2 - record.RDATA.copy(data, offset, 0, record.RDLENGTH) + data.writeUInt16BE(this.QCLASS, offset); return data; } } @@ -365,6 +283,7 @@ export class RecourceRecord implements MessageRecourceRecord { private _TTL: number; set TTL(value) { if (value < 0 || value > 4294967295) throw new TypeError("TTL Range: 0 - 4.294.967.295") + this._TTL = value; } get TTL() { @@ -376,4 +295,22 @@ export class RecourceRecord implements MessageRecourceRecord { get RDLENGTH() { return this.RDATA.length; } + + public serialize() { + // TODO: Implement compression + let name = serializeName(this.NAME); + let data = Buffer.alloc(name.length + 10 + this.RDLENGTH) // For TYPE, CLASS, TTL, RLENGTH + name.copy(data, 0, 0, name.length); + let offset = name.length; + data.writeUInt16BE(this.TYPE, offset) + offset += 2 + data.writeUInt16BE(this.CLASS, offset) + offset += 2 + data.writeUInt32BE(this._TTL, offset) + offset += 4 + data.writeUInt16BE(this.RDLENGTH, offset) + offset += 2 + this.RDATA.copy(data, offset, 0, this.RDLENGTH) + return data; + } } \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index e0453c6..d67ae9d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,12 +1,3 @@ - -// 0 No error condition -// * 1 Format error - unable to interpret query -// * 2 Server failure - internal problem -// * 3 Name error - Only for authorative name server, domain name of query does not exist -// * 4 Not implemented - Request not supported -// * 5 Refused - Nameserver refuses request -// * 6 - 15 Reserved for future usage -// * export enum ErrorCodes { /** * No error @@ -39,7 +30,119 @@ export enum ErrorCodes { Refused } -export interface MessageHeader { +export enum QueryTypes { + /** + * IPv4 address + */ + A = 0x01, + + /** + * Nameserver + */ + NS = 0x02, // nameserver + + /** + * Obsolete + */ + MD = 0x03, // obsolete + + /** + * Obsolete + */ + MF = 0x04, // obsolete + + /** + * Alias + */ + CNAME = 0x05, // alias + + /** + * Start of authority + */ + SOA = 0x06, // start of authority + + /** + * Experimental + */ + MB = 0x07, // experimental + + /** + * Experimental + */ + MG = 0x08, // experimental + + /** + * Experimental + */ + MR = 0x09, // experimental + + /** + * Experimental + */ + NULL = 0x0A, // experimental null RR + + /** + * Service description + */ + WKS = 0x0B, // service description + + /** + * Reverse entry (inaddr.arpa) + */ + PTR = 0x0C, // reverse entry (inaddr.arpa) + + /** + * Host information + */ + HINFO = 0x0D, // host information + + /** + * Mailbox / Mail-list information + */ + MINFO = 0x0E, // mailbox or mail list information + + /** + * Mail exchange + */ + MX = 0x0F, // mail exchange + + /** + * Text strings + */ + TXT = 0x10, // text strings + + /** + * IPv6 address + */ + AAAA = 0x1C, // ipv6 address + + /** + * SRV records + */ + SRV = 0x21, // srv records + + /** + * Request to transfer entire zone + */ + AXFR = 0xFC, // request to transfer entire zone + + /** + * Request for mailbox related records + */ + MAILA = 0xFE, // request for mailbox related records + + /** + * Request for mail agend RRs + */ + MAILB = 0xFD, // request for mail agent RRs + + /** + * Any class + */ + ANY = 0xFF, // any class +} + +export interface IMessageHeader { /** * A 16 bit identifier assigned by the program that * generates any kind of query. This identifier is copied @@ -93,7 +196,7 @@ export interface MessageHeader { /** * Reserved for future usage, must be 0 in all queries */ - Z: 0; + Z: 0 | 1; AD: 0 | 1; @@ -136,7 +239,7 @@ export interface MessageHeader { */ ARCOUNT: number; } -export interface MessageQuestion { +export interface IMessageQuestion { /** * Domain name represented as sequence of labels * Each label consists of a length octed followed @@ -203,9 +306,9 @@ export interface MessageRecourceRecord { */ RDATA: Buffer; } -export interface Message { - header: MessageHeader; - questions: MessageQuestion[]; +export interface IMessage { + header: IMessageHeader; + questions: IMessageQuestion[]; answers: MessageRecourceRecord[]; authorities: MessageRecourceRecord[]; additionals: MessageRecourceRecord[];