QuicChromiumPacketWriter::write_blocked_ is not set correctly with connection migration |
||
Issue descriptionQuicChromiumPacketWriter currently keeps a boolean |write_blocked_| to indicate whether a write is currently in flight. It is set to true when a) Socket::Write() returns ERR_IO_PENDING indicate the previous packet write is asynchronous. ref: QuicChromiumPacketWriter::WritePacketToSocketImpl() b) A retry after write error is in progress. ref: QuicChromiumPacketWriter::MaybeRetryAfterWriteError() c) QuicChromiumPacketWrite::set_write_blocked(true) is invoked c.1) when connection migration has no new network connected ref: QuicChromiumClientSession::OnNoNewNetwork() c.2) connection migration is wrapping up and migrates to an alternate socket. ref:QuicChromiumClientSession::MigrateToSocket() It is set to false when i) an asynchronous write is completed. ref: QuicChromiumPacketWriter::OnWriteComplete ii) QuicChromiumPacketWriter::set_write_blocked(false) is invoked when connection migration manages to migrate to the alternate socket and is about to write to the "new" socket. iii) QuicChromiumPacketWriter::SetWritable() is invoked, which is mostly used in non-chromium code. a) and b) indicate that the write is blocked on the socket level. c.1 and c.2 indicate that the write is blocked on the network level. i) indicates that write is unblocked on the socket level ii) indicates that write is unblocked at the network level. There would be no issue if connection migration is not turned on since network level block is introduced in connection migration. Current code doesn't differentiate the two different causes, which will cause a write being unblocked incorrectly, in particular, we want to unblock the network level by the time calling set_write_blocked(false), while the write was blocked on the socket level previously. A more concrete example is laid as follows: connection migration is on - connection detects path degrading, or session attempts to migrate back to the default network - a new socket is created to probe the alternate network - first connectivity probe is sent ... alarm fires.... - second connectivity probe is sent, asynchronous write returns ERR_IO_PENDING, set the probing write blocked (at socket level) - response to first connectivity probe is received - connection migration proceeds by MigrateToSocket, set the writer blocked (at network level) - connection migration wraps up by WriteToNewSocket, set the writer unblocked (at network level) - A new write comes in, found the writer unblocked, may attempt to write to the blocked writer, which blows up.
,
Jul 10
,
Jul 11
Fix in #1 landed in 69.0.3488.0. |
||
►
Sign in to add a comment |
||
Comment 1 by bugdroid1@chromium.org
, Jul 10