Changes to enable use of DatagramTransport as a data channel transport.

PeerConnection now has a new setting in RTCConfiguration to enable use of
datagram transport for data channels.  There is also a corresponding field
trial, which has both a kill-switch and a way to change the default value.

PeerConnection's interaction with MediaTransport for data channels has been
refactored to work with DataChannelTransportInterface instead.

Adds a DataChannelState and OnStateChanged() to the DataChannelSink
callbacks.  This allows PeerConnection to listen to the data channel's
state directly, instead of indirectly by monitoring media transport
state.  This is necessary to enable use of non-media-transport (eg.
datagram transport) data channel transports.

For now, PeerConnection watches the state through MediaTransport as well.
This will persist until MediaTransport implements the new callback.

Datagram transport use is negotiated.  As such, an offer that requests to use
datagram transport for data channels may be rejected by the answerer.  If the
offer includes DTLS, the data channels will be negotiated as SCTP/DTLS data
channels with an extra x-opaque parameter for datagram transport.  If the
opaque parameter is rejected (by an answerer without datagram support), the
offerer may fall back to SCTP.

If DTLS is not enabled, there is no viable fallback.  In this case, the data
channels are negotiated as media transport data channels.  If the receiver does
not understand the x-opaque line, it will reject these data channels, and the
offerer's data channels will be closed.

Bug: webrtc:9719
Change-Id: Ic1bf3664c4bcf9d754482df59897f5f72fe68fcc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/147702
Commit-Queue: Bjorn Mellem <mellem@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28932}
This commit is contained in:
Bjorn A Mellem
2019-08-21 10:44:59 -07:00
committed by Commit Bot
parent f254e9e9e5
commit b689af4c99
20 changed files with 1139 additions and 191 deletions

View File

@ -44,6 +44,7 @@ class MockDataChannelSink : public DataChannelSink {
void(int, DataMessageType, const rtc::CopyOnWriteBuffer&));
MOCK_METHOD1(OnChannelClosing, void(int));
MOCK_METHOD1(OnChannelClosed, void(int));
MOCK_METHOD0(OnReadyToSend, void());
};
class MockStateCallback : public MediaTransportStateCallback {
@ -203,8 +204,8 @@ TEST(LoopbackMediaTransport, InitialStateDeliveredWhenCallbackSet) {
MediaTransportPair transport_pair(thread.get());
MockStateCallback state_callback;
EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kPending));
transport_pair.first()->SetMediaTransportStateCallback(&state_callback);
transport_pair.FlushAsyncInvokes();
}
@ -238,4 +239,47 @@ TEST(LoopbackMediaTransport, StateChangeDeliveredToCallback) {
transport_pair.FlushAsyncInvokes();
}
TEST(LoopbackMediaTransport, NotReadyToSendWhenDataSinkSet) {
std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
thread->Start();
MediaTransportPair transport_pair(thread.get());
MockDataChannelSink data_channel_sink;
EXPECT_CALL(data_channel_sink, OnReadyToSend()).Times(0);
transport_pair.first()->SetDataSink(&data_channel_sink);
transport_pair.FlushAsyncInvokes();
transport_pair.first()->SetDataSink(nullptr);
}
TEST(LoopbackMediaTransport, ReadyToSendWhenDataSinkSet) {
std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
thread->Start();
MediaTransportPair transport_pair(thread.get());
transport_pair.SetState(MediaTransportState::kWritable);
transport_pair.FlushAsyncInvokes();
MockDataChannelSink data_channel_sink;
EXPECT_CALL(data_channel_sink, OnReadyToSend());
transport_pair.first()->SetDataSink(&data_channel_sink);
transport_pair.FlushAsyncInvokes();
transport_pair.first()->SetDataSink(nullptr);
}
TEST(LoopbackMediaTransport, StateChangeDeliveredToDataSink) {
std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
thread->Start();
MediaTransportPair transport_pair(thread.get());
MockDataChannelSink data_channel_sink;
EXPECT_CALL(data_channel_sink, OnReadyToSend());
transport_pair.first()->SetDataSink(&data_channel_sink);
transport_pair.SetState(MediaTransportState::kWritable);
transport_pair.FlushAsyncInvokes();
transport_pair.first()->SetDataSink(nullptr);
}
} // namespace webrtc