DataChannel: Propagate SCTP transport errors to the channels

When the transport is terminated, if an error has occured, it will
be propagated to the channels.
When such errors can happen at the SCTP level (e.g. out of resources),
RTCError may contain an error code matching the definition at
https://www.iana.org/assignments/sctp-parameters/sctp-parameters.xhtml#sctp-parameters-24
If the m= line is rejected or removed from SDP, an error will again be sent
to the data channels, signaling their unexpected transition to closed.

Bug: webrtc:12904
Change-Id: Iea3d8aba0a57bbedb5d03f0fb6f7aba292e92fe8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/223541
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34386}
This commit is contained in:
Florent Castelli
2021-06-29 14:58:23 +02:00
committed by WebRTC LUCI CQ
parent c362eb2d1c
commit dcb9ffc6f2
14 changed files with 172 additions and 37 deletions

View File

@ -13,6 +13,7 @@
#include <memory>
#include <vector>
#include "media/sctp/sctp_transport_internal.h"
#include "pc/sctp_data_channel.h"
#include "pc/sctp_utils.h"
#include "pc/test/fake_data_channel_provider.h"
@ -635,7 +636,9 @@ TEST_F(SctpDataChannelTest, TransportDestroyedWhileDataBuffered) {
// Tell the data channel that its transport is being destroyed.
// It should then stop using the transport (allowing us to delete it) and
// transition to the "closed" state.
webrtc_data_channel_->OnTransportChannelClosed();
webrtc::RTCError error(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA, "");
error.set_error_detail(webrtc::RTCErrorDetailType::SCTP_FAILURE);
webrtc_data_channel_->OnTransportChannelClosed(error);
provider_.reset(nullptr);
EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed,
webrtc_data_channel_->state(), kDefaultTimeout);
@ -646,6 +649,31 @@ TEST_F(SctpDataChannelTest, TransportDestroyedWhileDataBuffered) {
webrtc_data_channel_->error().error_detail());
}
TEST_F(SctpDataChannelTest, TransportGotErrorCode) {
SetChannelReady();
// Tell the data channel that its transport is being destroyed with an
// error code.
// It should then report that error code.
webrtc::RTCError error(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA,
"Transport channel closed");
error.set_error_detail(webrtc::RTCErrorDetailType::SCTP_FAILURE);
error.set_sctp_cause_code(
static_cast<uint16_t>(cricket::SctpErrorCauseCode::kProtocolViolation));
webrtc_data_channel_->OnTransportChannelClosed(error);
provider_.reset(nullptr);
EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed,
webrtc_data_channel_->state(), kDefaultTimeout);
EXPECT_FALSE(webrtc_data_channel_->error().ok());
EXPECT_EQ(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA,
webrtc_data_channel_->error().type());
EXPECT_EQ(webrtc::RTCErrorDetailType::SCTP_FAILURE,
webrtc_data_channel_->error().error_detail());
EXPECT_EQ(
static_cast<uint16_t>(cricket::SctpErrorCauseCode::kProtocolViolation),
webrtc_data_channel_->error().sctp_cause_code());
}
class SctpSidAllocatorTest : public ::testing::Test {
protected:
SctpSidAllocator allocator_;