diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc index 17d224f982..5e5ba0156e 100644 --- a/webrtc/p2p/base/p2ptransportchannel.cc +++ b/webrtc/p2p/base/p2ptransportchannel.cc @@ -1112,9 +1112,11 @@ void P2PTransportChannel::HandleNotWritable() { } } +// If all connections timed out, delete them all. void P2PTransportChannel::HandleAllTimedOut() { - // Currently we are treating this as channel not writable. - HandleNotWritable(); + for (Connection* connection : connections_) { + connection->Destroy(); + } } bool P2PTransportChannel::weak() const { diff --git a/webrtc/p2p/base/p2ptransportchannel.h b/webrtc/p2p/base/p2ptransportchannel.h index e49fc27323..9efb96c42d 100644 --- a/webrtc/p2p/base/p2ptransportchannel.h +++ b/webrtc/p2p/base/p2ptransportchannel.h @@ -158,6 +158,9 @@ class P2PTransportChannel : public TransportChannelImpl, // Public for unit tests. Connection* FindNextPingableConnection(); + // Public for unit tests. + const std::vector& connections() const { return connections_; } + private: rtc::Thread* thread() { return worker_thread_; } PortAllocatorSession* allocator_session() { diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc index 86f4ec3852..37cda7c661 100644 --- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc +++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc @@ -2159,3 +2159,34 @@ TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) { EXPECT_TRUE_WAIT(!conn2->active(), 1000); EXPECT_EQ(cricket::TransportChannelState::STATE_COMPLETED, ch.GetState()); } + +// Test that if all connections in a channel has timed out on writing, they +// will all be deleted. We use Prune to simulate write_time_out. +TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) { + cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr); + cricket::P2PTransportChannel ch("test channel", 1, nullptr, &pa); + PrepareChannel(&ch); + ch.Connect(); + ch.MaybeStartGathering(); + // Have one connection only but later becomes write-time-out. + ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 100)); + cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); + ASSERT_TRUE(conn1 != nullptr); + conn1->ReceivedPing(); // Becomes receiving + conn1->Prune(); + EXPECT_TRUE_WAIT(ch.connections().empty(), 1000); + + // Have two connections but both become write-time-out later. + ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 1)); + cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); + ASSERT_TRUE(conn2 != nullptr); + conn2->ReceivedPing(); // Becomes receiving + ch.AddRemoteCandidate(CreateCandidate("3.3.3.3", 3, 2)); + cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3); + ASSERT_TRUE(conn3 != nullptr); + conn3->ReceivedPing(); // Becomes receiving + // Now prune both conn2 and conn3; they will be deleted soon. + conn2->Prune(); + conn3->Prune(); + EXPECT_TRUE_WAIT(ch.connections().empty(), 1000); +}