Hi Fan,
I am sorry for delay. I will try to describe an example which we can reliably reproduce in our test framework.
Imagine you have a quic client which tries to do a POST or PUT request.
1) Client sends 3 packets with handshake which are received by server.
2) Client sends 4th packet with last crypto frame (handhake confirmation). This packet is the last from hanshake packet number space and is lost.
3) Client beleives it confirmed handshake and starts sending data with forward secure encryption.
4) Server misses 4th packet from the client with handshake confirmation and gets 5th packet with data but cannot decrypt them because even if server has keys, it is not allowed to use them until the confirmation, so server buffers them for later decryption.
5) Client didn't get ack to 4th packet, so PTO fires. But because client does PUT/POST, he usualy has much data to send, so client prefers new data sending with skipped packet number to provoke ack response.
6) Server gets new data, buffers them. Unfortunetelly, I don't remember if server sends any ack or not.
7) Client doesn't know it should retransmit the last packet from handskake space and sends new data again.
8) If client has enough data to send, it might deplete server buffer space.
9) Connection end due to an error or handshake timeout.
The patch I provided solves the situation. It prefers retransmit in case handshake is not confirmed, otherwise it uses the optimization. Maybe it could be solved somewhere else, don't know, I am not so skilled in quiche source as you surely are.
I briefly looked at SendStreamData and it might solve the situation (not sure) but it is conditioned to server only.
Note: We currently work with sources at 7f718d04e3 (quiche repository).
Hope it helps.
Petr