Chapter 15 real isolated Linux TCP evidence, 2026-09-20 Run: sudo python3 lab.py inside an owned Linux VM. Stdout is JSON Lines. Only two fresh network namespaces and their veth interfaces are used per case; no physical interface, host default route or production endpoint is changed. Application: eight 8-byte writes, payload 0000000; through 0000007; (64 bytes). Client enables TCP_NODELAY, sends, then shutdown(SHUT_WR). Server reads until EOF with recv(3), verifies all bytes, echoes 64 bytes, then shutdown(SHUT_WR). Client reads echo with recv(7) until EOF and verifies all bytes. Socket timeout 5 seconds, read loop100 iterations, capture cap256 frames and one-second drain. These are bounded test guards, not protocol timeout or performance claims. Capture is AF_PACKET on receiving namespace B/eth0, bound before listen/accept. Both incoming client and outgoing server frames are retained as raw hex. Decoded rows point back through frame_index. Only this IPv4 pair and TCP port 46015 are included; IHL/TCP header/IP total lengths and ports are explicit. Fragmented IPv4 is rejected. Untagged Ethernet/IPv4/TCP only; no IPv6, VLAN, IP fragment reassembly or checksum validation. Raw capture is not a PCAP file. SACK-permitted and SACK blocks are distinct fields. Relative values subtract the separate directional SYN ISNs modulo 2^32; ACK/SACK subtract peer ISN. Final baseline run: net15-4adfeb08, A ISN3926289439, B ISN510217489. B sees client data relative SEQ1,9,17,25,33,41,49,57, eight bytes each. Both directions transfer64 bytes. FIN sequence position65, cumulative ACK66. No SACK block is observed in this baseline. Final netem run: net15-da58fb8b, A ISN952091099, B ISN2818598428. Only A's owned eth0 egress has netem limit100 delay100ms reorder100% gap2. B observes client data relative SEQ9,1,17,25. A receiver ACK has relative ACK1 and actual SACK [9,17). The segment beginning25 contains40 payload bytes and FIN; FIN therefore occupies position65, not the segment's starting SEQ25. Both byte streams match all64 application bytes, and ACK66 is captured. The decoded data interval order and SACK hole corroborate out-of-order receipt. A decreasing SEQ alone could also indicate retransmission and is not sufficient proof. No sender-outbound pre-qdisc capture is used to infer arrival order. The first complete run already passed ordinary TCP and observed SACK, but lacked port/header-length fields. After adding those decoding boundaries, both cases were rerun. Same Linux6.18.10-200.fc43.aarch64, Python3.14.3, iproute2 6.14.0; new namespace names, ISNs, ports and packet grouping differ naturally. First netem SACK was [17,25) with ACK9; final evidence is [9,17) with ACK1. run.jsonl contains only the final complete successful run, never merged runs. No assumption that writes, IP packets and recv calls share message boundaries. Every case deletes only its owned namespaces in finally and records cleanup. The enclosing shell stopped the Podman VM after success (exit0). No packages were installed. --help exit0, --bad exit2, macOS lab invocation exits1 before network changes. Python no-excuse checker zero violations. This proves this short isolated kernel-TCP transfer and observed sequence/SACK relationships. It does not establish public/production end-to-end delivery, NIC timing, offload behavior, congestion recovery choice or general performance. No claim is made that netem gap order or packet grouping repeats identically. Final trace review: netem decoded frame_index17 is a real B->A RST (flags4). The preceding two decoded packets are A ACK66 then A ACK65. The full trace therefore includes an extra RST after the captured FIN/ACK exchange; it must not be described as exclusively normal FIN termination. A late ACK reaching an already closed endpoint is compatible with this observation, but no kernel socket-state tracing was collected, so that is not an established unique cause. The raw frame is retained. The byte/sequence checks and application results remain as recorded; no experiment was changed or rerun to remove this evidence.