Fixing leaked reference from SCTP transport to DTLS/ICE transport.

This was causing ICE pings to continue going out on PeerConnections
that use DataChannels, even after closing the PeerConnection.

This CL adds a two-line fix, and an integration test that will catch
this and similar issues.

Bug: webrtc:7655
Change-Id: I589a2a1aaf6433c1d65be69a1267e1b52a33534b
Reviewed-on: https://webrtc-review.googlesource.com/37145
Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21488}
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index ee1cffe..1d96a7f 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -5102,6 +5102,8 @@
 void PeerConnection::DestroySctpTransport_n() {
   RTC_DCHECK(network_thread()->IsCurrent());
   sctp_transport_.reset(nullptr);
+  transport_controller_->DestroyDtlsTransport_n(
+      *sctp_transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP);
   sctp_content_name_.reset();
   sctp_transport_name_.reset();
   sctp_invoker_.reset(nullptr);
diff --git a/pc/peerconnection_integrationtest.cc b/pc/peerconnection_integrationtest.cc
index abad10f..0bc68a2 100644
--- a/pc/peerconnection_integrationtest.cc
+++ b/pc/peerconnection_integrationtest.cc
@@ -3659,6 +3659,31 @@
                                   kMaxWaitForFramesMs);
 }
 
+// Test that after closing PeerConnections, they stop sending any packets (ICE,
+// DTLS, RTP...).
+TEST_F(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
+  // Set up audio/video/data, wait for some frames to be received.
+  ASSERT_TRUE(CreatePeerConnectionWrappers());
+  ConnectFakeSignaling();
+  caller()->AddAudioVideoMediaStream();
+#ifdef HAVE_SCTP
+  caller()->CreateDataChannel();
+#endif
+  caller()->CreateAndSetAndSignalOffer();
+  ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
+  ExpectNewFramesReceivedWithWait(0, 0, kDefaultExpectedAudioFrameCount,
+                                  kDefaultExpectedAudioFrameCount,
+                                  kMaxWaitForFramesMs);
+  // Close PeerConnections.
+  caller()->pc()->Close();
+  callee()->pc()->Close();
+  // Pump messages for a second, and ensure no new packets end up sent.
+  uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
+  WAIT(false, 1000);
+  uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
+  EXPECT_EQ(sent_packets_a, sent_packets_b);
+}
+
 }  // namespace
 
 #endif  // if !defined(THREAD_SANITIZER)
diff --git a/rtc_base/virtualsocketserver.cc b/rtc_base/virtualsocketserver.cc
index d461bf1..d8771e7 100644
--- a/rtc_base/virtualsocketserver.cc
+++ b/rtc_base/virtualsocketserver.cc
@@ -834,6 +834,7 @@
 int VirtualSocketServer::SendUdp(VirtualSocket* socket,
                                  const char* data, size_t data_size,
                                  const SocketAddress& remote_addr) {
+  ++sent_packets_;
   if (sending_blocked_) {
     CritScope cs(&socket->crit_);
     socket->ready_to_send_ = false;
@@ -897,6 +898,7 @@
 }
 
 void VirtualSocketServer::SendTcp(VirtualSocket* socket) {
+  ++sent_packets_;
   if (sending_blocked_) {
     // Eventually the socket's buffer will fill and VirtualSocket::SendTcp will
     // set EWOULDBLOCK.
diff --git a/rtc_base/virtualsocketserver.h b/rtc_base/virtualsocketserver.h
index e25a5ff..e17caae 100644
--- a/rtc_base/virtualsocketserver.h
+++ b/rtc_base/virtualsocketserver.h
@@ -148,6 +148,10 @@
   bool CloseTcpConnections(const SocketAddress& addr_local,
                            const SocketAddress& addr_remote);
 
+  // Number of packets that clients have attempted to send through this virtual
+  // socket server. Intended to be used for test assertions.
+  uint32_t sent_packets() const { return sent_packets_; }
+
   // For testing purpose only. Fired when a client socket is created.
   sigslot::signal1<VirtualSocket*> SignalSocketCreated;
 
@@ -282,6 +286,9 @@
   uint32_t delay_stddev_;
   uint32_t delay_samples_;
 
+  // Used for testing.
+  uint32_t sent_packets_ = 0;
+
   std::map<rtc::IPAddress, int> delay_by_ip_;
   std::map<rtc::IPAddress, rtc::IPAddress> alternative_address_mapping_;
   std::unique_ptr<Function> delay_dist_;