diff --git a/net/dcsctp/socket/dcsctp_socket.cc b/net/dcsctp/socket/dcsctp_socket.cc index cc9a71eae8..4f445fb6f8 100644 --- a/net/dcsctp/socket/dcsctp_socket.cc +++ b/net/dcsctp/socket/dcsctp_socket.cc @@ -1305,9 +1305,6 @@ bool DcSctpSocket::HandleCookieEchoWithTCB(const CommonHeader& header, RTC_DLOG(LS_VERBOSE) << log_prefix() << "Received COOKIE-ECHO indicating a restarted peer"; - // If a message was partly sent, and the peer restarted, resend it in - // full by resetting the send queue. - send_queue_.Reset(); tcb_ = nullptr; callbacks_.OnConnectionRestarted(); } else if (header.verification_tag == tcb_->my_verification_tag() && diff --git a/net/dcsctp/socket/dcsctp_socket_test.cc b/net/dcsctp/socket/dcsctp_socket_test.cc index 914bea34c4..4c03acab45 100644 --- a/net/dcsctp/socket/dcsctp_socket_test.cc +++ b/net/dcsctp/socket/dcsctp_socket_test.cc @@ -2341,6 +2341,32 @@ TEST(DcSctpSocketTest, CloseStreamsWithPendingRequest) { absl::optional msg6 = z.cb.ConsumeReceivedMessage(); ASSERT_TRUE(msg6.has_value()); EXPECT_EQ(msg6->stream_id(), StreamID(3)); -} // namespace +} + +TEST(DcSctpSocketTest, ReconnectSocketWithPendingStreamReset) { + // This is an issue found by fuzzing, and doesn't really make sense in WebRTC + // data channels as a SCTP connection is never ever closed and then + // reconnected. SCTP connections are closed when the peer connection is + // deleted, and then it doesn't do more with SCTP. + SocketUnderTest a("A"); + SocketUnderTest z("Z"); + + ConnectSockets(a, z); + + a.socket.ResetStreams(std::vector({StreamID(1)})); + + // EXPECT_CALL(a.cb, OnAborted).Times(1); + EXPECT_CALL(z.cb, OnAborted).Times(1); + a.socket.Close(); + + EXPECT_EQ(a.socket.state(), SocketState::kClosed); + + EXPECT_CALL(a.cb, OnConnected).Times(1); + EXPECT_CALL(z.cb, OnConnected).Times(1); + a.socket.Connect(); + ExchangeMessages(a, z); + a.socket.ResetStreams(std::vector({StreamID(2)})); +} + } // namespace } // namespace dcsctp diff --git a/net/dcsctp/socket/transmission_control_block.h b/net/dcsctp/socket/transmission_control_block.h index 8c240f1043..0971c67317 100644 --- a/net/dcsctp/socket/transmission_control_block.h +++ b/net/dcsctp/socket/transmission_control_block.h @@ -118,7 +118,14 @@ class TransmissionControlBlock : public Context { &reassembly_queue_, &retransmission_queue_, handover_state), - heartbeat_handler_(log_prefix, options, this, &timer_manager_) {} + heartbeat_handler_(log_prefix, options, this, &timer_manager_) { + // If the connection is re-established (peer restarted, but re-used old + // connection), make sure that all message identifiers are reset and any + // partly sent message is re-sent in full. The same is true when the socket + // is closed and later re-opened, which never happens in WebRTC, but is a + // valid operation on the SCTP level. + send_queue.Reset(); + } // Implementation of `Context`. bool is_connection_established() const override {