This repository has been archived on 2024-04-14. You can view files and clone it, but cannot push or open issues or pull requests.
icydns/src/dns/cache.ts

73 lines
1.8 KiB
TypeScript
Raw Normal View History

2021-05-15 08:45:12 +00:00
import { CachedZone, DNSRecord, DNSZone, SOARecord } from "../models/interfaces";
import { readZoneFile } from "./reader";
import { DNSRecordType } from "./records";
import { writeZoneFile } from "./writer";
export class DNSCache {
private cached: Record<string, CachedZone> = {};
constructor(private ttl = 1600) {}
has(name: string): boolean {
return this.cached[name] != null;
}
async get(name: string): Promise<CachedZone | null> {
const cached = this.cached[name];
if (!cached) {
return null;
}
if (cached.changed.getTime() < new Date().getTime() - this.ttl * 1000) {
return this.load(name, cached.file);
}
return this.cached[name];
}
async set(name: string, zone: CachedZone): Promise<void> {
this.cached[name] = zone;
}
async load(name: string, file: string): Promise<CachedZone> {
const zoneFile = await readZoneFile(file);
const cache = {
name,
file,
zone: zoneFile,
added: new Date(),
changed: new Date()
}
this.cached[name] = cache;
return cache;
}
async save(name: string): Promise<void> {
const zone = await this.get(name);
if (!zone) {
throw new Error('No such cached zone file!');
}
await writeZoneFile(zone.zone, zone.file);
}
async update(name: string, newZone?: CachedZone): Promise<void> {
let zone: CachedZone | null;
if (newZone) {
zone = newZone;
} else {
zone = await this.get(name);
}
if (!zone) {
throw new Error('No such cached zone file!');
}
zone.changed = new Date();
const soa = zone.zone.records.find((record) => record.type === DNSRecordType.SOA) as SOARecord;
soa.serial = Math.floor(Date.now() / 1000);
this.set(name, zone);
return this.save(name);
}
}