Rewriting of backend
All checks were successful
the build was successful

This commit is contained in:
Fabian Stamm
2018-11-30 21:48:27 +01:00
parent e8dcf31461
commit 69094524d1
27 changed files with 3215 additions and 3069 deletions

75
src/header.ts Normal file
View File

@ -0,0 +1,75 @@
import { IMessageHeader, ErrorCodes } from "./types";
import { Serializeable } from "./serializeable";
export class Header implements IMessageHeader, Serializeable {
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) {
for (let k in header) {
this[k] = header[k];
}
}
lock() {
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;
let id = this.ID;
let qdc = this.QDCOUNT;
let anc = this.ANCOUNT;
let nsc = this.NSCOUNT;
let arc = this.ARCOUNT;
return {
length: 12,
serialize: (buffer: Buffer, offset: number) => {
buffer.writeUInt16BE(id, offset);
offset += 2;
buffer.writeUInt16BE(f, offset);
offset += 2;
buffer.writeUInt16BE(qdc, offset);
offset += 2;
buffer.writeUInt16BE(anc, offset);
offset += 2;
buffer.writeUInt16BE(nsc, offset);
offset += 2;
buffer.writeUInt16BE(arc, offset);
return offset + 2;
}
}
}
// serialize() {
// let data = Buffer.alloc(12);
// data.writeUInt16BE(this.ID, 0);
// 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;
// }
}

View File

@ -1,4 +1,7 @@
import * as Types from "./types";
import * as Request from "./request"
export = Object.assign({}, Types, Request);
export = {
types: Types,
request: Request
}

60
src/label.ts Normal file
View File

@ -0,0 +1,60 @@
import { Serializeable } from "./serializeable";
const MAX_LABEL_SIZE = 63;
export class Label implements Serializeable {
constructor(public name?: string) { }
public lock() {
let parts = this.name.split(".");
let length = 0;
parts.forEach(e => {
if (e.length > MAX_LABEL_SIZE) throw new Error("Label to large");
length += e.length + 1;
})
length += 1;
return {
length: length,
serialize: (buffer: Buffer, offset: number) => {
parts.forEach(e => {
buffer.writeUInt8(e.length, offset)
offset++
buffer.write(e, offset, e.length)
offset += e.length
})
buffer.writeUInt8(0, offset);
offset += 1;
return offset;
}
}
}
// set name(name: string) {
// if (name != this._name) {
// let length = 0;
// let parts = name.split(".")
// parts.forEach(e => {
// if (e.length > MAX_LABEL_SIZE) throw new Error("Label to large");
// length += e.length + 1;
// })
// length += 1; //Adding last 0 length octet
// this._length = length;
// this._name_parts = parts;
// this._name = name;
// }
// }
// get name() {
// return this._name;
// }
// get length() {
// return this._length;
// }
// serialize(buffer: Buffer, offset: number) {
// }
}

0
src/lock.ts Normal file
View File

37
src/question.ts Normal file
View File

@ -0,0 +1,37 @@
import { IMessageQuestion } from "./types";
import { Label } from "./label";
import { Serializeable } from "./serializeable";
export class Question implements IMessageQuestion, Serializeable {
private _QNAME = new Label();
get QNAME() { return this._QNAME.name };
_QTYPE: number;
get QTYPE() { return this._QTYPE };
_QCLASS: number;
get QCLASS() { return this._QCLASS };
constructor(question: IMessageQuestion) {
this._QCLASS = question.QCLASS;
this._QTYPE = question.QTYPE;
this._QNAME.name = question.QNAME;
}
lock() {
let name = this._QNAME.lock();
let type = this._QTYPE;
let cl = this._QCLASS;
return {
length: name.length + 4,
serialize: (buffer: Buffer, offset: number) => {
offset = name.serialize(buffer, offset);
buffer.writeUInt16BE(type, offset);
offset += 2;
buffer.writeUInt16BE(cl, offset);
offset += 2;
return offset;
}
}
}
}

92
src/record.ts Normal file
View File

@ -0,0 +1,92 @@
import { Serializeable, Serializer } from "./serializeable";
import { MessageRecourceRecord } from "./types";
import { Label } from "./label";
export class RecourceRecord implements Partial<MessageRecourceRecord>, Serializeable {
/**
* This value can be set to identify if specific record is already set
*/
public Identifier: string;
private _NAME = new Label();
public get NAME() { return this._NAME.name };
public set NAME(name) { this._NAME.name = name };
private _TYPE: number;
public get TYPE() { return this._TYPE }
public set TYPE(value) {
if (value < 0 || value > 65535) throw new TypeError("TYPE Range: 0 - 65.535")
this._TYPE = value;
}
private _CLASS: number = 1;
public get CLASS() { return this._CLASS }
public set CLASS(value) {
if (value < 0 || value > 65535) throw new TypeError("CLASS Range: 0 - 65.535")
this._CLASS = value;
}
private _TTL: number;
public get TTL() { return this._TTL }
public set TTL(value) {
if (value < 0 || value > 4294967295) throw new TypeError("TTL Range: 0 - 4.294.967.295")
this._TTL = value;
}
constructor(data?: Partial<MessageRecourceRecord>) {
if (data) {
for (let key in data) {
this[key] = data[key];
}
}
}
protected dataLock?: () => Serializer;
public lock() {
if (!this.dataLock) return {
length: 0,
serialize: (buffer: Buffer, offset: number) => offset
}
let name = this._NAME.lock();
let type = this.TYPE;
let cl = this.CLASS;
let ttl = this.TTL;
let data = this.dataLock();
let length = name.length + 2 + 2 + 4 + 2 + data.length;
return {
length: length,
serialize: (buffer: Buffer, offset: number) => {
offset = name.serialize(buffer, offset);
buffer.writeUInt16BE(type, offset)
offset += 2
buffer.writeUInt16BE(cl, offset)
offset += 2
buffer.writeUInt32BE(ttl, offset)
offset += 4
buffer.writeUInt16BE(data.length, offset)
offset += 2
return data.serialize(buffer, offset);
}
}
}
}
export class RDATARecord extends RecourceRecord {
public RDATA: Buffer;
get RDLENGTH() {
return this.RDATA.length;
}
dataLock = () => {
return {
length: this.RDATA.length,
serialize: (buffer: Buffer, offset: number) => {
this.RDATA.copy(buffer, offset);
return offset + this.RDATA.length;
}
}
}
}

View File

@ -1,7 +1,11 @@
import { Parser } from "binary-parser"
import { IMessage, IMessageHeader, IMessageQuestion, MessageRecourceRecord, ErrorCodes } from "./types"
import { IMessageHeader, IMessageQuestion, MessageRecourceRecord, ErrorCodes } from "./types"
import { Serializer } from "./serializeable";
import { Question } from "./question";
import { RecourceRecord } from "./record";
import { Header } from "./header";
const headerParser: Parser = new Parser()
export const headerParser: Parser = new Parser()
.endianess("big")
.uint16("ID")
.bit1("QR")
@ -19,15 +23,7 @@ const headerParser: Parser = new Parser()
.uint16("NSCOUNT")
.uint16("ARCOUNT")
export function parseHeader(data: Buffer): IMessageHeader {
try {
return <any>headerParser.parse(data);
} catch (e) {
throw new Error("Header parsing failed" + e.message)
}
}
const labelParser = new Parser()
export const labelParser = new Parser()
.endianess("big")
.uint8("dataLength")
.string("name", {
@ -35,7 +31,7 @@ const labelParser = new Parser()
encoding: "ascii"
})
const questionParser = new Parser()
export const questionParser = new Parser()
.endianess("big")
.array("QNAME", {
type: labelParser,
@ -50,47 +46,24 @@ const questionParser = new Parser()
.uint16("QTYPE")
.uint16("QCLASS")
export function parseQuestions(count: number, packet: Buffer): IMessageQuestion[] {
try {
return <any>new Parser()
.endianess("big")
.array("questions", {
type: questionParser,
length: count
}).parse(packet).questions;
} catch (e) {
throw new Error("Question parsing failed" + e.message)
}
}
const MAX_LABEL_SIZE = 63;
export function serializeName(name: string) {
let length = 0;
let parts = name.split(".");
parts.forEach(e => {
// Length of part and byte that holds the length information
if (e.length > MAX_LABEL_SIZE) throw new Error("Label to large");
length += e.length + 1;
const packetParser = new Parser()
.endianess("big")
.nest("header", { type: headerParser })
.array("questions", {
type: questionParser,
length: "header.QDCOUNT"
})
length += 1; //Adding last 0 length octet
let data = Buffer.alloc(length);
let offset = 0;
parts.forEach(e => {
data.writeUInt8(e.length, offset)
offset++
data.write(e, offset, e.length)
offset += e.length
})
data.writeUInt8(0, offset);
return data;
export function parseInput(data: Buffer): { header: IMessageHeader, questions: IMessageQuestion[] } {
let res = packetParser.parse(data);
return <any>res;
}
export class Request implements IMessage {
export class Request {
private _header: Header;
get header() {
return Object.assign({}, this._header);
return { ...this._header };
}
private _questions: Question[];
@ -98,21 +71,18 @@ export class Request implements IMessage {
return this._questions.map(e => Object.assign({}, e));
}
answers: RecourceRecord[] = [];
authorities: RecourceRecord[] = [];
additionals: RecourceRecord[] = [];
public _answers: RecourceRecord[] = [];
public _authorities: RecourceRecord[] = [];
public _additionals: RecourceRecord[] = [];
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);
constructor(packet: Buffer, public sender: string, private max_size = 0) {
let parsed = parseInput(packet);
this._header = new Header(parseHeader(headerData));
this._header = new Header(parsed.header);
this._header.AD = 0;
this._header.RCODE = ErrorCodes.NoError;
this._header.RA = this._header.RD;
this._questions = parseQuestions(this._header.QDCOUNT, bodyData).map(e => new Question(e));
this._questions = parsed.questions.map(e => new Question(e));
}
error(error: ErrorCodes) {
@ -124,42 +94,39 @@ export class Request implements IMessage {
this._header.RA = 0;
}
send() {
this.sendCallback(this.serialize());
}
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.ANCOUNT = this._answers.length;
this._header.ARCOUNT = this._additionals.length;
this._header.NSCOUNT = this._authorities.length;
this._header.QR = 1;
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;
let header = this._header.lock();
let questions = this._questions.map(e => e.lock())
let answers = this._answers.map(e => e.lock())
let authority = this._authorities.map(e => e.lock())
let additional = this._additionals.map(e => e.lock())
let length = header.length;
questions.forEach(e => length += e.length);
answers.forEach(e => length += e.length)
authority.forEach(e => length += e.length)
additional.forEach(e => length += e.length)
if (length > this.max_size) {
if (this.max_size && length > this.max_size) {
this._header.TC = 1;
//Will ignore data, that exceeds length
length = this.max_size;
}
let header = this._header.serialize();
let data = Buffer.alloc(length)
let offset = 0;
let append = (buffer: Buffer) => {
let append = (ser: Serializer) => {
if (offset <= length) {
buffer.copy(data, offset, 0, buffer.length)
offset += buffer.length;
offset = ser.serialize(data, offset);
}
}
append(header)
@ -170,144 +137,3 @@ export class Request implements IMessage {
return data;
}
}
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;
constructor(header: IMessageHeader) {
for (let k in header) {
this[k] = header[k];
}
}
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(this.QTYPE, offset);
offset += 2;
data.writeUInt16BE(this.QCLASS, offset);
return data;
}
}
export class RecourceRecord implements MessageRecourceRecord {
constructor(data?: Partial<MessageRecourceRecord>) {
if (data) {
for (let key in data) {
this[key] = data[key];
}
}
}
/**
* This value can be set to identify if specific record is already set
*/
Identifier: string;
NAME: string
private _TYPE: number;
set TYPE(value) {
if (value < 0 || value > 65535) throw new TypeError("TYPE Range: 0 - 65.535")
this._TYPE = value;
}
get TYPE() {
return this._TYPE;
}
private _CLASS: number;
set CLASS(value) {
if (value < 0 || value > 65535) throw new TypeError("CLASS Range: 0 - 65.535")
this._CLASS = value;
}
get CLASS() {
return this._CLASS;
}
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() {
return this._TTL;
}
RDATA: Buffer;
get RDLENGTH() {
return this.RDATA.length;
}
public serialize() {
// TODO: Implement compression
let name = serializeName(this.NAME);
let rdata = this.RDATA;
let data = Buffer.alloc(name.length + 10 + rdata.length) // 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(rdata.length, offset)
offset += 2
rdata.copy(data, offset, 0, rdata.length)
return data;
}
}

19
src/serializeable.ts Normal file
View File

@ -0,0 +1,19 @@
export interface Serializer {
/**
*
* @param buffer Buffer to write to (should be capable to hold this.length)
* @param offset The offset at wich to start writing
* @returns The new offset (should be equal to original offset + this.length)
*/
serialize(buffer: Buffer, offset: number): number;
/**
* Returns length of serialized data
* @readonly
*/
length: number;
}
export interface Serializeable {
lock(): Serializer;
}

View File

@ -1,7 +1,10 @@
import { assert, expect } from "chai";
import { assert } from "chai";
import { parseHeader, Header, parseQuestions, Question, RecourceRecord, Request } from "./request"
import { IMessageHeader, IMessageQuestion, QueryTypes } from "./types";
import { parseInput, Request, questionParser, headerParser } from "./request"
import { IMessageHeader, RecordTypes } from "./types";
import { RDATARecord } from "./record";
import { Question } from "./question";
import { Header } from "./header";
function fromHex(data: string) {
return Buffer.from(data.replace(/\s/g, ""), "hex");
@ -11,21 +14,7 @@ describe("parser", function () {
describe("header", function () {
describe("header parser", function () {
let should_templ: IMessageHeader = {
ID: 0,
QR: 0,
OPCODE: 0,
AA: 0,
TC: 0,
RD: 0,
RA: 0,
Z: 0,
AD: 0,
CD: 0,
RCODE: 0,
QDCOUNT: 0,
ANCOUNT: 0,
ARCOUNT: 0,
NSCOUNT: 0
ID: 0, QR: 0, OPCODE: 0, AA: 0, TC: 0, RD: 0, RA: 0, Z: 0, AD: 0, CD: 0, RCODE: 0, QDCOUNT: 0, ANCOUNT: 0, ARCOUNT: 0, NSCOUNT: 0
}
let tests: { name: string, data: string, fields: Partial<IMessageHeader> }[] = [
@ -124,29 +113,15 @@ describe("parser", function () {
name: "Testing all Flags and Values max",
data: "FFFF FFFF FFFF FFFF FFFF FFFF",
fields: {
ID: 65535,
QR: 1,
OPCODE: 15,
AA: 1,
TC: 1,
RD: 1,
RA: 1,
Z: 1,
AD: 1,
CD: 1,
RCODE: 15,
QDCOUNT: 65535,
ANCOUNT: 65535,
NSCOUNT: 65535,
ARCOUNT: 65535
ID: 65535, QR: 1, OPCODE: 15, AA: 1, TC: 1, RD: 1, RA: 1, Z: 1, AD: 1, CD: 1, RCODE: 15, QDCOUNT: 65535, ANCOUNT: 65535, NSCOUNT: 65535, ARCOUNT: 65535
}
}
]
tests.forEach(function (e) {
it(e.name, function () {
let testdata = fromHex(e.data)
let should: IMessageHeader = Object.assign({}, should_templ, e.fields) // Build in "clone" function
let header = parseHeader(testdata);
let should: IMessageHeader = { ...should_templ, ...e.fields }
let header = <any>headerParser.parse(testdata);
assert.hasAllKeys(header, Object.keys(should), "Parsed header is missing some fields")
assert.deepEqual(header, should, "Parsed header has not expected values!")
})
@ -155,21 +130,7 @@ describe("parser", function () {
describe("header serializer", function () {
let empty_header: IMessageHeader = {
ID: 0,
QR: 0,
OPCODE: 0,
AA: 0,
TC: 0,
RD: 0,
RA: 0,
Z: 0,
AD: 0,
CD: 0,
RCODE: 0,
QDCOUNT: 0,
ANCOUNT: 0,
ARCOUNT: 0,
NSCOUNT: 0
ID: 0, QR: 0, OPCODE: 0, AA: 0, TC: 0, RD: 0, RA: 0, Z: 0, AD: 0, CD: 0, RCODE: 0, QDCOUNT: 0, ANCOUNT: 0, ARCOUNT: 0, NSCOUNT: 0
}
let tests: { name: string, result: string, values: Partial<IMessageHeader> }[] = [
{
@ -287,8 +248,11 @@ describe("parser", function () {
tests.forEach(function (e) {
it(e.name, function () {
let header = Object.assign({}, empty_header, e.values)
let serialized = new Header(header).serialize();
assert.equal(serialized.toString("hex"), e.result.replace(/\s/g, "").toLowerCase(), "Header serialization failed");
let slz = new Header(header).lock();
assert.equal(slz.length, 12, "Header returns wrong length");
let res = Buffer.alloc(slz.length);
assert.equal(slz.serialize(res, 0), 12, "Header returns wrong offset");
assert.equal(res.toString("hex"), e.result.replace(/\s/g, "").toLowerCase(), "Header serialization failed");
})
})
})
@ -298,75 +262,78 @@ describe("parser", function () {
let questionData = fromHex("0474 6573 7407 6578 616d 706c 6503 636f 6d00 0001 0001")
let questionObj = {
QNAME: "test.example.com",
QTYPE: QueryTypes.A,
QTYPE: RecordTypes.A,
QCLASS: 1
}
it("check question parser with one question", function () {
let res = parseQuestions(1, questionData)
let should: IMessageQuestion[] = [questionObj]
let res = questionParser.parse(questionData)
assert.deepEqual(res, should, "Question parser does not parse input correctly")
assert.deepEqual(res, questionObj, "Question parser does not parse input correctly")
})
it("check question serialization", function () {
let res = new Question(questionObj).serialize()
let slz = new Question(questionObj).lock()
assert.equal(slz.length, 22, "Question serializer returns wrong length")
let res = Buffer.alloc(slz.length);
assert.equal(slz.serialize(res, 0), 22, "Question serializer returns wrong offset")
assert.equal(res.toString("hex"), questionData.toString("hex"), "Query serializer does not serialite correctly");
})
})
it("parse valid request", () => {
let should = {
header: { ID: 59445, QR: 0, OPCODE: 0, AA: 0, TC: 0, RD: 1, RA: 0, Z: 0, AD: 0, CD: 0, RCODE: 0, QDCOUNT: 1, ANCOUNT: 0, NSCOUNT: 0, ARCOUNT: 0 },
questions: [{ QNAME: 'example.com', QTYPE: 1, QCLASS: 1 }]
}
let data = fromHex("E835 0100 0001 0000 0000 0000 07 6578616D706c65 03636F6D 00 0001 0001");
let res = parseInput(data);
assert.deepEqual(res, should);
})
it("recource record serialization", function () {
let should = "07 6578616D706C65 03 636f6D 00 0001 0001 00000640 0004 0A000001"
let rr = new RecourceRecord()
let rr = new RDATARecord()
rr.CLASS = 1
rr.NAME = "example.com"
rr.TTL = 1600
rr.TYPE = 1
rr.RDATA = fromHex("0A 00 00 01")
let res = rr.serialize().toString("hex")
assert.equal(res, should.replace(/\s/g, "").toLowerCase(), "Serialization not working properly")
let srl = rr.lock();
let res = Buffer.alloc(srl.length);
srl.serialize(res, 0);
assert.equal(res.toString("hex"), should.replace(/\s/g, "").toLowerCase(), "Serialization not working properly")
})
it("recource record constructor value assign", function () {
let should = "07 6578616D706C65 03 636f6D 00 0001 0001 00000640 0004 0A000001"
let rr = new RecourceRecord({
let rr = new RDATARecord({
CLASS: 1,
NAME: "example.com",
TTL: 1600,
TYPE: 1,
RDATA: fromHex("0A 00 00 01")
})
let res = rr.serialize().toString("hex")
assert.equal(res, should.replace(/\s/g, "").toLowerCase(), "Serialization not working properly")
let srl = rr.lock();
assert.equal(srl.length, 27, "Record serializer returns wrong length")
let res = Buffer.alloc(srl.length);
assert.equal(srl.serialize(res, 0), 27, "Record serializer returns wrong offset")
assert.equal(res.toString("hex"), should.replace(/\s/g, "").toLowerCase(), "Record serialization not working properly")
})
it("full response serialization", function () {
let reqData = fromHex("E835 0100 0001 0000 0000 0000 07 6578616D706c65 03636F6D 00 0001 0001");
let should = "E835 8580 0001000100000000 076578616D706C6503636F6D0000010001 07 6578616D706C65 03 636F6D 00 0001 0001 0000 0640 0004 0A000001"
let request = new Request(reqData, () => null)
let rr = new RecourceRecord()
let request = new Request(reqData, "")
let rr = new RDATARecord()
rr.CLASS = 1
rr.NAME = "example.com"
rr.TTL = 1600
rr.TYPE = 1
rr.RDATA = fromHex("0A 00 00 01")
request.answers.push(rr)
request._answers.push(rr)
let data = request.serialize()
assert.equal(data.toString("hex"), should.replace(/\s/g, "").toLowerCase(), "Whole packet serialization failed")
})
// it("full response serialization benchmark", function () {
// let reqData = fromHex("E835 0100 0001 0000 0000 0000 07 6578616D706c65 03636F6D 00 0001 0001");
// for (let i = 0; i < 100; i++) {
// let request = new Request(reqData, () => null)
// let rr = new RecourceRecord()
// rr.CLASS = 1
// rr.NAME = "example.com"
// rr.TTL = 1600
// rr.TYPE = 1
// rr.RDATA = fromHex("0A 00 00 01")
// request.answers.push(rr)
// request.serialize()
// }
// })
})

View File

@ -30,7 +30,7 @@ export enum ErrorCodes {
Refused
}
export enum QueryTypes {
export enum RecordTypes {
/**
* IPv4 address
*/
@ -254,14 +254,13 @@ export interface IMessageQuestion {
/**
* Two octed code that specifies the class of the Query
* IS for internet
* WARNING: ONLY IN IS SUPPORTED BY THIS APPLICATION
* IN for internet
*/
QCLASS: number;
}
export interface MessageRecourceRecord {
/**
* Domain name to wich resource record pertains
* Domain name to wich resource record points
*/
NAME: string;
@ -297,7 +296,7 @@ export interface MessageRecourceRecord {
RDLENGTH: number;
/**
* a variable length string of ectets taht describes
* a variable length string of octets that describes
* the resource. The format is defined by TYPE and CLASS
* field.
*
@ -306,10 +305,10 @@ export interface MessageRecourceRecord {
*/
RDATA: Buffer;
}
export interface IMessage {
header: IMessageHeader;
questions: IMessageQuestion[];
answers: MessageRecourceRecord[];
authorities: MessageRecourceRecord[];
additionals: MessageRecourceRecord[];
}
// export interface IMessage {
// header: IMessageHeader;
// questions: IMessageQuestion[];
// _answers: MessageRecourceRecord[];
// _authorities: MessageRecourceRecord[];
// _additionals: MessageRecourceRecord[];
// }