Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/* globals require, __dirname, global, Buffer, process */
const fs = require("fs");
const options = {
key: fs.readFileSync(__dirname + "/http2-cert.key.pem"),
cert: fs.readFileSync(__dirname + "/http2-cert.pem"),
};
const http2 = require("http2");
const http = require("http");
const url = require("url");
const path = require("path");
let dnsPacket;
let libPath = path.join(__dirname, "../../xpcshell/dns-packet");
if (fs.existsSync(libPath)) {
// This is the path of dns-packet when running mochitest locally.
dnsPacket = require(libPath);
} else {
// This path is for running mochitest on try.
dnsPacket = require(path.join(__dirname, "./dns_packet"));
}
let serverPort = parseInt(process.argv[2].split("=")[1]);
let listeningPort = parseInt(process.argv[3].split("=")[1]);
let alpn = process.argv[4].split("=")[1];
let server = http2.createSecureServer(
options,
function handleRequest(req, res) {
let u = "";
if (req.url != undefined) {
u = url.parse(req.url, true);
}
if (u.pathname === "/dns-query") {
let payload = Buffer.from("");
req.on("data", function receiveData(chunk) {
payload = Buffer.concat([payload, chunk]);
});
req.on("end", function finishedData() {
let packet = dnsPacket.decode(payload);
let answers = [];
// Return the HTTPS RR to let Firefox connect to the HTTP/3 server
if (packet.questions[0].type === "HTTPS") {
answers.push({
name: packet.questions[0].name,
type: "HTTPS",
ttl: 55,
class: "IN",
flush: false,
data: {
priority: 1,
name: packet.questions[0].name,
values: [
{ key: "alpn", value: [alpn] },
{ key: "port", value: serverPort },
],
},
});
} else if (packet.questions[0].type === "A") {
answers.push({
name: packet.questions[0].name,
type: "A",
ttl: 55,
flush: false,
data: "127.0.0.1",
});
}
let buf = dnsPacket.encode({
type: "response",
id: packet.id,
flags: dnsPacket.RECURSION_DESIRED,
questions: packet.questions,
answers,
});
res.setHeader("Content-Type", "application/dns-message");
res.setHeader("Content-Length", buf.length);
res.writeHead(200);
res.write(buf);
res.end("");
});
}
}
);
server.listen(listeningPort);
console.log(`DoH server listening on ports ${server.address().port}`);