feat(core): TCP in the simulation core
engine.ts ports Swift's "Java-compatible TCP sockets" in one piece, since half a state machine could not be checked: server and client sockets (a free port from Java's random numbers on their own seed), the three-way handshake with its result (connected, invalid socket, unreachable, timed out), segments of 1460 bytes, messages up to the push, a timeout of 3 × 2.5 s with at most three attempts, closing through every Java state including TIME_WAIT (2.5 s), sequence numbers modulo 2^32. Three scenarios match the Swift engine trace for trace: a LAN with data over three segments, closing from both ends, a closed port and an unreachable host; two networks through a router with a firewall rule, data lost until the connection closes, and an accepted socket that does not hold the port of its closed listener; CLOSING, reached by a lost FIN. The engine delivers a FIN within the same close, so both ends close at once only with packet loss; an empty message does not arrive in Swift (it does not advance the sequence number), nor here. Swift's four TCP engine tests are ported, with tests for stopping, a foreign SYN+ACK at a listener and the flag names. 17 mutation probes, 16 caught; the other (delivered, not waited, not connected gives unreachable) cannot be reached through Swift's engine, which never sends a reset and always acknowledges correctly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
{
|
||||
"seed": 31,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000101",
|
||||
"kind": "pc",
|
||||
"ports": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000111",
|
||||
"label": "eth0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000102",
|
||||
"kind": "pc",
|
||||
"ports": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000112",
|
||||
"label": "eth0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000103",
|
||||
"kind": "pc",
|
||||
"ports": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000113",
|
||||
"label": "eth0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000104",
|
||||
"kind": "networkSwitch",
|
||||
"ports": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000121",
|
||||
"label": "sw1"
|
||||
},
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000122",
|
||||
"label": "sw2"
|
||||
},
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000123",
|
||||
"label": "sw3"
|
||||
},
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000124",
|
||||
"label": "sw4"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-00000000F001",
|
||||
"sourceNode": "00000000-0000-0000-0000-000000000101",
|
||||
"sourcePort": "00000000-0000-0000-0000-000000000111",
|
||||
"targetNode": "00000000-0000-0000-0000-000000000104",
|
||||
"targetPort": "00000000-0000-0000-0000-000000000121"
|
||||
},
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-00000000F002",
|
||||
"sourceNode": "00000000-0000-0000-0000-000000000102",
|
||||
"sourcePort": "00000000-0000-0000-0000-000000000112",
|
||||
"targetNode": "00000000-0000-0000-0000-000000000104",
|
||||
"targetPort": "00000000-0000-0000-0000-000000000122"
|
||||
},
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-00000000F003",
|
||||
"sourceNode": "00000000-0000-0000-0000-000000000103",
|
||||
"sourcePort": "00000000-0000-0000-0000-000000000113",
|
||||
"targetNode": "00000000-0000-0000-0000-000000000104",
|
||||
"targetPort": "00000000-0000-0000-0000-000000000123"
|
||||
}
|
||||
],
|
||||
"devices": {
|
||||
"00000000-0000-0000-0000-000000000101": {
|
||||
"ip": "192.168.0.10",
|
||||
"mask": "255.255.255.0"
|
||||
},
|
||||
"00000000-0000-0000-0000-000000000102": {
|
||||
"ip": "192.168.0.20",
|
||||
"mask": "255.255.255.0"
|
||||
},
|
||||
"00000000-0000-0000-0000-000000000103": {
|
||||
"ip": "192.168.0.30",
|
||||
"mask": "255.255.255.0"
|
||||
}
|
||||
},
|
||||
"switches": {
|
||||
"00000000-0000-0000-0000-000000000104": {
|
||||
"ssid": "lab",
|
||||
"retention": 5000
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"op": "openTcpServer",
|
||||
"node": "00000000-0000-0000-0000-000000000101",
|
||||
"port": 80
|
||||
},
|
||||
{
|
||||
"op": "openTcpServer",
|
||||
"node": "00000000-0000-0000-0000-000000000101",
|
||||
"port": 80
|
||||
},
|
||||
{
|
||||
"op": "openTcpClient",
|
||||
"node": "00000000-0000-0000-0000-000000000102",
|
||||
"target": "192.168.0.10",
|
||||
"port": 80
|
||||
},
|
||||
{
|
||||
"op": "connectTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000002"
|
||||
},
|
||||
{
|
||||
"op": "acceptedTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000001"
|
||||
},
|
||||
{
|
||||
"op": "peerTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000002"
|
||||
},
|
||||
{
|
||||
"op": "sendTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000002",
|
||||
"payload": "GET /"
|
||||
},
|
||||
{
|
||||
"op": "receiveTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000003"
|
||||
},
|
||||
{
|
||||
"op": "sendTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000003",
|
||||
"payload": "x",
|
||||
"repeatCount": 3000
|
||||
},
|
||||
{
|
||||
"op": "receiveTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000002"
|
||||
},
|
||||
{
|
||||
"op": "receiveTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000002"
|
||||
},
|
||||
{
|
||||
"op": "closeSocket",
|
||||
"socket": "00000000-0000-0000-0000-000000000002"
|
||||
},
|
||||
{
|
||||
"op": "advance",
|
||||
"to": 3000
|
||||
},
|
||||
{
|
||||
"op": "closeSocket",
|
||||
"socket": "00000000-0000-0000-0000-000000000003"
|
||||
},
|
||||
{
|
||||
"op": "advance",
|
||||
"to": 4000
|
||||
},
|
||||
{
|
||||
"op": "advance",
|
||||
"to": 8000
|
||||
},
|
||||
{
|
||||
"op": "cleanTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000002"
|
||||
},
|
||||
{
|
||||
"op": "cleanTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000001"
|
||||
},
|
||||
{
|
||||
"op": "connectTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000001"
|
||||
},
|
||||
{
|
||||
"op": "openTcpClient",
|
||||
"node": "00000000-0000-0000-0000-000000000103",
|
||||
"target": "192.168.0.10",
|
||||
"port": 81
|
||||
},
|
||||
{
|
||||
"op": "sendTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000004",
|
||||
"payload": "ohne Verbindung"
|
||||
},
|
||||
{
|
||||
"op": "connectTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000004"
|
||||
},
|
||||
{
|
||||
"op": "openTcpClient",
|
||||
"node": "00000000-0000-0000-0000-000000000103",
|
||||
"target": "192.168.0.99",
|
||||
"port": 80,
|
||||
"localPort": 5000
|
||||
},
|
||||
{
|
||||
"op": "connectTcp",
|
||||
"socket": "00000000-0000-0000-0000-000000000005"
|
||||
},
|
||||
{
|
||||
"op": "closeSocket",
|
||||
"socket": "00000000-0000-0000-0000-000000000001"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user