Add API for returning a webrtc::DtlsTransport for a MID on a PC

This includes a refactoring of jseptransport to store a refcounted
object instead of a std::unique_ptr to the cricket::DtlsTransport.

Bug: chromium:907849
Change-Id: Ib557ce72c2e6ce8af297c2b8deb7ec3a103d6d31
Reviewed-on: https://webrtc-review.googlesource.com/c/111920
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25831}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 813a35e..f3038db 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -87,6 +87,7 @@
     "cryptoparams.h",
     "datachannelinterface.cc",
     "datachannelinterface.h",
+    "dtlstransportinterface.h",
     "dtmfsenderinterface.h",
     "jsep.cc",
     "jsep.h",
diff --git a/api/DEPS b/api/DEPS
index 9756f44..c4be2a3 100644
--- a/api/DEPS
+++ b/api/DEPS
@@ -75,6 +75,10 @@
     "+rtc_base/refcount.h",
   ],
 
+  "dtlstransportinterface\.h": [
+    "+rtc_base/refcount.h",
+  ],
+
   "dtmfsenderinterface\.h": [
     "+rtc_base/refcount.h",
   ],
diff --git a/api/dtlstransportinterface.h b/api/dtlstransportinterface.h
new file mode 100644
index 0000000..dff4f5e
--- /dev/null
+++ b/api/dtlstransportinterface.h
@@ -0,0 +1,30 @@
+/*
+ *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_DTLSTRANSPORTINTERFACE_H_
+#define API_DTLSTRANSPORTINTERFACE_H_
+
+#include "rtc_base/refcount.h"
+
+namespace webrtc {
+
+// A DTLS transport, as represented to the outside world.
+// Its role is to report state changes and errors, and make sure information
+// about remote certificates is available.
+class DtlsTransportInterface : public rtc::RefCountInterface {
+ public:
+  // TODO(hta): Need a notifier interface to transmit state changes and
+  // error events. The generic NotifierInterface of mediasteraminterface.h
+  // may be suitable, or may be copyable.
+};
+
+}  // namespace webrtc
+
+#endif  // API_DTLSTRANSPORTINTERFACE_H_
diff --git a/api/peerconnectioninterface.cc b/api/peerconnectioninterface.cc
index f2953b5..a861801 100644
--- a/api/peerconnectioninterface.cc
+++ b/api/peerconnectioninterface.cc
@@ -9,6 +9,7 @@
  */
 
 #include "api/peerconnectioninterface.h"
+#include "api/dtlstransportinterface.h"
 
 namespace webrtc {
 
@@ -175,6 +176,11 @@
   return false;
 }
 
+rtc::scoped_refptr<DtlsTransportInterface>
+PeerConnectionInterface::LookupDtlsTransportByMid(const std::string& mid) {
+  return nullptr;
+}
+
 PeerConnectionInterface::BitrateParameters::BitrateParameters() = default;
 
 PeerConnectionInterface::BitrateParameters::~BitrateParameters() = default;
diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h
index 54161b8..02b925d 100644
--- a/api/peerconnectioninterface.h
+++ b/api/peerconnectioninterface.h
@@ -129,6 +129,7 @@
 class AudioDeviceModule;
 class AudioMixer;
 class AudioProcessing;
+class DtlsTransportInterface;
 class MediaConstraintsInterface;
 class VideoDecoderFactory;
 class VideoEncoderFactory;
@@ -1029,6 +1030,14 @@
   // TODO(henrika): deprecate and remove this.
   virtual void SetAudioRecording(bool recording) {}
 
+  // Looks up the DtlsTransport associated with a MID value.
+  // In the Javascript API, DtlsTransport is a property of a sender, but
+  // because the PeerConnection owns the DtlsTransport in this implementation,
+  // it is better to look them up on the PeerConnection.
+  virtual rtc::scoped_refptr<DtlsTransportInterface> LookupDtlsTransportByMid(
+      const std::string& mid);
+  // TODO(hta): Remove default implementation.
+
   // Returns the current SignalingState.
   virtual SignalingState signaling_state() = 0;
 
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index b759b6b..6999ddd 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -36,6 +36,8 @@
     "channelmanager.h",
     "dtlssrtptransport.cc",
     "dtlssrtptransport.h",
+    "dtlstransport.cc",
+    "dtlstransport.h",
     "externalhmac.cc",
     "externalhmac.h",
     "jseptransport.cc",
diff --git a/pc/dtlstransport.cc b/pc/dtlstransport.cc
new file mode 100644
index 0000000..dd95bae
--- /dev/null
+++ b/pc/dtlstransport.cc
@@ -0,0 +1,23 @@
+/*
+ *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "pc/dtlstransport.h"
+
+#include <utility>
+
+namespace webrtc {
+
+DtlsTransport::DtlsTransport(
+    std::unique_ptr<cricket::DtlsTransportInternal> internal)
+    : internal_dtls_transport_(std::move(internal)) {
+  RTC_DCHECK(internal_dtls_transport_.get());
+}
+
+}  // namespace webrtc
diff --git a/pc/dtlstransport.h b/pc/dtlstransport.h
new file mode 100644
index 0000000..dacdba2
--- /dev/null
+++ b/pc/dtlstransport.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef PC_DTLSTRANSPORT_H_
+#define PC_DTLSTRANSPORT_H_
+
+#include <memory>
+
+#include "api/dtlstransportinterface.h"
+#include "p2p/base/dtlstransport.h"
+
+namespace webrtc {
+
+// This implementation wraps a cricket::DtlsTransport, and takes
+// ownership of it.
+class DtlsTransport : public DtlsTransportInterface {
+ public:
+  explicit DtlsTransport(
+      std::unique_ptr<cricket::DtlsTransportInternal> internal);
+  cricket::DtlsTransportInternal* internal() {
+    return internal_dtls_transport_.get();
+  }
+
+ private:
+  std::unique_ptr<cricket::DtlsTransportInternal> internal_dtls_transport_;
+};
+
+}  // namespace webrtc
+#endif  // PC_DTLSTRANSPORT_H_
diff --git a/pc/jseptransport.cc b/pc/jseptransport.cc
index 7a95c48..c60c28d 100644
--- a/pc/jseptransport.cc
+++ b/pc/jseptransport.cc
@@ -101,8 +101,15 @@
     std::unique_ptr<webrtc::MediaTransportInterface> media_transport)
     : mid_(mid),
       local_certificate_(local_certificate),
-      rtp_dtls_transport_(std::move(rtp_dtls_transport)),
-      rtcp_dtls_transport_(std::move(rtcp_dtls_transport)),
+      rtp_dtls_transport_(
+          rtp_dtls_transport ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
+                                   std::move(rtp_dtls_transport))
+                             : nullptr),
+      rtcp_dtls_transport_(
+          rtcp_dtls_transport
+              ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
+                    std::move(rtcp_dtls_transport))
+              : nullptr),
       media_transport_(std::move(media_transport)) {
   RTC_DCHECK(rtp_dtls_transport_);
   if (unencrypted_rtp_transport) {
@@ -185,10 +192,10 @@
     }
   }
 
-  SetLocalIceParameters(rtp_dtls_transport_->ice_transport());
+  SetLocalIceParameters(rtp_dtls_transport_->internal()->ice_transport());
 
   if (rtcp_dtls_transport_) {
-    SetLocalIceParameters(rtcp_dtls_transport_->ice_transport());
+    SetLocalIceParameters(rtcp_dtls_transport_->internal()->ice_transport());
   }
 
   // If PRANSWER/ANSWER is set, we should decide transport protocol type.
@@ -248,10 +255,10 @@
   }
 
   remote_description_.reset(new JsepTransportDescription(jsep_description));
-  SetRemoteIceParameters(rtp_dtls_transport_->ice_transport());
+  SetRemoteIceParameters(rtp_dtls_transport_->internal()->ice_transport());
 
   if (rtcp_dtls_transport_) {
-    SetRemoteIceParameters(rtcp_dtls_transport_->ice_transport());
+    SetRemoteIceParameters(rtcp_dtls_transport_->internal()->ice_transport());
   }
 
   // If PRANSWER/ANSWER is set, we should decide transport protocol type.
@@ -278,14 +285,14 @@
   for (const cricket::Candidate& candidate : candidates) {
     auto transport =
         candidate.component() == cricket::ICE_CANDIDATE_COMPONENT_RTP
-            ? rtp_dtls_transport_.get()
-            : rtcp_dtls_transport_.get();
+            ? rtp_dtls_transport_
+            : rtcp_dtls_transport_;
     if (!transport) {
       return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                               "Candidate has an unknown component: " +
                                   candidate.ToString() + " for mid " + mid());
     }
-    transport->ice_transport()->AddRemoteCandidate(candidate);
+    transport->internal()->ice_transport()->AddRemoteCandidate(candidate);
   }
   return webrtc::RTCError::OK();
 }
@@ -300,7 +307,7 @@
 absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
   RTC_DCHECK(rtp_dtls_transport_);
   rtc::SSLRole dtls_role;
-  if (!rtp_dtls_transport_->GetDtlsRole(&dtls_role)) {
+  if (!rtp_dtls_transport_->internal()->GetDtlsRole(&dtls_role)) {
     return absl::optional<rtc::SSLRole>();
   }
 
@@ -310,9 +317,9 @@
 bool JsepTransport::GetStats(TransportStats* stats) {
   stats->transport_name = mid();
   stats->channel_stats.clear();
-  bool ret = GetTransportStats(rtp_dtls_transport_.get(), stats);
+  bool ret = GetTransportStats(rtp_dtls_transport_->internal(), stats);
   if (rtcp_dtls_transport_) {
-    ret &= GetTransportStats(rtcp_dtls_transport_.get(), stats);
+    ret &= GetTransportStats(rtcp_dtls_transport_->internal(), stats);
   }
   return ret;
 }
@@ -440,7 +447,7 @@
     dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport(),
                                             /*rtcp_dtls_transport=*/nullptr);
   }
-  rtcp_dtls_transport_.reset();
+  rtcp_dtls_transport_ = nullptr;  // Destroy this reference.
   // Notify the JsepTransportController to update the aggregate states.
   SignalRtcpMuxActive();
 }
@@ -528,14 +535,14 @@
   // creation, we have the negotiation state saved until a new
   // negotiation happens.
   webrtc::RTCError error = SetNegotiatedDtlsParameters(
-      rtp_dtls_transport_.get(), negotiated_dtls_role,
+      rtp_dtls_transport_->internal(), negotiated_dtls_role,
       remote_fingerprint.get());
   if (!error.ok()) {
     return error;
   }
 
   if (rtcp_dtls_transport_) {
-    error = SetNegotiatedDtlsParameters(rtcp_dtls_transport_.get(),
+    error = SetNegotiatedDtlsParameters(rtcp_dtls_transport_->internal(),
                                         negotiated_dtls_role,
                                         remote_fingerprint.get());
   }
@@ -634,9 +641,13 @@
                                       TransportStats* stats) {
   RTC_DCHECK(dtls_transport);
   TransportChannelStats substats;
-  substats.component = dtls_transport == rtcp_dtls_transport_.get()
-                           ? ICE_CANDIDATE_COMPONENT_RTCP
-                           : ICE_CANDIDATE_COMPONENT_RTP;
+  if (rtcp_dtls_transport_) {
+    substats.component = dtls_transport == rtcp_dtls_transport_->internal()
+                             ? ICE_CANDIDATE_COMPONENT_RTCP
+                             : ICE_CANDIDATE_COMPONENT_RTP;
+  } else {
+    substats.component = ICE_CANDIDATE_COMPONENT_RTP;
+  }
   dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
   dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
   substats.dtls_state = dtls_transport->dtls_state();
diff --git a/pc/jseptransport.h b/pc/jseptransport.h
index 952f2cc..dee5500 100644
--- a/pc/jseptransport.h
+++ b/pc/jseptransport.h
@@ -24,6 +24,7 @@
 #include "p2p/base/p2pconstants.h"
 #include "p2p/base/transportinfo.h"
 #include "pc/dtlssrtptransport.h"
+#include "pc/dtlstransport.h"
 #include "pc/rtcpmuxfilter.h"
 #include "pc/rtptransport.h"
 #include "pc/sessiondescription.h"
@@ -117,7 +118,6 @@
   webrtc::RTCError SetRemoteJsepTransportDescription(
       const JsepTransportDescription& jsep_description,
       webrtc::SdpType type);
-
   webrtc::RTCError AddRemoteCandidates(const Candidates& candidates);
 
   // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
@@ -157,12 +157,40 @@
     }
   }
 
-  DtlsTransportInternal* rtp_dtls_transport() const {
-    return rtp_dtls_transport_.get();
+  const DtlsTransportInternal* rtp_dtls_transport() const {
+    if (rtp_dtls_transport_) {
+      return rtp_dtls_transport_->internal();
+    } else {
+      return nullptr;
+    }
   }
 
-  DtlsTransportInternal* rtcp_dtls_transport() const {
-    return rtcp_dtls_transport_.get();
+  DtlsTransportInternal* rtp_dtls_transport() {
+    if (rtp_dtls_transport_) {
+      return rtp_dtls_transport_->internal();
+    } else {
+      return nullptr;
+    }
+  }
+
+  const DtlsTransportInternal* rtcp_dtls_transport() const {
+    if (rtcp_dtls_transport_) {
+      return rtcp_dtls_transport_->internal();
+    } else {
+      return nullptr;
+    }
+  }
+
+  DtlsTransportInternal* rtcp_dtls_transport() {
+    if (rtcp_dtls_transport_) {
+      return rtcp_dtls_transport_->internal();
+    } else {
+      return nullptr;
+    }
+  }
+
+  rtc::scoped_refptr<webrtc::DtlsTransportInterface> RtpDtlsTransport() {
+    return rtp_dtls_transport_;
   }
 
   // Returns media transport, if available.
@@ -256,8 +284,8 @@
   std::unique_ptr<webrtc::SrtpTransport> sdes_transport_;
   std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport_;
 
-  std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport_;
-  std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport_;
+  rtc::scoped_refptr<webrtc::DtlsTransport> rtp_dtls_transport_;
+  rtc::scoped_refptr<webrtc::DtlsTransport> rtcp_dtls_transport_;
 
   SrtpFilter sdes_negotiator_;
   RtcpMuxFilter rtcp_mux_negotiator_;
diff --git a/pc/jseptransport_unittest.cc b/pc/jseptransport_unittest.cc
index e518301..ab9101b 100644
--- a/pc/jseptransport_unittest.cc
+++ b/pc/jseptransport_unittest.cc
@@ -870,7 +870,7 @@
       CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp);
   JsepTransportDescription local_desc;
   local_desc.rtcp_mux_enabled = true;
-  EXPECT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
+  ASSERT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
   EXPECT_FALSE(signal_rtcp_mux_active_received_);
 
   // The remote side supports RTCP-mux.
diff --git a/pc/jseptransportcontroller.cc b/pc/jseptransportcontroller.cc
index 78ecaf3..a7a18b4 100644
--- a/pc/jseptransportcontroller.cc
+++ b/pc/jseptransportcontroller.cc
@@ -153,7 +153,7 @@
 }
 
 cricket::DtlsTransportInternal* JsepTransportController::GetDtlsTransport(
-    const std::string& mid) const {
+    const std::string& mid) {
   auto jsep_transport = GetJsepTransportForMid(mid);
   if (!jsep_transport) {
     return nullptr;
@@ -161,8 +161,8 @@
   return jsep_transport->rtp_dtls_transport();
 }
 
-cricket::DtlsTransportInternal* JsepTransportController::GetRtcpDtlsTransport(
-    const std::string& mid) const {
+const cricket::DtlsTransportInternal*
+JsepTransportController::GetRtcpDtlsTransport(const std::string& mid) const {
   auto jsep_transport = GetJsepTransportForMid(mid);
   if (!jsep_transport) {
     return nullptr;
@@ -170,6 +170,15 @@
   return jsep_transport->rtcp_dtls_transport();
 }
 
+rtc::scoped_refptr<webrtc::DtlsTransportInterface>
+JsepTransportController::LookupDtlsTransportByMid(const std::string& mid) {
+  auto jsep_transport = GetJsepTransportForMid(mid);
+  if (!jsep_transport) {
+    return nullptr;
+  }
+  return jsep_transport->RtpDtlsTransport();
+}
+
 void JsepTransportController::SetIceConfig(const cricket::IceConfig& config) {
   if (!network_thread_->IsCurrent()) {
     network_thread_->Invoke<void>(RTC_FROM_HERE, [&] { SetIceConfig(config); });
@@ -346,9 +355,10 @@
       continue;
     }
     for (const cricket::Candidate& candidate : candidates) {
-      auto dtls = candidate.component() == cricket::ICE_CANDIDATE_COMPONENT_RTP
-                      ? jsep_transport->rtp_dtls_transport()
-                      : jsep_transport->rtcp_dtls_transport();
+      cricket::DtlsTransportInternal* dtls =
+          candidate.component() == cricket::ICE_CANDIDATE_COMPONENT_RTP
+              ? jsep_transport->rtp_dtls_transport()
+              : jsep_transport->rtcp_dtls_transport();
       if (dtls) {
         dtls->ice_transport()->RemoveRemoteCandidate(candidate);
       }
diff --git a/pc/jseptransportcontroller.h b/pc/jseptransportcontroller.h
index 3ed7f5f..653c4c9 100644
--- a/pc/jseptransportcontroller.h
+++ b/pc/jseptransportcontroller.h
@@ -28,6 +28,7 @@
 #include "p2p/base/transportfactoryinterface.h"
 #include "pc/channel.h"
 #include "pc/dtlssrtptransport.h"
+#include "pc/dtlstransport.h"
 #include "pc/jseptransport.h"
 #include "pc/rtptransport.h"
 #include "pc/srtptransport.h"
@@ -112,10 +113,12 @@
   // Get transports to be used for the provided |mid|. If bundling is enabled,
   // calling GetRtpTransport for multiple MIDs may yield the same object.
   RtpTransportInternal* GetRtpTransport(const std::string& mid) const;
-  cricket::DtlsTransportInternal* GetDtlsTransport(
+  cricket::DtlsTransportInternal* GetDtlsTransport(const std::string& mid);
+  const cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
       const std::string& mid) const;
-  cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
-      const std::string& mid) const;
+  // Gets the externally sharable version of the DtlsTransport.
+  rtc::scoped_refptr<webrtc::DtlsTransportInterface> LookupDtlsTransportByMid(
+      const std::string& mid);
 
   MediaTransportInterface* GetMediaTransport(const std::string& mid) const;
   MediaTransportState GetMediaTransportState(const std::string& mid) const;
diff --git a/pc/jseptransportcontroller_unittest.cc b/pc/jseptransportcontroller_unittest.cc
index 129d22a..03ef2ea 100644
--- a/pc/jseptransportcontroller_unittest.cc
+++ b/pc/jseptransportcontroller_unittest.cc
@@ -371,11 +371,20 @@
                   .ok());
   EXPECT_NE(nullptr, transport_controller_->GetDtlsTransport(kAudioMid1));
   EXPECT_NE(nullptr, transport_controller_->GetRtcpDtlsTransport(kAudioMid1));
+  EXPECT_NE(nullptr,
+            transport_controller_->LookupDtlsTransportByMid(kAudioMid1));
   EXPECT_NE(nullptr, transport_controller_->GetDtlsTransport(kVideoMid1));
   EXPECT_NE(nullptr, transport_controller_->GetRtcpDtlsTransport(kVideoMid1));
+  EXPECT_NE(nullptr,
+            transport_controller_->LookupDtlsTransportByMid(kVideoMid1));
+  // Lookup for all MIDs should return different transports (no bundle)
+  EXPECT_NE(transport_controller_->LookupDtlsTransportByMid(kAudioMid1),
+            transport_controller_->LookupDtlsTransportByMid(kVideoMid1));
   // Return nullptr for non-existing ones.
   EXPECT_EQ(nullptr, transport_controller_->GetDtlsTransport(kVideoMid2));
   EXPECT_EQ(nullptr, transport_controller_->GetRtcpDtlsTransport(kVideoMid2));
+  EXPECT_EQ(nullptr,
+            transport_controller_->LookupDtlsTransportByMid(kVideoMid2));
 }
 
 TEST_F(JsepTransportControllerTest, GetDtlsTransportWithRtcpMux) {
@@ -1275,6 +1284,9 @@
   EXPECT_EQ(transport1, transport3);
   EXPECT_EQ(transport1, transport4);
 
+  EXPECT_EQ(transport_controller_->LookupDtlsTransportByMid(kAudioMid1),
+            transport_controller_->LookupDtlsTransportByMid(kVideoMid1));
+
   // Verify the OnRtpTransport/DtlsTransportChanged signals are fired correctly.
   auto it = changed_rtp_transport_by_mid_.find(kAudioMid2);
   ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index a6b47c1..9c04c31 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -3346,6 +3346,11 @@
       RTC_FROM_HERE, rtc::Bind(&PeerConnection::StopRtcEventLog_w, this));
 }
 
+rtc::scoped_refptr<DtlsTransportInterface>
+PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
+  return transport_controller_->LookupDtlsTransportByMid(mid);
+}
+
 const SessionDescriptionInterface* PeerConnection::local_description() const {
   return pending_local_description_ ? pending_local_description_.get()
                                     : current_local_description_.get();
diff --git a/pc/peerconnection.h b/pc/peerconnection.h
index 7e97afa..3bdd37e 100644
--- a/pc/peerconnection.h
+++ b/pc/peerconnection.h
@@ -194,6 +194,9 @@
   void SetAudioPlayout(bool playout) override;
   void SetAudioRecording(bool recording) override;
 
+  rtc::scoped_refptr<DtlsTransportInterface> LookupDtlsTransportByMid(
+      const std::string& mid) override;
+
   RTC_DEPRECATED bool StartRtcEventLog(rtc::PlatformFile file,
                                        int64_t max_size_bytes) override;
   bool StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
diff --git a/pc/peerconnection_bundle_unittest.cc b/pc/peerconnection_bundle_unittest.cc
index 6c372b4..fca9914 100644
--- a/pc/peerconnection_bundle_unittest.cc
+++ b/pc/peerconnection_bundle_unittest.cc
@@ -51,6 +51,18 @@
 // will use: https://www.w3.org/TR/webrtc/#dom-rtcrtpsender-transport
 // Should also be able to remove GetTransceiversForTesting at that point.
 
+class FakeNetworkManagerWithNoAnyNetwork : public rtc::FakeNetworkManager {
+ public:
+  void GetAnyAddressNetworks(NetworkList* networks) override {
+    // This function allocates networks that are owned by the
+    // NetworkManager. But some tests assume that they can release
+    // all networks independent of the network manager.
+    // In order to prevent use-after-free issues, don't allow this
+    // function to have any effect when run in tests.
+    RTC_LOG(LS_INFO) << "FakeNetworkManager::GetAnyAddressNetworks ignored";
+  }
+};
+
 class PeerConnectionWrapperForBundleTest : public PeerConnectionWrapper {
  public:
   using PeerConnectionWrapper::PeerConnectionWrapper;
@@ -235,7 +247,7 @@
     // base class members). Therefore, the test fixture will own all the fake
     // networks even though tests should access the fake network through the
     // PeerConnectionWrapper.
-    auto* fake_network = new rtc::FakeNetworkManager();
+    auto* fake_network = new FakeNetworkManagerWithNoAnyNetwork();
     fake_networks_.emplace_back(fake_network);
     return fake_network;
   }
diff --git a/rtc_base/fakenetwork.h b/rtc_base/fakenetwork.h
index cb890ec..fc690d9 100644
--- a/rtc_base/fakenetwork.h
+++ b/rtc_base/fakenetwork.h
@@ -129,9 +129,6 @@
   int start_count_ = 0;
   bool sent_first_update_ = false;
 
-  IPAddress default_local_ipv4_address_;
-  IPAddress default_local_ipv6_address_;
-
   std::unique_ptr<webrtc::FakeMdnsResponder> mdns_responder_;
 };