aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/dcsctp/socket/dcsctp_socket.cc2
-rw-r--r--net/dcsctp/socket/dcsctp_socket_test.cc40
2 files changed, 42 insertions, 0 deletions
diff --git a/net/dcsctp/socket/dcsctp_socket.cc b/net/dcsctp/socket/dcsctp_socket.cc
index dd54317718..622f6ecfcf 100644
--- a/net/dcsctp/socket/dcsctp_socket.cc
+++ b/net/dcsctp/socket/dcsctp_socket.cc
@@ -280,6 +280,8 @@ void DcSctpSocket::Shutdown() {
// endpoint enters the SHUTDOWN-PENDING state and remains there until all
// outstanding data has been acknowledged by its peer."
SetState(State::kShutdownPending, "Shutdown called");
+ t1_init_->Stop();
+ t1_cookie_->Stop();
MaybeSendShutdownOrAck();
} else {
// Connection closed before even starting to connect, or during the initial
diff --git a/net/dcsctp/socket/dcsctp_socket_test.cc b/net/dcsctp/socket/dcsctp_socket_test.cc
index 2b2e9880f1..a9eec60083 100644
--- a/net/dcsctp/socket/dcsctp_socket_test.cc
+++ b/net/dcsctp/socket/dcsctp_socket_test.cc
@@ -282,6 +282,46 @@ TEST_F(DcSctpSocketTest, EstablishConnectionWithSetupCollision) {
EXPECT_EQ(sock_z_.state(), SocketState::kConnected);
}
+TEST_F(DcSctpSocketTest, ShuttingDownWhileEstablishingConnection) {
+ EXPECT_CALL(cb_a_, OnConnected).Times(0);
+ EXPECT_CALL(cb_z_, OnConnected).Times(1);
+ sock_a_.Connect();
+
+ // Z reads INIT, produces INIT_ACK
+ sock_z_.ReceivePacket(cb_a_.ConsumeSentPacket());
+ // A reads INIT_ACK, produces COOKIE_ECHO
+ sock_a_.ReceivePacket(cb_z_.ConsumeSentPacket());
+ // Z reads COOKIE_ECHO, produces COOKIE_ACK
+ sock_z_.ReceivePacket(cb_a_.ConsumeSentPacket());
+ // Drop COOKIE_ACK, just to more easily verify shutdown protocol.
+ cb_z_.ConsumeSentPacket();
+
+ // As Socket A has received INIT_ACK, it has a TCB and is connected, while
+ // Socket Z needs to receive COOKIE_ECHO to get there. Socket A still has
+ // timers running at this point.
+ EXPECT_EQ(sock_a_.state(), SocketState::kConnecting);
+ EXPECT_EQ(sock_z_.state(), SocketState::kConnected);
+
+ // Socket A is now shut down, which should make it stop those timers.
+ sock_a_.Shutdown();
+
+ EXPECT_CALL(cb_a_, OnClosed).Times(1);
+ EXPECT_CALL(cb_z_, OnClosed).Times(1);
+
+ // Z reads SHUTDOWN, produces SHUTDOWN_ACK
+ sock_z_.ReceivePacket(cb_a_.ConsumeSentPacket());
+ // A reads SHUTDOWN_ACK, produces SHUTDOWN_COMPLETE
+ sock_a_.ReceivePacket(cb_z_.ConsumeSentPacket());
+ // Z reads SHUTDOWN_COMPLETE.
+ sock_z_.ReceivePacket(cb_a_.ConsumeSentPacket());
+
+ EXPECT_TRUE(cb_a_.ConsumeSentPacket().empty());
+ EXPECT_TRUE(cb_z_.ConsumeSentPacket().empty());
+
+ EXPECT_EQ(sock_a_.state(), SocketState::kClosed);
+ EXPECT_EQ(sock_z_.state(), SocketState::kClosed);
+}
+
TEST_F(DcSctpSocketTest, EstablishSimultaneousConnection) {
EXPECT_CALL(cb_a_, OnConnected).Times(1);
EXPECT_CALL(cb_z_, OnConnected).Times(1);