private-octopus / picoquic

Minimal implementation of the QUIC protocol
MIT License
547 stars 161 forks source link

Malformed packets sent during interop L1 test #1521

Closed huitema closed 1 year ago

huitema commented 1 year ago

The interop L1 test consists of 50 connection attempts using hq-interop, which succeed if a 1024 bytes file is successfully received despite 30% packet loss. We see failures caused by malformed packets, such as

1- Test with happroxy. Ping, followed by a hallucinated stream frame (no reason to send anything on stream 15), occurs twice, see text log:

a8c72861ce43fd60: T= 1.619638, cwin: 15360,flight: 920,nb_ret: 4,rtt_min: 0,rtt: 250000,rtt_var: 0,max_ack_delay: 0,state: 14
a8c72861ce43fd60: Sending packet type: 6 (1rtt protected), S1, Q1,
a8c72861ce43fd60:     <e29097573939c979>, Seq: 2 (2), Phi: 0,
a8c72861ce43fd60:     Prepared 285 bytes
a8c72861ce43fd60:     ping, 2 bytes
a8c72861ce43fd60:     padding, 1 bytes
a8c72861ce43fd60:     Stream 12590, offset 0, length 279, fin = 0: 5b7d1ec96bc37875...
...
a744459868ecb635: Sending packet type: 6 (1rtt protected), S1, Q1,
a744459868ecb635:     <b79ab6085e7a2cf6>, Seq: 2 (2), Phi: 0,
a744459868ecb635:     Prepared 285 bytes
a744459868ecb635:     ping, 2 bytes
a744459868ecb635:     padding, 1 bytes
a744459868ecb635:     Stream 15, offset 0, length 280, fin = 0: b4d904c321bfebdb...

2- Test with ngtcp2. Ping, followed by a hallucinated stream frame, see text log:

331dd973f3b6558c: T= 0.375010, cwin: 15360,flight: 1009,nb_ret: 1,rtt_min: 0,rtt: 250000,rtt_var: 0,max_ack_delay: 0,state: 14
331dd973f3b6558c: Sending packet type: 6 (1rtt protected), S1, Q0,
331dd973f3b6558c:     <7e44dcfad4cd703e1cf7d1c0f03f70eac1a1>, Seq: 3 (3), Phi: 0,
331dd973f3b6558c:     Prepared 275 bytes
331dd973f3b6558c:     ping, 2 bytes
331dd973f3b6558c:     padding, 1 bytes
331dd973f3b6558c:     Stream 41, offset 0, length 270, fin = 0: ca140b9421e2c55f...

3- Test with s2n-quic. Two occurrences of Ping, followed by hallucinated frames, see text log:

56f2473e4b895d32: T= 0.692622, cwin: 16975,flight: 238,nb_ret: 4,rtt_min: 35893,rtt: 43629,rtt_var: 24478,max_ack_delay: 0,state: 14
56f2473e4b895d32: Sending packet type: 6 (1rtt protected), S1, Q1,
56f2473e4b895d32:     <55efe3c2d24c2efd548b4c3621139f73>, Seq: 4 (4), Phi: 0,
56f2473e4b895d32:     Prepared 149 bytes
56f2473e4b895d32:     ping, 2 bytes
56f2473e4b895d32:     padding, 1 bytes
56f2473e4b895d32:     Stream 2891023286785438310, offset 0, length 137, fin = 0: aae62c447b0b3261...

In all cases, the packets are sent while previously sent packets are not acknowledged.

huitema commented 1 year ago

In the first failure case, the "bad" packet has the same length as a previous 1RTT packet:

a8c72861ce43fd60: Sending packet type: 6 (1rtt protected), S0, Q1,
a8c72861ce43fd60:     <e29097573939c979>, Seq: 1 (1), Phi: 0,
a8c72861ce43fd60:     Prepared 285 bytes
a8c72861ce43fd60:     NEW CONNECTION ID[1]: 0x712e5b7d1ec96bc3, 787546ab64b34aed1a6efbcffcc61995
a8c72861ce43fd60:     NEW CONNECTION ID[2]: 0x7d5596bae23ade86, 2025f74d032f97497b474c12bf7b9023
a8c72861ce43fd60:     NEW CONNECTION ID[3]: 0x5759aabf550e9abb, 55aa89f334fd6375f0701038edfeadfd
a8c72861ce43fd60:     NEW CONNECTION ID[4]: 0x91fe1c00c5241ff3, aa785e54ea55d1493a1bf86dbe7b7134
a8c72861ce43fd60:     NEW CONNECTION ID[5]: 0x85fc6cd014c8e40b, 2e60f6753a9caf90dba309060b7ec150
a8c72861ce43fd60:     NEW CONNECTION ID[6]: 0xe377aede7558ab2f, c24086f4966c0c92375bf28575b25ebe
a8c72861ce43fd60:     NEW CONNECTION ID[7]: 0x2ebbcd8014461adc, 3628e673e04ed99dbe3d9b6c35942515
a8c72861ce43fd60:     padding, 89 bytes

The first content bytes of that packet would be 0x18010008712e5b7d1ec96bc3. If the first byte is replaced by "01", ping, this becomes 0x01010008712e5b7d1ec96bc3, which decodes as:

This much suggests that the packet was repeated, and that the first byte was overwritten by a "ping" byte.

The other two cases show the same pattern.

huitema commented 1 year ago

Verified fixed after PR #1524

The issue was caused by improper integration of "preemptive repeat" in the sender flow.