Fix QUIC proxy Fast Open DCHECK
QUIC Fast Open can complete Connect() while response headers are still pending, leaving connect_callback_ null. If that pending header path later fails, OnIOComplete() re-entered the connect completion path and hit the debug DCHECK. Handle post-Connect Fast Open completions by routing failures to the pending read callback when present, or leaving the socket disconnected without a second Connect callback. This preserves successful Fast Open behavior while making header/response-code failure paths obey the socket state machine.pull/808/head
parent
d9d09c9cc5
commit
3dd80b3032
|
|
@ -281,9 +281,19 @@ void QuicProxyClientSocket::OnIOComplete(int result) {
|
|||
DCHECK_NE(STATE_DISCONNECTED, next_state_);
|
||||
int rv = DoLoop(result);
|
||||
if (rv != ERR_IO_PENDING) {
|
||||
// Connect() finished (successfully or unsuccessfully).
|
||||
DCHECK(!connect_callback_.is_null());
|
||||
std::move(connect_callback_).Run(rv);
|
||||
if (!connect_callback_.is_null()) {
|
||||
// Connect() finished (successfully or unsuccessfully).
|
||||
std::move(connect_callback_).Run(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(use_fastopen_);
|
||||
read_headers_pending_ = false;
|
||||
next_state_ = STATE_DISCONNECTED;
|
||||
if (!read_callback_.is_null()) {
|
||||
read_buf_ = nullptr;
|
||||
std::move(read_callback_).Run(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -340,12 +350,17 @@ int QuicProxyClientSocket::DoLoop(int last_io_result) {
|
|||
if (use_fastopen_ && read_headers_pending_) {
|
||||
read_headers_pending_ = false;
|
||||
if (rv < 0) {
|
||||
// read_callback_ will be called with this error and be reset.
|
||||
// Further data after that will be ignored.
|
||||
// If a Read() is pending, OnIOComplete() will report this error to
|
||||
// that callback. Otherwise keep the completed Connect() quiet and
|
||||
// leave the socket disconnected for any future operations.
|
||||
next_state_ = STATE_DISCONNECTED;
|
||||
if (read_callback_.is_null())
|
||||
rv = ERR_IO_PENDING;
|
||||
} else {
|
||||
// Prevents calling connect_callback_ after Fast Open Connect()
|
||||
// already completed synchronously.
|
||||
rv = ERR_IO_PENDING;
|
||||
}
|
||||
// Prevents calling connect_callback_.
|
||||
rv = ERR_IO_PENDING;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Reference in New Issue