feat(core): the firewall settings page of routers after Java, measured against Java

The page konfig changes the firewall at run time (into the snapshot, back
into the project through projectWithSimulationChanges). KonfigCases feeds
Java's plug-in directly (25 cases, de and en); RouterWebRun plays two
stories over the network. Ten Java bugs named, not adopted. The web server
answers a method not written GET or POST with 501, as Java does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 18:13:31 +00:00
co-authored by Claude Opus 5.5
parent 7dac57cbbe
commit 8438b42018
23 changed files with 13229 additions and 24 deletions
+18 -3
View File
@@ -116,6 +116,7 @@ import { ApplicationThreads, waitUntil, type Steps, type Wait } from './threads.
import { EchoServer, SimpleClient } from './apps/echo.js';
import { WebBrowser, WebServer, type WebServerPage } from './apps/web.js';
import { firewallLogPage, forwardingTablePage, ripTablePage, routerIndexPage } from './apps/routerPages.js';
import { applyFirewallSettings, firewallSettingsPage } from './apps/firewallSettings.js';
import { VirtualFileSystem } from '../model/virtualFileSystem.js';
import {
PRODUCTION_TRACE_RETENTION,
@@ -1152,7 +1153,17 @@ export class NetworkRuntimeEngine {
const files = new VirtualFileSystem();
files.createDirectory('/webserver', true);
files.writeTextFile('/webserver/index.html', routerIndexPage(kind, language));
const pages = new Map<string, WebServerPage>([['log', () => firewallLogPage(this.firewallLog(nodeId), language)]]);
const pages = new Map<string, WebServerPage>([
['log', () => firewallLogPage(this.firewallLog(nodeId), language)],
[
'konfig',
(postData) => {
const result = applyFirewallSettings(this.firewallConfiguration(nodeId), postData);
if (result.configuration !== this.firewallConfiguration(nodeId)) this.setFirewallConfiguration(nodeId, result.configuration);
return firewallSettingsPage(result.configuration, language, result.rejected);
},
],
]);
if (kind === 'router') {
pages.set('routes', () => {
const rip = this.ripTable(nodeId);
@@ -5096,6 +5107,11 @@ export class NetworkRuntimeEngine {
// ── Firewall ─────────────────────────────────────────────────────────────
/** The node's firewall as it is now: changed at run time (the page konfig), it is in the snapshot, and so in the project saved from it. */
firewallConfiguration(nodeId: Id): FirewallConfiguration {
return this.stateValue.topologySnapshot.firewallConfigurationsByNodeId.get(nodeId) ?? firewallConfiguration();
}
setFirewallConfiguration(nodeId: Id, configuration: FirewallConfiguration): void {
const configurations = new Map(this.stateValue.topologySnapshot.firewallConfigurationsByNodeId);
configurations.set(nodeId, configuration);
@@ -5111,8 +5127,7 @@ export class NetworkRuntimeEngine {
* recorded, including "firewall inactive".
*/
evaluateFirewall(packet: IPv4Packet, nodeId: Id, incomingInterfaceId?: Id, frameIdentity?: number): FirewallDecision {
const configuration =
this.stateValue.topologySnapshot.firewallConfigurationsByNodeId.get(nodeId) ?? firewallConfiguration();
const configuration = this.firewallConfiguration(nodeId);
const decide = (accepted: boolean, ruleIndex: number | undefined, detail: string): FirewallDecision =>
this.recordFirewallDecision(packet, frameIdentity, nodeId, incomingInterfaceId, accepted, ruleIndex, detail);