import { Request, parseInput } from "./request"; import { RDATARecord, RecourceRecord } from "./record"; import { MonitoringPlugin, QuestionPlugin, DnsCore, AnswerHandler, ListenerPlugin, StoragePlugin, Record } from "./core"; import assert = require("assert"); import { RecordTypes } from "./types"; import { Question } from "./question"; function fromHex(data: string) { return Buffer.from(data.replace(/\s/g, ""), "hex"); } const itr = 100000; console.log("All tests x" + itr); let reqData = fromHex("E835 0100 0001 0000 0000 0000 07 6578616D706c65 03636F6D 00 0001 0001"); console.time("input parser") for (let i = 0; i < itr; i++) { parseInput(reqData); } console.timeEnd("input parser") console.time("complete") for (let i = 0; i < itr; i++) { 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.addAnswer(rr) request.serialize() } console.timeEnd("complete") console.time("complete 10 answers") for (let i = 0; i < itr; i++) { 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") for (let i = 0; i < 10; i++) request.addAnswer(rr); request.serialize() } console.timeEnd("complete 10 answers") class TestMonitoringPlugin implements MonitoringPlugin { constructor() { } async init(core) { } priority = 0 onRequest(domain, hostname, type) { } } class ARR extends RecourceRecord { TYPE = RecordTypes.A constructor(domain: string, ip: string) { super(); this.NAME = domain this.TTL = 1600 let data = Buffer.alloc(4) let idx = 0; ip.split(".").forEach(e => { data.writeUInt8(Number(e), idx); idx++; }) this.dataLock = () => { return { length: 4, serialize: (buffer, offset) => { data.copy(buffer, offset); return offset + 4; } } }; } } class TestQuestionPlugin implements QuestionPlugin { private Core: DnsCore question_types = [RecordTypes.A] priority = 0 async init(core) { this.Core = core; } async handleQuestion(question: Question, request: AnswerHandler, next: () => void) { assert(this.question_types.find(e => e === question.QTYPE), "Handler was called with not supported question type") let parts = question.QNAME.split(".") let domain = parts.splice(-2, 2).join(".") let hostname = parts.join("."); hostname = hostname !== "" ? hostname : "*" let records = await this.Core.storageManager.getRecords(domain, hostname, question.QTYPE) records.forEach(e => request.addAnswer(new ARR(question.QNAME, e.value))); } } class TestListenerPlugin implements ListenerPlugin { async init(core) { } priority = 0; callback: (data: Buffer, sender: string, max_size?: number) => Promise; registerCallback(callback) { this.callback = callback; } sendRequest(message: Buffer) { return this.callback(message, "localhost") } } class TestStoragePlugin implements StoragePlugin { re: Record = { domain: "example.com", hostname: "test", type: RecordTypes.A, value: "10.0.0.1", ttl: 1600 } constructor(record?: Record, private count: number = 1) { if (record) this.re = record; } priority = 0 no_cache = false record_types = [RecordTypes.A] isResponsible(domain: string) { // console.log("Is responsible") return true } async init(core) { } async getRecords(domain, hostname, type) { if (domain !== this.re.domain || hostname !== this.re.hostname || type != this.re.type) return undefined; let r = []; for (let i = 0; i < this.count; i++) { r.push(this.re); } return r; } async getAllRecordsForDomain(domain) { if (domain !== this.re.domain) return undefined; return [this.re]; } } let core = new DnsCore(); let listener = new TestListenerPlugin(); core.addListener(listener) core.addMonitoring(new TestMonitoringPlugin()); core.addQuestion(new TestQuestionPlugin()) let storage = new TestStoragePlugin({ domain: "example.com", hostname: "test", type: RecordTypes.A, ttl: 500, value: "10.0.0.1" }, 3) core.addStorage(storage); core.start().then(async () => { let reqData = fromHex("E835 0100 0001 0000 0000 0000 04 74657374 07 6578616D706c65 03 636F6D 00 0001 0001"); console.time("core handler"); for (let i = 0; i < itr; i++) { await listener.sendRequest(reqData) } console.timeEnd("core handler"); });