When running high-throughput TCP tests with iperf3 on Windows against my libkrun VM I noticed that the result host -> guest were not that good (150Mbps). By digging into it, i found out that gvproxy frequently trasmits duplicate TCP frames within microseconds one another.
An example
15:41:32.691401 IP 192.168.127.1.19246 > 192.168.127.2.5202: Flags [P.], seq 129405470:129405578, ack 1, win 4096, options [nop,nop,TS val 3177150739 ecr 3838743611], length 108
15:41:32.691403 IP 192.168.127.1.19246 > 192.168.127.2.5202: Flags [.], seq 129405578:129412678, ack 1, win 4096, options [nop,nop,TS val 3177150739 ecr 3838743611], length 7100
15:41:32.691403 IP 192.168.127.1.19246 > 192.168.127.2.5202: Flags [P.], seq 129405470:129405578, ack 1, win 4096, options [nop,nop,TS val 3177150739 ecr 3838743611], length 108This duplication is weird because i would expect to see a duplicate packet after a bit more time. It's impossible that the sender RTO is just 2 microseconds. This causes the receiver to generate SACKs/DSACKs in response, and the sender to update its congestion window and reducing the throughput.
Steps to Reproduce:
- Launch a libkrun VM on Windows with gvproxy over a unix socket.
- Run
iperf3 -s -p <port>inside the VM. - Run
iperf3 -c <target_ip> -p <port> -t 10from the client. - Capture traffic with tcpdump on the interface and inspect for sub-millisecond duplicate sequence numbers and SACK blocks.
I am not sure this is from gvproxy or some other part of the stack. I'm opening this issue so i don't forget. Even if the result is not that good it's still 7x better than what we have with hvsock/hyperv. So i guess we always faced it but nobody complained/investigated.
In fact gvisor-tap-vsock will convert 1 TCP connection into 2 TCP connections, one between the remote machine and the host, one between gVisor's TCP stack and the guest, so it's possible to observe very small RTTs.