mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-08 09:42:06 +03:00
No-op StopSending If Ingress Closed
Summary: - as title, we should just no-op ::StopSending when ingress is already closed Reviewed By: jbeshay, mjoras Differential Revision: D40990383 fbshipit-source-id: e0cd64facf78f510eabe8198e93a643c6ebfb89e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
79cf450bbf
commit
e1f8e0df1d
@@ -806,6 +806,13 @@ folly::Expected<folly::Unit, LocalErrorCode> QuicTransportBase::stopSending(
|
||||
if (!conn_->streamManager->streamExists(id)) {
|
||||
return folly::makeUnexpected(LocalErrorCode::STREAM_NOT_EXISTS);
|
||||
}
|
||||
auto* stream = CHECK_NOTNULL(conn_->streamManager->getStream(id));
|
||||
if (stream->recvState == StreamRecvState::Closed) {
|
||||
// skip STOP_SENDING if ingress is already closed
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
// send STOP_SENDING frame to peer
|
||||
sendSimpleFrame(*conn_, StopSendingFrame(id, error));
|
||||
updateWriteLooper(true);
|
||||
return folly::unit;
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <quic/state/DatagramHandlers.h>
|
||||
#include <quic/state/QuicStreamFunctions.h>
|
||||
#include <quic/state/QuicStreamUtilities.h>
|
||||
#include <quic/state/stream/StreamReceiveHandlers.h>
|
||||
#include <quic/state/test/Mocks.h>
|
||||
|
||||
#include <folly/io/async/test/MockAsyncUDPSocket.h>
|
||||
@@ -666,6 +667,49 @@ TEST_P(QuicTransportImplTestBase, IdleTimeoutStreamMaessage) {
|
||||
transport->invokeIdleTimeout();
|
||||
}
|
||||
|
||||
TEST_P(QuicTransportImplTestBase, StopSendingClosesIngress) {
|
||||
// create bidi stream
|
||||
auto streamID = transport->createBidirectionalStream().value();
|
||||
auto* stream = CHECK_NOTNULL(transport->getStream(streamID));
|
||||
|
||||
EXPECT_EQ(stream->sendState, StreamSendState::Open);
|
||||
EXPECT_EQ(stream->recvState, StreamRecvState::Open);
|
||||
|
||||
// suppose we rx a reset from peer which closes our ingress SM
|
||||
receiveRstStreamSMHandler(
|
||||
*stream,
|
||||
RstStreamFrame(stream->id, GenericApplicationErrorCode::NO_ERROR, 0));
|
||||
EXPECT_EQ(stream->sendState, StreamSendState::Open);
|
||||
EXPECT_EQ(stream->recvState, StreamRecvState::Closed);
|
||||
|
||||
// send stop sending to peer should no-op
|
||||
transport->stopSending(streamID, GenericApplicationErrorCode::NO_ERROR);
|
||||
EXPECT_EQ(transport->transportConn->pendingEvents.frames.size(), 0);
|
||||
|
||||
// now test ingress uni-directional stream
|
||||
auto& streamManager = *transport->transportConn->streamManager;
|
||||
auto nextPeerUniStream =
|
||||
streamManager.nextAcceptablePeerUnidirectionalStreamId();
|
||||
EXPECT_TRUE(nextPeerUniStream.has_value());
|
||||
stream = streamManager.getStream(*nextPeerUniStream);
|
||||
EXPECT_EQ(stream->sendState, StreamSendState::Invalid);
|
||||
EXPECT_EQ(stream->recvState, StreamRecvState::Open);
|
||||
|
||||
// suppose we rx a reset from peer which closes our ingress SM
|
||||
receiveRstStreamSMHandler(
|
||||
*stream,
|
||||
RstStreamFrame(stream->id, GenericApplicationErrorCode::NO_ERROR, 0));
|
||||
EXPECT_EQ(stream->sendState, StreamSendState::Invalid);
|
||||
EXPECT_EQ(stream->recvState, StreamRecvState::Closed);
|
||||
EXPECT_TRUE(stream->inTerminalStates());
|
||||
|
||||
// send stop sending to peer should no-op
|
||||
transport->stopSending(stream->id, GenericApplicationErrorCode::NO_ERROR);
|
||||
EXPECT_EQ(transport->transportConn->pendingEvents.frames.size(), 0);
|
||||
|
||||
transport.reset();
|
||||
}
|
||||
|
||||
TEST_P(QuicTransportImplTestBase, WriteAckPacketUnsetsLooper) {
|
||||
// start looper in running state first
|
||||
transport->writeLooper()->run(true);
|
||||
|
Reference in New Issue
Block a user