Files
mesh-catalog/modules/dnsmasq/index.ts

39 lines
1.5 KiB
TypeScript

// dnsmasq's events. The resolver's answered set changes whenever the mesh rewrites the wildcard file
// and restarts it — a machine joined the private network or left it. This watches that file and
// announces, from the resolver's own vantage, that a name became (or stopped being) resolvable on
// this node: DNS having actually propagated here, distinct from the mesh's own node.* events.
//
// Emits (novox/hq ADR 0041/0042):
// module.dnsmasq.name.added — this node's resolver now answers a machine's name
// module.dnsmasq.name.removed — it no longer does
import { emit } from "@novox/mesh-sdk/events";
import { DnsmasqClient } from "./client.js";
const dnsmasq = DnsmasqClient.fromEnv();
// name -> address, primed silently so a restart does not re-announce every name it already answered.
const known = new Map<string, string>();
let primed = false;
async function poll(): Promise<void> {
const now = new Map((await dnsmasq.answeredNames()).map((a) => [a.name, a.address]));
if (primed) {
for (const [name, address] of now) {
if (!known.has(name)) await emit("module.dnsmasq.name.added", { name, address });
}
for (const [name] of known) {
if (!now.has(name)) await emit("module.dnsmasq.name.removed", { name });
}
}
known.clear();
for (const [name, address] of now) known.set(name, address);
primed = true;
}
const run = (): void => void poll().catch((err) => console.error(`[dnsmasq] ${err}`));
setInterval(run, 30_000);
run();
console.log("[dnsmasq] watching the resolver's answered names");