test(core): WLAN measured with Java FILIUS — a wireless cable is a cable, an SSID connects nothing
WlanRun pings on the new network wlan-lan: over wireless cables, over a plain cable, and to and from a notebook on the switch's SSID without a cable. The engine matches Java without a change: it runs the links only. Swift's wirelessAssociations, which join a host to its SSID's switch at run time, are not taken. ScenarioNetwork sets wireless cables, wireless cards and SSIDs; a corpus test pings over the wireless cables of multicast_server.fls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -417,3 +417,32 @@ Threads zwischen Karte und Ethernet-Schicht sitzen):
|
||||
(bei 90 % 55 Minuten), geprüft jede Sekunde, aufgefrischt nur von
|
||||
eingehenden Paketen (aus dem Code, nicht gemessen).
|
||||
|
||||
|
||||
## WLAN zur Laufzeit
|
||||
|
||||
`WlanRun` startet das Netz von `wlan-lan` (Notebooks 192.168.1.11 und .12
|
||||
mit Funkkarte, je über ein Funkkabel am Switch mit der SSID „schule";
|
||||
PC 192.168.1.13 an einem Kabel; Notebook 192.168.1.14 mit Funkkarte und
|
||||
SSID „schule", aber ohne Kabel) und schreibt nach `wlan-java-<ablauf>.java.json`
|
||||
die Frames und die Aufrufe. `ScenarioNetwork` setzt dazu `Kabel.setWireless`
|
||||
nach dem Feld `wireless` eines Kabels, die SSID des Switches (`switches`)
|
||||
und Funkkarte und SSID der Rechner (`wireless`). Abläufe: `pingWired` (.11
|
||||
pingt .13), `pingWireless` (.11 pingt .12), `pingWithoutCable` (.11 pingt
|
||||
.14), `pingFromWithoutCable` (.14 pingt .11).
|
||||
|
||||
Gemessen (01.10.2026), wie im Code (`Kabel.wireless`, `Betriebssystem.ssid`
|
||||
liest nur die Oberfläche):
|
||||
|
||||
* Ein Funkkabel ist zur Laufzeit ein Kabel wie jedes andere: dieselben
|
||||
Frames zu denselben Zeiten über Funk wie über Kabel (Ping 470 ms).
|
||||
* Eine SSID verbindet nichts. Das Notebook ohne Kabel bleibt unerreichbar
|
||||
(zweimal ARP, nach 5,5 s „Host unreachable" beim Absender), und es selbst
|
||||
erreicht niemanden. Das Funkkabel legt nur Javas Editor
|
||||
(`JHostKonfiguration.updateWifiConnection`: das alte entfernen, an den
|
||||
Switch mit der SSID anschließen); ändert sich die SSID eines Switches,
|
||||
entfernt er dessen Funkkabel, ohne neu zu verbinden. So entsteht in einer
|
||||
Datei ein Rechner mit SSID ohne Kabel.
|
||||
|
||||
Swift verbindet zur Laufzeit jeden Rechner mit eingeschaltetem WLAN mit
|
||||
einem freien Port des Switches seiner SSID, auch ohne Kabel
|
||||
(`wirelessAssociations`). Der Kern folgt Java: Er kennt nur die Kabel.
|
||||
|
||||
@@ -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" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.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" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.java" "$here/src/WlanRun.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.
|
||||
@@ -183,3 +183,13 @@ for story in pingLan pingRouted udpTwice udpBehind routedUdpBehind routedPingBes
|
||||
"$root/packages/core/test/scenarios/arp-routed.scenario.json" "$story" 16000 "$output" 2>&1 | grep -v 'logback\|^$' || true
|
||||
test -s "$output"
|
||||
done
|
||||
|
||||
# WLAN as Java FILIUS runs it: pings over wireless cables, a plain cable and
|
||||
# to a host on the switch's SSID without a cable (WlanRun); frames and calls.
|
||||
for story in pingWired pingWireless pingWithoutCable pingFromWithoutCable; do
|
||||
output="$root/packages/core/test/scenarios/wlan-java-$story.java.json"
|
||||
rm -f "$output"
|
||||
HOME="$here/.build/home" xvfb-run -a java -cp "$classpath:$here/.build" WlanRun \
|
||||
"$root/packages/core/test/scenarios/wlan-lan.scenario.json" "$story" 12000 "$output" 2>&1 | grep -v 'logback\|^$' || true
|
||||
test -s "$output"
|
||||
done
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// A core scenario's network (packages/core/test/scenarios/*.scenario.json:
|
||||
// nodes, links, devices, dhcpServers, dhcpClients) built in Java FILIUS the
|
||||
// nodes, links (wireless or not), devices, switches' and hosts' SSIDs,
|
||||
// dhcpServers, dhcpClients, …) built in Java FILIUS the
|
||||
// way the core reads it: a port's MAC is its `mac`, else the core's
|
||||
// stableGeneratedMacAddress. Started as the action mode starts it (every
|
||||
// system software's starten()); afterwards every frame each network card saw
|
||||
@@ -22,8 +23,10 @@ import filius.rahmenprogramm.nachrichten.Lauscher;
|
||||
import filius.software.dhcp.DHCPServer;
|
||||
import filius.software.dns.DNSServer;
|
||||
import filius.software.netzzugangsschicht.EthernetFrame;
|
||||
import filius.software.system.Betriebssystem;
|
||||
import filius.software.system.GatewayFirmware;
|
||||
import filius.software.system.InternetKnotenBetriebssystem;
|
||||
import filius.software.system.SwitchFirmware;
|
||||
import filius.software.system.VermittlungsrechnerBetriebssystem;
|
||||
import filius.software.transportschicht.Segment;
|
||||
import filius.software.transportschicht.TcpSegment;
|
||||
@@ -139,6 +142,17 @@ public class ScenarioNetwork {
|
||||
Map<String, Object> link = map(each);
|
||||
Kabel cable = new Kabel();
|
||||
cable.setAnschluesse(new Port[] { ports.get(link.get("sourcePort")), ports.get(link.get("targetPort")) });
|
||||
cable.setWireless(Boolean.TRUE.equals(link.get("wireless")));
|
||||
}
|
||||
// A switch's SSID, a host's wireless card and the SSID it joins: what the
|
||||
// editor reads to lay a wireless cable; the simulation does not ask.
|
||||
for (Map.Entry<String, Object> entry : map(scenario.getOrDefault("switches", new HashMap<>())).entrySet()) {
|
||||
((SwitchFirmware) nodes.get(entry.getKey()).getSystemSoftware()).setSSID((String) map(entry.getValue()).get("ssid"));
|
||||
}
|
||||
for (Map.Entry<String, Object> entry : map(scenario.getOrDefault("wireless", new HashMap<>())).entrySet()) {
|
||||
Betriebssystem os = (Betriebssystem) system(nodes.get(entry.getKey()));
|
||||
os.nicWireless(true);
|
||||
os.setSsid((String) map(entry.getValue()).get("ssid"));
|
||||
}
|
||||
for (Map.Entry<String, Object> entry : map(scenario.getOrDefault("dhcpServers", new HashMap<>())).entrySet()) {
|
||||
Map<String, Object> config = map(entry.getValue());
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
// Runs wlan-lan's network in Java FILIUS (ScenarioNetwork) and records what a
|
||||
// wireless connection does at run time: every frame each card saw and when
|
||||
// each call started and ended.
|
||||
//
|
||||
// WlanRun <scenario.json> <story> <milliseconds> <out.json>
|
||||
//
|
||||
// Notebooks 192.168.1.11 and .12 with wireless cards on the switch's SSID
|
||||
// "schule", each joined by a wireless cable; PC 192.168.1.13 on a plain
|
||||
// cable; notebook 192.168.1.14 with a wireless card on "schule" but no cable
|
||||
// (as after the switch's SSID changed: Java's editor removes the cable and
|
||||
// does not lay it again). The stories:
|
||||
// pingWired .11 pings .13
|
||||
// pingWireless .11 pings .12
|
||||
// pingWithoutCable .11 pings .14
|
||||
// pingFromWithoutCable .14 pings .11
|
||||
|
||||
import filius.software.vermittlungsschicht.IcmpPaket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WlanRun {
|
||||
static final String NOTEBOOK = "00000000-0000-0000-0000-000000000601";
|
||||
static final String UNCABLED = "00000000-0000-0000-0000-000000000605";
|
||||
|
||||
static ScenarioNetwork network;
|
||||
static final List<Object[]> events = new ArrayList<>();
|
||||
|
||||
static synchronized void event(String what) {
|
||||
events.add(new Object[] { System.currentTimeMillis() - network.start, what });
|
||||
}
|
||||
|
||||
static String icmp(IcmpPaket packet) {
|
||||
return packet == null ? "null" : "ICMP " + packet.getIcmpType() + "/" + packet.getIcmpCode() + " from " + packet.getSender();
|
||||
}
|
||||
|
||||
static void ping(String from, String target) {
|
||||
String label = "sendProbe " + target;
|
||||
event(label + " called");
|
||||
try {
|
||||
event(label + " returned " + icmp(network.system(from).holeICMP().sendProbe(target, 64, 1, 1)));
|
||||
} catch (Exception e) {
|
||||
event(label + " failed " + e.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
network = ScenarioNetwork.read(args[0]);
|
||||
String story = args[1];
|
||||
long end = Long.parseLong(args[2]);
|
||||
network.start();
|
||||
Thread.sleep(500);
|
||||
switch (story) {
|
||||
case "pingWired":
|
||||
ping(NOTEBOOK, "192.168.1.13");
|
||||
break;
|
||||
case "pingWireless":
|
||||
ping(NOTEBOOK, "192.168.1.12");
|
||||
break;
|
||||
case "pingWithoutCable":
|
||||
ping(NOTEBOOK, "192.168.1.14");
|
||||
break;
|
||||
case "pingFromWithoutCable":
|
||||
ping(UNCABLED, "192.168.1.11");
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown story " + story);
|
||||
}
|
||||
long rest = network.start + end - System.currentTimeMillis();
|
||||
if (rest > 0) Thread.sleep(rest);
|
||||
|
||||
ScenarioNetwork.Json out = new ScenarioNetwork.Json();
|
||||
out.open('{');
|
||||
network.writeFrames(out);
|
||||
synchronized (WlanRun.class) {
|
||||
out.key("events").open('[');
|
||||
for (Object[] each : events) out.open('[').number((Long) each[0]).string((String) each[1]).close(']');
|
||||
out.close(']');
|
||||
}
|
||||
out.close('}');
|
||||
network.stop();
|
||||
ScenarioNetwork.write(args[3], out);
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user