diff --git a/net/dcsctp/socket/dcsctp_socket.cc b/net/dcsctp/socket/dcsctp_socket.cc index 5f8312d4bd..822040ef5b 100644 --- a/net/dcsctp/socket/dcsctp_socket.cc +++ b/net/dcsctp/socket/dcsctp_socket.cc @@ -1316,9 +1316,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 cc5566f9ae..82fbb1b90b 100644 --- a/net/dcsctp/socket/dcsctp_socket_test.cc +++ b/net/dcsctp/socket/dcsctp_socket_test.cc @@ -2379,5 +2379,29 @@ TEST_P(DcSctpSocketParametrizedTest, WillHandoverPriority) { EXPECT_EQ(a->socket.GetStreamPriority(StreamID(1)), StreamPriority(43)); EXPECT_EQ(a->socket.GetStreamPriority(StreamID(2)), StreamPriority(43)); } + +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(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..41a79eada5 100644 --- a/net/dcsctp/socket/transmission_control_block.h +++ b/net/dcsctp/socket/transmission_control_block.h @@ -118,7 +118,17 @@ 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. Note that in case of handover, the + // send queue is already re-configured, and shouldn't be reset. + if (handover_state == nullptr) { + send_queue.Reset(); + } + } // Implementation of `Context`. bool is_connection_established() const override {