Rollback transport created by data channel
No-Try: True
Bug: chromium:1032987
Change-Id: I2c0dbd6a19e71a391dc2e0d30676d4efa26a9525
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168306
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30561}
diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc
index 8d4eee0..0687a06 100644
--- a/pc/jsep_transport_controller.cc
+++ b/pc/jsep_transport_controller.cc
@@ -443,19 +443,19 @@
use_datagram_transport_for_data_channels_receive_only;
}
-void JsepTransportController::RollbackTransportForMids(
- const std::vector<std::string>& mids) {
+void JsepTransportController::RollbackTransports() {
if (!network_thread_->IsCurrent()) {
- network_thread_->Invoke<void>(RTC_FROM_HERE,
- [=] { RollbackTransportForMids(mids); });
+ network_thread_->Invoke<void>(RTC_FROM_HERE, [=] { RollbackTransports(); });
return;
}
- for (auto&& mid : mids) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ for (auto&& mid : pending_mids_) {
RemoveTransportForMid(mid);
}
- for (auto&& mid : mids) {
+ for (auto&& mid : pending_mids_) {
MaybeDestroyJsepTransport(mid);
}
+ pending_mids_.clear();
}
rtc::scoped_refptr<webrtc::IceTransportInterface>
@@ -605,7 +605,7 @@
bool local,
SdpType type,
const cricket::SessionDescription* description) {
- RTC_DCHECK(network_thread_->IsCurrent());
+ RTC_DCHECK_RUN_ON(network_thread_);
RTC_DCHECK(description);
if (local) {
@@ -718,6 +718,9 @@
content_info.name + ": " + error.message());
}
}
+ if (type == SdpType::kAnswer) {
+ pending_mids_.clear();
+ }
return RTCError::OK();
}
@@ -874,7 +877,8 @@
if (mid_to_transport_[mid] == jsep_transport) {
return true;
}
-
+ RTC_DCHECK_RUN_ON(network_thread_);
+ pending_mids_.push_back(mid);
mid_to_transport_[mid] = jsep_transport;
return config_.transport_observer->OnTransportChanged(
mid, jsep_transport->rtp_transport(), jsep_transport->RtpDtlsTransport(),
diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h
index 9c3f691..c966e74 100644
--- a/pc/jsep_transport_controller.h
+++ b/pc/jsep_transport_controller.h
@@ -224,9 +224,9 @@
bool use_datagram_transport_for_data_channels,
bool use_datagram_transport_for_data_channels_receive_only);
- // TODO(elrello): For now the rollback only removes mid to transport mappings
+ // For now the rollback only removes mid to transport mappings
// and deletes unused transports, but doesn't consider anything more complex.
- void RollbackTransportForMids(const std::vector<std::string>& mids);
+ void RollbackTransports();
// Gets the transport parameters for the transport identified by |mid|.
// If |mid| is bundled, returns the parameters for the bundled transport.
@@ -430,7 +430,8 @@
// This keeps track of the mapping between media section
// (BaseChannel/SctpTransport) and the JsepTransport underneath.
std::map<std::string, cricket::JsepTransport*> mid_to_transport_;
-
+ // Keep track of mids that have been mapped to transports. Used for rollback.
+ std::vector<std::string> pending_mids_ RTC_GUARDED_BY(network_thread_);
// Aggregate states for Transports.
// standardized_ice_connection_state_ is intended to replace
// ice_connection_state, see bugs.webrtc.org/9308
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index b9e9d29..6678552a 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -7536,7 +7536,6 @@
}
RTC_DCHECK_RUN_ON(signaling_thread());
RTC_DCHECK(IsUnifiedPlan());
- std::vector<std::string> mids;
std::vector<rtc::scoped_refptr<MediaStreamInterface>> all_added_streams;
std::vector<rtc::scoped_refptr<MediaStreamInterface>> all_removed_streams;
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> removed_receivers;
@@ -7563,8 +7562,6 @@
}
RTC_DCHECK(transceiver->internal()->mid().has_value());
- std::string mid = transceiver->internal()->mid().value();
- mids.push_back(mid);
DestroyTransceiverChannel(transceiver);
if (signaling_state() == PeerConnectionInterface::kHaveRemoteOffer &&
@@ -7589,7 +7586,7 @@
transceiver->internal()->set_mid(state.mid());
transceiver->internal()->set_mline_index(state.mline_index());
}
- transport_controller_->RollbackTransportForMids(mids);
+ transport_controller_->RollbackTransports();
transceiver_stable_states_by_transceivers_.clear();
pending_local_description_.reset();
pending_remote_description_.reset();
diff --git a/pc/peer_connection_jsep_unittest.cc b/pc/peer_connection_jsep_unittest.cc
index 3186e8f..2a3c4c60 100644
--- a/pc/peer_connection_jsep_unittest.cc
+++ b/pc/peer_connection_jsep_unittest.cc
@@ -2129,4 +2129,73 @@
"id_1");
}
+TEST_F(PeerConnectionJsepTest, DataChannelImplicitRollback) {
+ RTCConfiguration config;
+ config.sdp_semantics = SdpSemantics::kUnifiedPlan;
+ config.enable_implicit_rollback = true;
+ auto caller = CreatePeerConnection(config);
+ caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
+ auto callee = CreatePeerConnection(config);
+ callee->CreateDataChannel("dummy");
+ EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
+ EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ EXPECT_TRUE(callee->CreateAnswerAndSetAsLocal());
+ EXPECT_TRUE(callee->observer()->negotiation_needed());
+ EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
+}
+
+TEST_F(PeerConnectionJsepTest, RollbackRemoteDataChannelThenAddTransceiver) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
+ caller->CreateDataChannel("dummy");
+ EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
+ callee->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
+ EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
+}
+
+TEST_F(PeerConnectionJsepTest,
+ RollbackRemoteDataChannelThenAddTransceiverAndDataChannel) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
+ caller->CreateDataChannel("dummy");
+ EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
+ callee->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
+ callee->CreateDataChannel("dummy");
+ EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
+}
+
+TEST_F(PeerConnectionJsepTest, RollbackRemoteDataChannelThenAddDataChannel) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
+ caller->CreateDataChannel("dummy");
+ EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
+ callee->CreateDataChannel("dummy");
+ EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
+}
+
+TEST_F(PeerConnectionJsepTest, RollbackRemoteTransceiverThenAddDataChannel) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
+ caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
+ EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
+ callee->CreateDataChannel("dummy");
+ EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
+}
+
+TEST_F(PeerConnectionJsepTest,
+ RollbackRemoteTransceiverThenAddDataChannelAndTransceiver) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
+ caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
+ EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
+ callee->CreateDataChannel("dummy");
+ callee->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
+ EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
+}
+
} // namespace webrtc