163 lines
3.5 KiB
TypeScript
163 lines
3.5 KiB
TypeScript
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<dnsPacket.Packet>((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(); |