mirror of
https://github.com/fosrl/pangolin.git
synced 2026-09-15 07:10:06 +02:00
replace node cache in dns server
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { LRUCache } from "lru-cache";
|
import { LRUCache } from "lru-cache";
|
||||||
|
|
||||||
const DEFAULT_MAX_KEYS = 10000;
|
const DEFAULT_MAX_KEYS = 10000;
|
||||||
const DEFAULT_TTL_MS = 3600 * 1000;
|
const DEFAULT_TTL_SECONDS = 3600;
|
||||||
|
|
||||||
export type LocalCache = {
|
export type LocalCache = {
|
||||||
get<T>(key: string): T | undefined;
|
get<T>(key: string): T | undefined;
|
||||||
@@ -14,10 +14,13 @@ export type LocalCache = {
|
|||||||
getTtl(key: string): number | undefined;
|
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<string, {}>({
|
const lru = new LRUCache<string, {}>({
|
||||||
max,
|
max,
|
||||||
ttl: DEFAULT_TTL_MS,
|
ttl: ttlSeconds * 1000,
|
||||||
updateAgeOnGet: false
|
updateAgeOnGet: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -22,14 +22,7 @@ export async function startDnsServer() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cacheOptions = {
|
dnsServer = new AuthoritativeDNSServer(dnsConfig.listen_port);
|
||||||
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);
|
|
||||||
|
|
||||||
await dnsServer.start();
|
await dnsServer.start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,11 @@
|
|||||||
|
|
||||||
import * as dgram from "dgram";
|
import * as dgram from "dgram";
|
||||||
import * as dns from "dns-packet";
|
import * as dns from "dns-packet";
|
||||||
import NodeCache from "node-cache";
|
|
||||||
import { createHash } from "crypto";
|
import { createHash } from "crypto";
|
||||||
|
import {
|
||||||
|
createLocalCache,
|
||||||
|
type LocalCache
|
||||||
|
} from "@server/lib/createLocalCache";
|
||||||
import { eq, and, gt, or, inArray, desc } from "drizzle-orm";
|
import { eq, and, gt, or, inArray, desc } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
db,
|
db,
|
||||||
@@ -46,8 +49,10 @@ type DNSRecord = {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DNS_CACHE_TTL_SECONDS = 300;
|
||||||
|
|
||||||
export class AuthoritativeDNSServer {
|
export class AuthoritativeDNSServer {
|
||||||
private cache: NodeCache;
|
private cache: LocalCache = createLocalCache(10_000, DNS_CACHE_TTL_SECONDS);
|
||||||
private server: dgram.Socket;
|
private server: dgram.Socket;
|
||||||
private port: number;
|
private port: number;
|
||||||
private inFlightLookups: Map<string, Promise<unknown>> = new Map();
|
private inFlightLookups: Map<string, Promise<unknown>> = new Map();
|
||||||
@@ -66,23 +71,16 @@ export class AuthoritativeDNSServer {
|
|||||||
private licenseRefreshInterval: NodeJS.Timeout | null = null;
|
private licenseRefreshInterval: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
// Cache for per-queryName zone resolution and SOA records
|
// Cache for per-queryName zone resolution and SOA records
|
||||||
private authoritativeDomainCache: NodeCache = new NodeCache({
|
private authoritativeDomainCache: LocalCache = createLocalCache(
|
||||||
stdTTL: 300,
|
10_000,
|
||||||
checkperiod: 60
|
DNS_CACHE_TTL_SECONDS
|
||||||
});
|
);
|
||||||
private soaCache: NodeCache = new NodeCache({
|
private soaCache: LocalCache = createLocalCache(
|
||||||
stdTTL: 300,
|
10_000,
|
||||||
checkperiod: 60
|
DNS_CACHE_TTL_SECONDS
|
||||||
});
|
);
|
||||||
|
|
||||||
constructor(port: number, cacheOptions: NodeCache.Options = {}) {
|
|
||||||
// Initialize cache with default TTL of 5 minutes
|
|
||||||
this.cache = new NodeCache({
|
|
||||||
stdTTL: 300,
|
|
||||||
checkperiod: 60,
|
|
||||||
...cacheOptions
|
|
||||||
});
|
|
||||||
|
|
||||||
|
constructor(port: number) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.server = dgram.createSocket("udp4");
|
this.server = dgram.createSocket("udp4");
|
||||||
|
|
||||||
@@ -130,9 +128,7 @@ export class AuthoritativeDNSServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.isLicensed) {
|
if (!this.isLicensed) {
|
||||||
logger.debug(
|
logger.debug("Refusing DNS query - license is not subscribed");
|
||||||
"Refusing DNS query - license is not subscribed"
|
|
||||||
);
|
|
||||||
// REFUSED (rcode=5) indicates a policy refusal by this nameserver.
|
// REFUSED (rcode=5) indicates a policy refusal by this nameserver.
|
||||||
this.sendResponse(packet, [], rinfo, false, 5, []);
|
this.sendResponse(packet, [], rinfo, false, 5, []);
|
||||||
return;
|
return;
|
||||||
@@ -1092,7 +1088,7 @@ export class AuthoritativeDNSServer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCacheStats(): NodeCache.Stats {
|
public getCacheStats(): { keys: number } {
|
||||||
return this.cache.getStats();
|
return this.cache.getStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user