dcsctp: Send buffered data directly on response

When a stream reset response has been received, this may result
in unpausing the streams (either because it was successful or
because it failed - but streams will be unpaused). Directly after
receiving the response, send out any pending chunks that are
ready to be sent.

Before this CL, they would eventually be sent out, but that is
unnecessary and undeterministic.

Bug: webrtc:14277
Change-Id: Ic1ab38bc3cea96cfec7419e25001f12807523a3a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/273800
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38009}
This commit is contained in:
Victor Boivie
2022-09-01 13:00:28 +00:00
committed by WebRTC LUCI CQ
parent 1e6965a857
commit dd1eb2e1ec
2 changed files with 38 additions and 0 deletions

View File

@ -1541,6 +1541,7 @@ void DcSctpSocket::HandleError(const CommonHeader& header,
void DcSctpSocket::HandleReconfig(
const CommonHeader& header,
const SctpPacket::ChunkDescriptor& descriptor) {
TimeMs now = callbacks_.TimeMillis();
absl::optional<ReConfigChunk> chunk = ReConfigChunk::Parse(descriptor.data);
if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
tcb_->stream_reset_handler().HandleReConfig(*std::move(chunk));
@ -1549,6 +1550,9 @@ void DcSctpSocket::HandleReconfig(
// that were waiting for this request to finish, continue resetting them.
MaybeSendResetStreamsRequest();
}
// If a response was processed, pending to-be-reset streams may now have
// become unpaused. Try to send more DATA chunks.
tcb_->SendBufferedPackets(now);
}
void DcSctpSocket::HandleShutdown(

View File

@ -2815,5 +2815,39 @@ TEST(DcSctpSocketTest, ResetStreamsDeferred) {
EXPECT_EQ(msg3->payload().size(), kSmallMessageSize);
}
TEST(DcSctpSocketTest, ResetStreamsWithPausedSenderResumesWhenPerformed) {
SocketUnderTest a("A");
SocketUnderTest z("Z");
ConnectSockets(a, z);
a.socket.Send(DcSctpMessage(StreamID(1), PPID(51),
std::vector<uint8_t>(kSmallMessageSize)),
{});
a.socket.ResetStreams(std::vector<StreamID>({StreamID(1)}));
// Will be queued, as the stream has an outstanding reset operation.
a.socket.Send(DcSctpMessage(StreamID(1), PPID(52),
std::vector<uint8_t>(kSmallMessageSize)),
{});
EXPECT_CALL(a.cb, OnStreamsResetPerformed(ElementsAre(StreamID(1))));
EXPECT_CALL(z.cb, OnIncomingStreamsReset(ElementsAre(StreamID(1))));
ExchangeMessages(a, z);
absl::optional<DcSctpMessage> msg1 = z.cb.ConsumeReceivedMessage();
ASSERT_TRUE(msg1.has_value());
EXPECT_EQ(msg1->stream_id(), StreamID(1));
EXPECT_EQ(msg1->ppid(), PPID(51));
EXPECT_EQ(msg1->payload().size(), kSmallMessageSize);
absl::optional<DcSctpMessage> msg2 = z.cb.ConsumeReceivedMessage();
ASSERT_TRUE(msg2.has_value());
EXPECT_EQ(msg2->stream_id(), StreamID(1));
EXPECT_EQ(msg2->ppid(), PPID(52));
EXPECT_EQ(msg2->payload().size(), kSmallMessageSize);
}
} // namespace
} // namespace dcsctp