263 lines · 10.6 KB
import { HttpError, badRequest } from "../errors";

const DOH_ENDPOINT = "https://cloudflare-dns.com/dns-query";
const DOH_TIMEOUT_MS = 3_000;
const HTTP_UNAVAILABLE = 503;
const DNS_NOERROR = 0;
const DNS_NXDOMAIN = 3;
const CACHE_TTL_MS = 60_000;
const MAX_CACHE_ENTRIES = 500;
const MAX_CNAME_DEPTH = 5;
const MAX_DOH_BYTES = 64 * 1024;
const TYPE_A = 1;
const TYPE_CNAME = 5;
const TYPE_AAAA = 28;
const IPV4_OCTETS = 4;
const IPV6_GROUPS = 8;
const BYTE = 256;
const GROUP = 0x10000;

type Answer = { type: number; data: string };
type DohResponse = { Status: number; Answer?: Answer[] };
export type Resolver = (name: string, type: "A" | "AAAA") => Promise<DohResponse>;

/** Non-public IPv4 space as CIDRs (RFC 6890 special-purpose registry plus multicast and reserved). */
const PRIVATE_V4_CIDRS: Array<[string, number]> = [
  ["0.0.0.0", 8],
  ["10.0.0.0", 8],
  ["100.64.0.0", 10],
  ["127.0.0.0", 8],
  ["169.254.0.0", 16],
  ["172.16.0.0", 12],
  ["192.0.0.0", 24],
  ["192.0.2.0", 24],
  ["192.88.99.0", 24],
  ["192.168.0.0", 16],
  ["198.18.0.0", 15],
  ["198.51.100.0", 24],
  ["203.0.113.0", 24],
  ["224.0.0.0", 4],
  ["240.0.0.0", 4],