Archived
1
0
This repository has been archived on 2024-09-09. You can view files and clone it, but cannot push or open issues or pull requests.
code-server/packages/dns/src/dns.ts
Kyle Carberry 85d2225e0c Featureful (#31)
* Fix loading within the CLI

* Remove app

* Remove promise handle

* Add initial travis file

* Add libxkbfile dependency

* Add libxkbfile-dev

* Add build script

* Fix malformed bash statement

* Remove yarn from script

* Improve build script

* Extract upx before usage

* Only run upx if on linux

* Ensure resource directory exists

* Pack runnable binary

* Export binary with platform

* Improve build process

* Install upx before running install script

* Update typescript version before running nexe

* Add os.release() function for multi-platform support

* Update travis.yml to improve deployment

* Add on CI

* Update to v1.31.0

* Add libsecret

* Update build target

* Skip cleanup

* Fix built-in extensions

* Add basics for apps

* Create custom DNS server

* Fix forking within CLI. Fixes TS language features

* Fix filename resolve

* Fix default extensions path

* Add custom dialog

* Store workspace path

* Remove outfiles

* Cleanup

* Always authed outside of CLI

* Use location.host for client

* Remove useless app interface

* Remove debug file for building wordlist

* Use chromes tcp host

* Update patch

* Build browser app before packaging

* Replace all css containing file:// URLs, fix webviews

* Fix save

* Fix mkdir
2019-02-21 11:55:42 -06:00

110 lines
3.0 KiB
TypeScript

import { field, logger } from "@coder/logger";
import * as http from "http";
//@ts-ignore
import * as named from "node-named";
import * as ip from "ip-address";
import { words, wordKeys } from "./words";
import * as dgram from "dgram";
const oldCreate = dgram.createSocket;
// tslint:disable-next-line:no-any
(<any>dgram).createSocket = (_: any, callback: any): dgram.Socket => {
return oldCreate("udp4", callback);
};
interface DnsQuery {
name(): string;
// tslint:disable-next-line:no-any
addAnswer(domain: string, target: any, ttl: number): void;
}
const dnsServer: {
listen(port: number, host: string, callback: () => void): void;
on(event: "query", callback: (query: DnsQuery) => void): void;
send(query: DnsQuery): void;
} = named.createServer();
const isDev = process.env.NODE_ENV !== "production";
const dnsPort = isDev ? 9999 : 53;
dnsServer.listen(dnsPort, "0.0.0.0", () => {
logger.info("DNS server started", field("port", dnsPort));
});
dnsServer.on("query", (query) => {
const domain = query.name();
const reqParts = domain.split(".");
if (reqParts.length < 2) {
dnsServer.send(query);
logger.info("Invalid request", field("request", domain));
return;
}
const allWords = reqParts.shift()!;
if (allWords.length > 16) {
dnsServer.send(query);
logger.info("Invalid request", field("request", domain));
return;
}
const wordParts = allWords.split(/(?=[A-Z])/);
const ipParts: string[] = [];
// Should be left with HowAreYouNow
for (let i = 0; i < wordParts.length; i++) {
const part = wordParts[i];
if (part.length > 4) {
dnsServer.send(query);
logger.info("Words too long", field("request", domain));
return;
}
const ipPart = words[part.toLowerCase()];
if (typeof ipPart === "undefined") {
dnsServer.send(query);
logger.info("Word not found in index", field("part", part), field("request", domain));
return;
}
ipParts.push(ipPart.toString());
}
const address = new ip.Address4(ipParts.join("."));
if (address.isValid()) {
logger.info("Responded with valid address query", field("address", address.address), field("request", domain));
query.addAnswer(domain, new named.ARecord(address.address), 99999);
} else {
logger.warn("Received invalid request", field("request", domain));
}
dnsServer.send(query);
});
const httpServer = http.createServer((request, response) => {
const remoteAddr = request.connection.remoteAddress;
if (!remoteAddr) {
response.writeHead(422);
response.end();
return;
}
const hostHeader = request.headers.host;
if (!hostHeader) {
response.writeHead(422);
response.end();
return;
}
const host = remoteAddr.split(".").map(p => wordKeys[Number.parseInt(p, 10)]).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join("");
logger.info("Resolved host", field("remote-addr", remoteAddr), field("host", host));
response.writeHead(200);
response.write(`${host}.${hostHeader}`);
response.end();
});
const httpPort = isDev ? 3000 : 80;
httpServer.listen(httpPort, "0.0.0.0", () => {
logger.info("HTTP server started", field("port", httpPort));
});