Don't crash when renegotiating after the peer rejects data channels
Bug: webrtc:11320
Change-Id: I5a58d550574a4e0702fc6f05b7fb663fbc23d0b4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168200
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30463}
diff --git a/pc/media_session.cc b/pc/media_session.cc
index e764101..5f0c1ff 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -2255,7 +2255,7 @@
}
desc->AddContent(media_description_options.mid, MediaProtocolType::kSctp,
- std::move(data));
+ media_description_options.stopped, std::move(data));
if (!AddTransportOffer(media_description_options.mid,
media_description_options.transport_options,
current_description, desc, ice_credentials)) {
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 5ace3e3..2e138c4 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -5128,13 +5128,18 @@
}
} else {
RTC_CHECK_EQ(cricket::MEDIA_TYPE_DATA, media_type);
- RTC_CHECK(GetDataMid());
- if (had_been_rejected || mid != *GetDataMid()) {
+ if (had_been_rejected) {
session_options->media_description_options.push_back(
GetMediaDescriptionOptionsForRejectedData(mid));
} else {
- session_options->media_description_options.push_back(
- GetMediaDescriptionOptionsForActiveData(mid));
+ RTC_CHECK(GetDataMid());
+ if (mid == *GetDataMid()) {
+ session_options->media_description_options.push_back(
+ GetMediaDescriptionOptionsForActiveData(mid));
+ } else {
+ session_options->media_description_options.push_back(
+ GetMediaDescriptionOptionsForRejectedData(mid));
+ }
}
}
}
diff --git a/pc/peer_connection_data_channel_unittest.cc b/pc/peer_connection_data_channel_unittest.cc
index 61c669b..0a674f4 100644
--- a/pc/peer_connection_data_channel_unittest.cc
+++ b/pc/peer_connection_data_channel_unittest.cc
@@ -212,6 +212,13 @@
: PeerConnectionDataChannelBaseTest(GetParam()) {}
};
+class PeerConnectionDataChannelUnifiedPlanTest
+ : public PeerConnectionDataChannelBaseTest {
+ protected:
+ PeerConnectionDataChannelUnifiedPlanTest()
+ : PeerConnectionDataChannelBaseTest(SdpSemantics::kUnifiedPlan) {}
+};
+
TEST_P(PeerConnectionDataChannelTest,
NoSctpTransportCreatedIfRtpDataChannelEnabled) {
RTCConfiguration config;
@@ -411,4 +418,28 @@
Values(SdpSemantics::kPlanB,
SdpSemantics::kUnifiedPlan));
+TEST_F(PeerConnectionDataChannelUnifiedPlanTest,
+ ReOfferAfterPeerRejectsDataChannel) {
+ auto caller = CreatePeerConnectionWithDataChannel();
+ PeerConnectionFactoryInterface::Options options;
+ options.disable_sctp_data_channels = true;
+ auto callee = CreatePeerConnection(RTCConfiguration(), options);
+
+ ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
+
+ auto offer = caller->CreateOffer();
+ ASSERT_TRUE(offer);
+ const auto& contents = offer->description()->contents();
+ ASSERT_EQ(1u, contents.size());
+ EXPECT_TRUE(contents[0].rejected);
+
+ ASSERT_TRUE(
+ caller->SetLocalDescription(CloneSessionDescription(offer.get())));
+ ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
+
+ auto answer = callee->CreateAnswerAndSetAsLocal();
+ ASSERT_TRUE(answer);
+ EXPECT_TRUE(caller->SetRemoteDescription(std::move(answer)));
+}
+
} // namespace webrtc