feat(fls): DNS records from /dns/hosts, as Java's server answers them
Java's DNS server reads its records from the text file /dns/hosts on every query. dnsHosts.ts ports that reading (DNSServer.leseRecordListe, ResourceRecord, Dateisystem.holeDatei) and keeps in the model the records Java answers: type exactly A, MX or NS, and a name Java accepted. The file stays in the file system as it is. Both oracles read 76 hand-picked hosts files (dns-hosts.cases.txt): the Java oracle through DNSServer.holeResourceRecords (DnsHostsCases), the Swift oracle through TopologyDNSHostsFileCodec (--dns-hosts). The Java view matches Java on every case; the model matches Swift except for 33 named cases in twelve reasons: Java splits at single spaces and LF only, has no comments or "IN", turns a TTL that is no int into 3600, keeps duplicates, and empties names with a leading digit. The Swift dump now carries each server's records; the corpus comparison covers them on 16 files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -145,6 +145,7 @@ function systemOf(project: ImportedProject, nodeId: Id) {
|
||||
result.dnsServer = {
|
||||
recursiveResolutionEnabled: dns.recursiveResolutionEnabled,
|
||||
forwardingServerIPAddress: dns.forwardingServerIPAddress ?? null,
|
||||
records: dns.records.map((record) => [record.name, record.type, record.ttlSeconds, record.target]),
|
||||
};
|
||||
}
|
||||
const remoteLink = project.remoteLinkConfigurations.get(nodeId);
|
||||
@@ -787,12 +788,39 @@ describe('importProject rules', () => {
|
||||
expect(project.simpleClientConfigurations.get(notebook!)).toEqual({ targetAddress: '10.0.0.9', targetPort: 7 });
|
||||
expect(project.firewallConfigurationsByNodeId.get(notebook!)).toMatchObject({ isActive: true, defaultPolicy: 'accept' });
|
||||
expect([forwarding, self, iterative].map((id) => project.dnsServerConfigurations.get(id!))).toEqual([
|
||||
{ recursiveResolutionEnabled: true, forwardingServerIPAddress: '8.8.8.8' },
|
||||
{ recursiveResolutionEnabled: true },
|
||||
{ recursiveResolutionEnabled: false },
|
||||
{ recursiveResolutionEnabled: true, forwardingServerIPAddress: '8.8.8.8', records: [] },
|
||||
{ recursiveResolutionEnabled: true, records: [] },
|
||||
{ recursiveResolutionEnabled: false, records: [] },
|
||||
]);
|
||||
});
|
||||
|
||||
it("takes a DNS server's records from its /dns/hosts, and names the node in a warning", () => {
|
||||
const hosts = 'www.filius.de A 3600 141.99.2.10\nfilius.de MX 3600 mail.filius.de\nbroken.de A 3600 .1.2.3\n';
|
||||
const server = flsNode('Rechner', {
|
||||
name: 'DNS',
|
||||
interfaces: [nic('10.0.0.1')],
|
||||
system: {
|
||||
applications: [{ key: 'dns', javaClass: 'filius.software.dns.DNSServer', source: flsNode('Rechner').source, isActive: true }],
|
||||
fileSystem: {
|
||||
kind: 'directory',
|
||||
name: 'root',
|
||||
children: [
|
||||
{ kind: 'directory', name: 'dns', children: [{ kind: 'file', name: 'hosts', type: 'text', content: hosts, children: [] }] },
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
const project = importProject(topology({ nodes: [server] }), counter());
|
||||
const [id] = project.graph.nodes.map((node) => node.id);
|
||||
|
||||
expect(project.dnsServerConfigurations.get(id!)?.records).toEqual([
|
||||
{ name: 'www.filius.de', type: 'A', ttlSeconds: 3600, target: '141.99.2.10' },
|
||||
{ name: 'filius.de', type: 'MX', ttlSeconds: 3600, target: 'mail.filius.de.' },
|
||||
]);
|
||||
expect(project.virtualFileSystems.get(id!)?.textFile('/dns/hosts')).toBe(hosts);
|
||||
expect(project.warnings).toEqual(["node 'DNS': DNS record 'broken.de A .1.2.3' has no usable IPv4 address, left out (it stays in /dns/hosts)"]);
|
||||
});
|
||||
|
||||
it('leaves out a cable to itself and one to a port that already has a cable', () => {
|
||||
const project = importProject(
|
||||
topology({
|
||||
|
||||
Reference in New Issue
Block a user