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:
@@ -64,3 +64,16 @@ Java-Filius schickt jede IP-Adresse und Maske beim Laden durch
|
||||
zählen nicht (`10..0.0.1`), Vorzeichen und führende Nullen gehen, ebenso
|
||||
Ziffern jeder Schrift in der BMP (Thai, Devanagari, Vollbreite) — aber kein
|
||||
Leerzeichen und kein 𝟏 (Ersatzpaar).
|
||||
|
||||
## `/dns/hosts`
|
||||
|
||||
Javas DNS-Server liest seine Einträge bei jeder Anfrage aus der Textdatei
|
||||
`/dns/hosts`. `DnsHostsCases` legt für jede Zeile von
|
||||
`packages/fls/test/dns-hosts.cases.txt` (eine ganze Datei je Zeile, ASCII,
|
||||
Zeilenumbruch als `\u000A`) einen Rechner mit dieser Datei an und schreibt,
|
||||
was `DNSServer.holeResourceRecords()` liefert, nach `dns-hosts.java.json`.
|
||||
Gemessen: Felder trennt nur ein einzelnes Leerzeichen (Tab und NBSP nicht),
|
||||
Zeilen nur LF; ein Name, den Javas Muster ablehnt (`1und1.de`, `müller.de`),
|
||||
wird leer, der Eintrag bleibt trotzdem; Typen außer A/MX/NS (auch `a`,
|
||||
`CNAME`, eine Kommentarzeile) gelten als gültig; eine TTL, die kein `int`
|
||||
ist, wird still 3600.
|
||||
|
||||
@@ -21,7 +21,7 @@ if [ ! -f "$upstream/target/filius.jar" ]; then
|
||||
fi
|
||||
classpath="$upstream/target/filius.jar:$upstream/target/lib/*"
|
||||
mkdir -p "$here/.build"
|
||||
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java"
|
||||
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java"
|
||||
# FILIUS writes its settings below $HOME; keep them out of the real one.
|
||||
mkdir -p "$here/.build/home"
|
||||
# Removed first: a crashed run must not leave the previous result standing.
|
||||
@@ -66,3 +66,10 @@ ipcheck="$root/packages/fls/test/ip-check.java.json"
|
||||
rm -f "$ipcheck"
|
||||
HOME="$here/.build/home" java -cp "$classpath:$here/.build" IpCheckCases "$cases" "$ipcheck" 2>&1 | grep -v 'logback\|^$' || true
|
||||
test -s "$ipcheck"
|
||||
|
||||
# DNSServer's own reading of /dns/hosts on hand-picked files (packages/fls/src/dnsHosts.ts).
|
||||
cases="$root/packages/fls/test/dns-hosts.cases.txt"
|
||||
dnshosts="$root/packages/fls/test/dns-hosts.java.json"
|
||||
rm -f "$dnshosts"
|
||||
HOME="$here/.build/home" xvfb-run -a java -cp "$classpath:$here/.build" DnsHostsCases "$cases" "$dnshosts" 2>&1 | grep -v 'logback\|^$' || true
|
||||
test -s "$dnshosts"
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Runs FILIUS's own reading of /dns/hosts (DNSServer.holeResourceRecords)
|
||||
// on every case of a list and writes the records Java keeps — the reference
|
||||
// for packages/fls/src/dnsHosts.ts. One case per line: a whole hosts file,
|
||||
// ASCII with Java-style unicode escapes (backslash, u, four hex digits), so
|
||||
// line breaks and odd spaces survive editors and hooks.
|
||||
//
|
||||
// Usage: java -cp filius.jar:lib/*:classes DnsHostsCases <cases txt> <output json>
|
||||
|
||||
import filius.hardware.knoten.Rechner;
|
||||
import filius.software.dns.DNSServer;
|
||||
import filius.software.dns.ResourceRecord;
|
||||
import filius.software.system.Datei;
|
||||
import filius.software.system.Dateisystem;
|
||||
import filius.software.system.InternetKnotenBetriebssystem;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class DnsHostsCases {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
List<Object> result = new ArrayList<>();
|
||||
for (String line : Files.readAllLines(Path.of(args[0]), StandardCharsets.US_ASCII)) {
|
||||
InternetKnotenBetriebssystem system = (InternetKnotenBetriebssystem) new Rechner().getSystemSoftware();
|
||||
Dateisystem fileSystem = system.getDateisystem();
|
||||
fileSystem.erstelleVerzeichnis(fileSystem.getRoot(), "dns");
|
||||
Datei hosts = new Datei();
|
||||
hosts.setName("hosts");
|
||||
hosts.setDateiInhalt(IpCheckCases.unescape(line));
|
||||
fileSystem.speicherDatei(fileSystem.holeRootPfad() + Dateisystem.FILE_SEPARATOR + "dns", hosts);
|
||||
DNSServer server = new DNSServer();
|
||||
server.setSystemSoftware(system);
|
||||
List<Object> records = new ArrayList<>();
|
||||
for (ResourceRecord record : server.holeResourceRecords()) {
|
||||
records.add(Arrays.asList(record.getDomainname(), record.getType(), record.getTtl(), record.getRdata()));
|
||||
}
|
||||
result.add(Arrays.asList(line, records));
|
||||
}
|
||||
try (FileOutputStream out = new FileOutputStream(args[1])) {
|
||||
out.write((FlsOracle.Json.write(result, "") + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
System.out.println("dns hosts cases: " + result.size());
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user