/* 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}`);