feat: F4.6g2 the DNS server window, its records being /dns/hosts
Oracle DnsWindowRun uses Java's DNS server window as a person does and asks a computer's resolver after each step. The core's DNS server is a program its window changes: on and off (its socket on port 53), recursive resolution, and records that are /dns/hosts, read on every query as Java's server reads them (the reader moves from fls to the core). The snapshot carries every installed DNS server with whether it runs. The room takes the window's actions, sends its view and writes the server back after the run; the editor shows Java's window with its three tabs. Not taken from Java: a cell edit spilling into records of another type, an add losing what another program wrote into the file, an empty mail domain, a removal hitting the first record of the name. A table cell no longer takes the room's value over what is being typed (the web server's too). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -112,11 +112,12 @@ import { PacketCapture, PRODUCTION_CAPTURE_RETENTION, type CaptureRetentionPolic
|
||||
import { ICMP_TYPE_CODE } from './captureRows.js';
|
||||
import { JavaCompatibleRandom } from './random.js';
|
||||
import { routeTableRows, type RouteRow } from './routeTable.js';
|
||||
import { EMPTY_TOPOLOGY_SNAPSHOT, withSnapshot, type NodeSnapshot, type TopologySnapshot } from './snapshot.js';
|
||||
import { EMPTY_TOPOLOGY_SNAPSHOT, withSnapshot, type DnsServerSnapshot, type NodeSnapshot, type TopologySnapshot } from './snapshot.js';
|
||||
import { installationFiles } from './apps/installation.js';
|
||||
import { RuntimeSpeed } from './speed.js';
|
||||
import { ApplicationThreads, waitUntil, type Steps, type Wait } from './threads.js';
|
||||
import { EchoServer, SimpleClient } from './apps/echo.js';
|
||||
import { DnsServer } from './apps/dnsServer.js';
|
||||
import { WebBrowser, WebServer, type WebServerPage } from './apps/web.js';
|
||||
import { EmailClient, type EmailClientFolders } from './apps/emailClient.js';
|
||||
import { EmailServer } from './apps/emailServer.js';
|
||||
@@ -934,6 +935,7 @@ export class NetworkRuntimeEngine {
|
||||
/** The programs, by node (initializePrograms). */
|
||||
private readonly echoServersByNodeId = new Map<Id, EchoServer>();
|
||||
private readonly simpleClientsByNodeId = new Map<Id, SimpleClient>();
|
||||
private readonly dnsServersByNodeId = new Map<Id, DnsServer>();
|
||||
private readonly webServersByNodeId = new Map<Id, WebServer>();
|
||||
private readonly webBrowsersByNodeId = new Map<Id, WebBrowser>();
|
||||
private readonly emailServersByNodeId = new Map<Id, EmailServer>();
|
||||
@@ -1151,6 +1153,11 @@ export class NetworkRuntimeEngine {
|
||||
}
|
||||
|
||||
/** The node's generic client while the simulation runs, if it has one installed. */
|
||||
/** A node's DNS server while the simulation runs (installed, running or not). */
|
||||
dnsServer(nodeId: Id): DnsServer | undefined {
|
||||
return this.dnsServersByNodeId.get(nodeId);
|
||||
}
|
||||
|
||||
simpleClient(nodeId: Id): SimpleClient | undefined {
|
||||
return this.simpleClientsByNodeId.get(nodeId);
|
||||
}
|
||||
@@ -1381,6 +1388,8 @@ export class NetworkRuntimeEngine {
|
||||
firewallConfigurationsByNodeId: program === 'firewall' ? copied(snapshot.firewallConfigurationsByNodeId, source.firewallConfigurationsByNodeId) : snapshot.firewallConfigurationsByNodeId,
|
||||
});
|
||||
if (running !== undefined && this.hasProgram(nodeId, running)) this.startProgram(nodeId, running);
|
||||
const dns = program === 'dnsServer' ? state.topologySnapshot.dnsServerConfigurationsByNodeId.get(nodeId) : undefined;
|
||||
if (dns !== undefined) this.startDnsServer(nodeId, dns);
|
||||
this.applicationThreads.resume();
|
||||
}
|
||||
|
||||
@@ -1432,6 +1441,8 @@ export class NetworkRuntimeEngine {
|
||||
state.topologySnapshot = withSnapshot(snapshot, { gnutellaByNodeId: without(snapshot.gnutellaByNodeId) });
|
||||
break;
|
||||
case 'dnsServer':
|
||||
this.dnsServersByNodeId.get(nodeId)?.setActive(false);
|
||||
this.dnsServersByNodeId.delete(nodeId);
|
||||
state.topologySnapshot = withSnapshot(snapshot, { dnsServerConfigurationsByNodeId: without(snapshot.dnsServerConfigurationsByNodeId) });
|
||||
break;
|
||||
case 'firewall':
|
||||
@@ -2005,14 +2016,34 @@ export class NetworkRuntimeEngine {
|
||||
|
||||
// ── DNS (after Java's DNSServer and Resolver) ────────────────────────────
|
||||
|
||||
/** Every DNS server switched on listens on port 53. */
|
||||
/** Each DNS server installed; the ones switched on listen on port 53. */
|
||||
private initializeDnsState(): void {
|
||||
const state = this.stateValue;
|
||||
state.dnsServerSocketIdsByNodeId.clear();
|
||||
for (const [nodeId, configuration] of state.topologySnapshot.dnsServerConfigurationsByNodeId) {
|
||||
const socketId = this.bindUdpSocket(nodeId, { localPort: DNS_PORT });
|
||||
if (socketId !== undefined) state.dnsServerSocketIdsByNodeId.set(nodeId, socketId);
|
||||
}
|
||||
this.dnsServersByNodeId.clear();
|
||||
for (const [nodeId, configuration] of state.topologySnapshot.dnsServerConfigurationsByNodeId) this.startDnsServer(nodeId, configuration);
|
||||
}
|
||||
|
||||
private startDnsServer(nodeId: Id, configuration: DnsServerSnapshot): void {
|
||||
const server = new DnsServer(
|
||||
{
|
||||
files: () => this.stateValue.topologySnapshot.fileSystemsByNodeId.get(nodeId),
|
||||
filesToWrite: () => this.nodeFiles(nodeId),
|
||||
open: () => {
|
||||
const socketId = this.bindUdpSocket(nodeId, { localPort: DNS_PORT });
|
||||
if (socketId !== undefined) this.stateValue.dnsServerSocketIdsByNodeId.set(nodeId, socketId);
|
||||
},
|
||||
close: () => {
|
||||
const socketId = this.stateValue.dnsServerSocketIdsByNodeId.get(nodeId);
|
||||
if (socketId !== undefined) this.closeSocket(socketId);
|
||||
this.stateValue.dnsServerSocketIdsByNodeId.delete(nodeId);
|
||||
},
|
||||
},
|
||||
configuration,
|
||||
false,
|
||||
);
|
||||
this.dnsServersByNodeId.set(nodeId, server);
|
||||
server.setActive(configuration.isActive !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2064,10 +2095,10 @@ export class NetworkRuntimeEngine {
|
||||
* (the NS record of the question's zone and its address).
|
||||
*/
|
||||
private answerDnsQuestion(nodeId: Id, question: DnsQuestion, done: (answers: DnsMessageRecord[]) => void): void {
|
||||
const configuration = this.stateValue.topologySnapshot.dnsServerConfigurationsByNodeId.get(nodeId);
|
||||
const records = (configuration?.records ?? []).map(messageRecord);
|
||||
const server = this.dnsServersByNodeId.get(nodeId);
|
||||
const records = (server?.answering ?? []).map(messageRecord);
|
||||
const local = localDnsAnswers(question, records);
|
||||
if (local.length > 0 || configuration?.recursiveResolutionEnabled !== true) {
|
||||
if (local.length > 0 || server?.recursiveResolutionEnabled !== true) {
|
||||
done(local.length > 0 ? local : dnsReferral(question, records));
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user