import { expect, tap } from '@push.rocks/tapbundle'; import { tapNodeTools } from '@push.rocks/tapbundle/node'; import * as dnsPacket from 'dns-packet'; import * as https from 'https'; import * as dgram from 'dgram'; import * as smartdns from '../ts_server/index.js'; let dnsServer: smartdns.DnsServer; tap.test('should create an instance of DnsServer', async () => { // Use valid options const httpsData = await tapNodeTools.createHttpsCert(); dnsServer = new smartdns.DnsServer({ httpsKey: httpsData.key, httpsCert: httpsData.cert, httpsPort: 8080, udpPort: 8081, }); expect(dnsServer).toBeInstanceOf(smartdns.DnsServer); }); tap.test('should start the server', async () => { await dnsServer.start(); // @ts-ignore expect(dnsServer.httpsServer).toBeDefined(); }); tap.test('lets add a handler', async () => { dnsServer.registerHandler('*.bleu.de', ['A'], (question) => { return { name: question.name, type: 'A', class: 'IN', ttl: 300, data: '127.0.0.1', }; }); // @ts-ignore const response = dnsServer.processDnsRequest({ type: 'query', id: 1, flags: 0, questions: [ { name: 'dnsly_a.bleu.de', type: 'A', class: 'IN', }, ], answers: [], }); expect(response.answers[0]).toEqual({ name: 'dnsly_a.bleu.de', type: 'A', class: 'IN', ttl: 300, data: '127.0.0.1', }); }); tap.test('lets query over https', async () => { const query = dnsPacket.encode({ type: 'query', id: 2, flags: dnsPacket.RECURSION_DESIRED, questions: [ { name: 'dnsly_a.bleu.de', type: 'A', class: 'IN', }, ], }); const response = await fetch('https://localhost:8080/dns-query', { method: 'POST', body: query, headers: { 'Content-Type': 'application/dns-message', } }); expect(response.status).toEqual(200); const responseData = await response.arrayBuffer(); const dnsResponse = dnsPacket.decode(Buffer.from(responseData)); console.log(dnsResponse.answers[0]); expect(dnsResponse.answers[0]).toEqual({ name: 'dnsly_a.bleu.de', type: 'A', class: 'IN', ttl: 300, flush: false, data: '127.0.0.1', }); }); tap.test('lets query over udp', async () => { const client = dgram.createSocket('udp4'); const query = dnsPacket.encode({ type: 'query', id: 3, flags: dnsPacket.RECURSION_DESIRED, questions: [ { name: 'dnsly_a.bleu.de', type: 'A', class: 'IN', }, ], }); const responsePromise = new Promise((resolve, reject) => { client.on('message', (msg) => { const dnsResponse = dnsPacket.decode(msg); resolve(dnsResponse); client.close(); }); client.on('error', (err) => { reject(err); client.close(); }); client.send(query, 8081, 'localhost', (err) => { if (err) { reject(err); client.close(); } }); }); const dnsResponse = await responsePromise; console.log(dnsResponse.answers[0]); expect(dnsResponse.answers[0]).toEqual({ name: 'dnsly_a.bleu.de', type: 'A', class: 'IN', ttl: 300, flush: false, data: '127.0.0.1', }); }); tap.test('should run for a while', async (toolsArg) => { await toolsArg.delayFor(1000); }); tap.test('should stop the server', async () => { await dnsServer.stop(); // @ts-ignore expect(dnsServer.httpsServer).toBeFalsy(); }); await tap.start();