diff --git a/server/lib/createLocalCache.ts b/server/lib/createLocalCache.ts index f37fc48ad..f2dddda15 100644 --- a/server/lib/createLocalCache.ts +++ b/server/lib/createLocalCache.ts @@ -1,7 +1,7 @@ import { LRUCache } from "lru-cache"; const DEFAULT_MAX_KEYS = 10000; -const DEFAULT_TTL_MS = 3600 * 1000; +const DEFAULT_TTL_SECONDS = 3600; export type LocalCache = { get(key: string): T | undefined; @@ -14,10 +14,13 @@ export type LocalCache = { getTtl(key: string): number | undefined; }; -export function createLocalCache(max = DEFAULT_MAX_KEYS): LocalCache { +export function createLocalCache( + max = DEFAULT_MAX_KEYS, + ttlSeconds = DEFAULT_TTL_SECONDS +): LocalCache { const lru = new LRUCache({ max, - ttl: DEFAULT_TTL_MS, + ttl: ttlSeconds * 1000, updateAgeOnGet: false }); diff --git a/server/private/dns.ts b/server/private/dns.ts index d5401c355..d77f789ac 100644 --- a/server/private/dns.ts +++ b/server/private/dns.ts @@ -22,14 +22,7 @@ export async function startDnsServer() { return; } - const cacheOptions = { - stdTTL: 300, // 5 minutes default TTL - checkperiod: 60, // Check for expired keys every 60 seconds - useClones: false // Better performance - }; - - // Create DNS server - dnsServer = new AuthoritativeDNSServer(dnsConfig.listen_port, cacheOptions); + dnsServer = new AuthoritativeDNSServer(dnsConfig.listen_port); await dnsServer.start(); } diff --git a/server/private/lib/dns/server.ts b/server/private/lib/dns/server.ts index 2e9167ebb..7a1ef2b07 100644 --- a/server/private/lib/dns/server.ts +++ b/server/private/lib/dns/server.ts @@ -13,8 +13,11 @@ import * as dgram from "dgram"; import * as dns from "dns-packet"; -import NodeCache from "node-cache"; import { createHash } from "crypto"; +import { + createLocalCache, + type LocalCache +} from "@server/lib/createLocalCache"; import { eq, and, gt, or, inArray, desc } from "drizzle-orm"; import { db, @@ -46,8 +49,10 @@ type DNSRecord = { enabled: boolean; }; +const DNS_CACHE_TTL_SECONDS = 300; + export class AuthoritativeDNSServer { - private cache: NodeCache; + private cache: LocalCache = createLocalCache(10_000, DNS_CACHE_TTL_SECONDS); private server: dgram.Socket; private port: number; private inFlightLookups: Map> = new Map(); @@ -66,23 +71,16 @@ export class AuthoritativeDNSServer { private licenseRefreshInterval: NodeJS.Timeout | null = null; // Cache for per-queryName zone resolution and SOA records - private authoritativeDomainCache: NodeCache = new NodeCache({ - stdTTL: 300, - checkperiod: 60 - }); - private soaCache: NodeCache = new NodeCache({ - stdTTL: 300, - checkperiod: 60 - }); - - constructor(port: number, cacheOptions: NodeCache.Options = {}) { - // Initialize cache with default TTL of 5 minutes - this.cache = new NodeCache({ - stdTTL: 300, - checkperiod: 60, - ...cacheOptions - }); + private authoritativeDomainCache: LocalCache = createLocalCache( + 10_000, + DNS_CACHE_TTL_SECONDS + ); + private soaCache: LocalCache = createLocalCache( + 10_000, + DNS_CACHE_TTL_SECONDS + ); + constructor(port: number) { this.port = port; this.server = dgram.createSocket("udp4"); @@ -130,9 +128,7 @@ export class AuthoritativeDNSServer { } if (!this.isLicensed) { - logger.debug( - "Refusing DNS query - license is not subscribed" - ); + logger.debug("Refusing DNS query - license is not subscribed"); // REFUSED (rcode=5) indicates a policy refusal by this nameserver. this.sendResponse(packet, [], rinfo, false, 5, []); return; @@ -1092,7 +1088,7 @@ export class AuthoritativeDNSServer { }); } - public getCacheStats(): NodeCache.Stats { + public getCacheStats(): { keys: number } { return this.cache.getStats(); }