diff --git a/pc/BUILD.gn b/pc/BUILD.gn index f5c6254dce..33b6fa2753 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -36,8 +36,8 @@ rtc_static_library("rtc_pc_base") { "channel_manager.h", "composite_rtp_transport.cc", "composite_rtp_transport.h", - "datagram_dtls_adaptor.cc", - "datagram_dtls_adaptor.h", + "datagram_rtp_transport.cc", + "datagram_rtp_transport.h", "dtls_srtp_transport.cc", "dtls_srtp_transport.h", "dtls_transport.cc", diff --git a/pc/datagram_dtls_adaptor.cc b/pc/datagram_dtls_adaptor.cc deleted file mode 100644 index 190a2d31e4..0000000000 --- a/pc/datagram_dtls_adaptor.cc +++ /dev/null @@ -1,610 +0,0 @@ -/* - * 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/datagram_dtls_adaptor.h" - -#include -#include -#include - -#include "absl/memory/memory.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "api/rtc_error.h" -#include "api/rtc_event_log/rtc_event_log.h" -#include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h" -#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h" -#include "modules/rtp_rtcp/include/rtp_header_parser.h" -#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" -#include "modules/rtp_rtcp/source/rtp_packet.h" -#include "p2p/base/dtls_transport_internal.h" -#include "p2p/base/packet_transport_internal.h" -#include "rtc_base/buffer.h" -#include "rtc_base/checks.h" -#include "rtc_base/dscp.h" -#include "rtc_base/logging.h" -#include "rtc_base/message_queue.h" -#include "rtc_base/rtc_certificate.h" -#include "rtc_base/ssl_stream_adapter.h" -#include "rtc_base/stream.h" -#include "rtc_base/thread.h" -#include "system_wrappers/include/field_trial.h" - -#ifdef BYPASS_DATAGRAM_DTLS_TEST_ONLY -// Send unencrypted packets directly to ICE, bypassing datagtram -// transport. Use in tests only. -constexpr bool kBypassDatagramDtlsTestOnly = true; -#else -constexpr bool kBypassDatagramDtlsTestOnly = false; -#endif - -namespace cricket { - -namespace { - -// Field trials. -// Disable datagram to RTCP feedback translation and enable RTCP feedback loop -// on top of datagram feedback loop. Note that two -// feedback loops add unneccesary overhead, so it's preferable to use feedback -// loop provided by datagram transport and convert datagram ACKs to RTCP ACKs, -// but enabling RTCP feedback loop may be useful in tests and experiments. -const char kDisableDatagramToRtcpFeebackTranslationFieldTrial[] = - "WebRTC-kDisableDatagramToRtcpFeebackTranslation"; - -} // namespace - -// Maximum packet size of RTCP feedback packet for allocation. We re-create RTCP -// feedback packets when we get ACK notifications from datagram transport. Our -// rtcp feedback packets contain only 1 ACK, so they are much smaller than 1250. -constexpr size_t kMaxRtcpFeedbackPacketSize = 1250; - -DatagramDtlsAdaptor::DatagramDtlsAdaptor( - const std::vector& rtp_header_extensions, - IceTransportInternal* ice_transport, - webrtc::DatagramTransportInterface* datagram_transport, - const webrtc::CryptoOptions& crypto_options, - webrtc::RtcEventLog* event_log) - : crypto_options_(crypto_options), - ice_transport_(ice_transport), - datagram_transport_(datagram_transport), - event_log_(event_log), - disable_datagram_to_rtcp_feeback_translation_( - webrtc::field_trial::IsEnabled( - kDisableDatagramToRtcpFeebackTranslationFieldTrial)) { - // Save extension map for parsing RTP packets (we only need transport - // sequence numbers). - const webrtc::RtpExtension* transport_sequence_number_extension = - webrtc::RtpExtension::FindHeaderExtensionByUri( - rtp_header_extensions, webrtc::TransportSequenceNumber::kUri); - - if (transport_sequence_number_extension != nullptr) { - rtp_header_extension_map_.Register( - transport_sequence_number_extension->id); - } else { - RTC_LOG(LS_ERROR) << "Transport sequence numbers are not supported in " - "datagram transport connection"; - } - - // TODO(sukhanov): Add CHECK to make sure that field trial - // WebRTC-ExcludeTransportSequenceNumberFromFecFieldTrial is enabled. - // If feedback loop is translation is enabled, FEC packets must exclude - // transport sequence numbers, otherwise recovered packets will be corrupt. - - RTC_DCHECK(ice_transport_); - RTC_DCHECK(datagram_transport_); - ConnectToIceTransport(); -} - -void DatagramDtlsAdaptor::ConnectToIceTransport() { - ice_transport_->SignalWritableState.connect( - this, &DatagramDtlsAdaptor::OnWritableState); - ice_transport_->SignalReadyToSend.connect( - this, &DatagramDtlsAdaptor::OnReadyToSend); - ice_transport_->SignalReceivingState.connect( - this, &DatagramDtlsAdaptor::OnReceivingState); - // Datagram transport does not propagate network route change. - ice_transport_->SignalNetworkRouteChanged.connect( - this, &DatagramDtlsAdaptor::OnNetworkRouteChanged); - if (kBypassDatagramDtlsTestOnly) { - // In bypass mode we have to subscribe to ICE read and sent events. - // Test only case to use ICE directly instead of data transport. - ice_transport_->SignalReadPacket.connect( - this, &DatagramDtlsAdaptor::OnReadPacket); - ice_transport_->SignalSentPacket.connect( - this, &DatagramDtlsAdaptor::OnSentPacket); - } else { - // Subscribe to Data Transport read packets. - datagram_transport_->SetDatagramSink(this); - datagram_transport_->SetTransportStateCallback(this); - } -} - -DatagramDtlsAdaptor::~DatagramDtlsAdaptor() { - // Unsubscribe from Datagram Transport dinks. - datagram_transport_->SetDatagramSink(nullptr); - datagram_transport_->SetTransportStateCallback(nullptr); -} - -const webrtc::CryptoOptions& DatagramDtlsAdaptor::crypto_options() const { - return crypto_options_; -} - -int DatagramDtlsAdaptor::SendPacket(const char* data, - size_t len, - const rtc::PacketOptions& options, - int flags) { - RTC_DCHECK_RUN_ON(&thread_checker_); - - // TODO(sukhanov): Handle options and flags. - if (kBypassDatagramDtlsTestOnly) { - // In bypass mode sent directly to ICE. - return ice_transport_->SendPacket(data, len, options); - } - - // Assign and increment datagram_id. - const webrtc::DatagramId datagram_id = current_datagram_id_++; - - rtc::ArrayView original_data( - reinterpret_cast(data), len); - - // Send as is (without extracting transport sequence number) for - // - All RTCP packets, because they do not have transport sequence number. - // - RTP packets if we are not doing datagram => RTCP feedback translation. - if (disable_datagram_to_rtcp_feeback_translation_ || - webrtc::RtpHeaderParser::IsRtcp(original_data.data(), - original_data.size())) { - // Even if we are not extracting transport sequence number we need to - // propagate "Sent" notification for both RTP and RTCP packets. For this - // reason we need save options.packet_id in packet map. - sent_rtp_packet_map_[datagram_id] = SentPacketInfo(options.packet_id); - - return SendDatagram(original_data, datagram_id); - } - - // Parse RTP packet. - webrtc::RtpPacket rtp_packet(&rtp_header_extension_map_); - if (!rtp_packet.Parse(original_data)) { - RTC_NOTREACHED() << "Failed to parse outgoing RtpPacket, len=" << len - << ", options.packet_id=" << options.packet_id; - return -1; - } - - // Try to get transport sequence number. - uint16_t transport_senquence_number; - if (!rtp_packet.GetExtension( - &transport_senquence_number)) { - // Save packet info without transport sequence number. - sent_rtp_packet_map_[datagram_id] = SentPacketInfo(options.packet_id); - - RTC_LOG(LS_VERBOSE) - << "Sending rtp packet without transport sequence number, packet=" - << rtp_packet.ToString(); - - return SendDatagram(original_data, datagram_id); - } - - // Save packet info with sequence number and ssrc so we could reconstruct - // RTCP feedback packet when we receive datagram ACK. - sent_rtp_packet_map_[datagram_id] = SentPacketInfo( - options.packet_id, rtp_packet.Ssrc(), transport_senquence_number); - - // Since datagram transport provides feedback and timestamps, we do not need - // to send transport sequence number, so we remove it from RTP packet. Later - // when we get Ack for sent datagram, we will re-create RTCP feedback packet. - if (!rtp_packet.RemoveExtension(webrtc::TransportSequenceNumber::kId)) { - RTC_NOTREACHED() << "Failed to remove transport sequence number, packet=" - << rtp_packet.ToString(); - return -1; - } - - RTC_LOG(LS_VERBOSE) << "Removed transport_senquence_number=" - << transport_senquence_number - << " from packet=" << rtp_packet.ToString() - << ", saved bytes=" << len - rtp_packet.size(); - - return SendDatagram( - rtc::ArrayView(rtp_packet.data(), rtp_packet.size()), - datagram_id); -} - -int DatagramDtlsAdaptor::SendDatagram(rtc::ArrayView data, - webrtc::DatagramId datagram_id) { - webrtc::RTCError error = datagram_transport_->SendDatagram(data, datagram_id); - return (error.ok() ? data.size() : -1); -} - -void DatagramDtlsAdaptor::OnReadPacket(rtc::PacketTransportInternal* transport, - const char* data, - size_t size, - const int64_t& packet_time_us, - int flags) { - // Only used in bypass mode. - RTC_DCHECK(kBypassDatagramDtlsTestOnly); - - RTC_DCHECK_RUN_ON(&thread_checker_); - RTC_DCHECK_EQ(transport, ice_transport_); - RTC_DCHECK(flags == 0); - - PropagateReadPacket( - rtc::MakeArrayView(reinterpret_cast(data), size), - packet_time_us); -} - -void DatagramDtlsAdaptor::OnDatagramReceived( - rtc::ArrayView data) { - RTC_DCHECK_RUN_ON(&thread_checker_); - RTC_DCHECK(!kBypassDatagramDtlsTestOnly); - - // TODO(sukhanov): I am not filling out time, but on my video quality - // test in WebRTC the time was not set either and higher layers of the stack - // overwrite -1 with current current rtc time. Leaveing comment for now to - // make sure it works as expected. - int64_t packet_time_us = -1; - - PropagateReadPacket(data, packet_time_us); -} - -void DatagramDtlsAdaptor::OnDatagramSent(webrtc::DatagramId datagram_id) { - RTC_DCHECK_RUN_ON(&thread_checker_); - - // Find packet_id and propagate OnPacketSent notification. - const auto& it = sent_rtp_packet_map_.find(datagram_id); - if (it == sent_rtp_packet_map_.end()) { - RTC_NOTREACHED() << "Did not find sent packet info for sent datagram_id=" - << datagram_id; - return; - } - - // Also see how DatagramDtlsAdaptor::OnSentPacket handles OnSentPacket - // notification from ICE in bypass mode. - rtc::SentPacket sent_packet(/*packet_id=*/it->second.packet_id, - rtc::TimeMillis()); - - PropagateOnSentNotification(sent_packet); -} - -bool DatagramDtlsAdaptor::GetAndRemoveSentPacketInfo( - webrtc::DatagramId datagram_id, - SentPacketInfo* sent_packet_info) { - RTC_CHECK(sent_packet_info != nullptr); - - const auto& it = sent_rtp_packet_map_.find(datagram_id); - if (it == sent_rtp_packet_map_.end()) { - return false; - } - - *sent_packet_info = it->second; - sent_rtp_packet_map_.erase(it); - return true; -} - -void DatagramDtlsAdaptor::OnDatagramAcked(const webrtc::DatagramAck& ack) { - RTC_DCHECK_RUN_ON(&thread_checker_); - - SentPacketInfo sent_packet_info; - if (!GetAndRemoveSentPacketInfo(ack.datagram_id, &sent_packet_info)) { - // TODO(sukhanov): If OnDatagramAck() can come after OnDatagramLost(), - // datagram_id is already deleted and we may need to relax the CHECK below. - // It's probably OK to ignore such datagrams, because it's been a few RTTs - // anyway since they were sent. - RTC_NOTREACHED() << "Did not find sent packet info for datagram_id=" - << ack.datagram_id; - return; - } - - RTC_LOG(LS_VERBOSE) << "Datagram acked, ack.datagram_id=" << ack.datagram_id - << ", sent_packet_info.packet_id=" - << sent_packet_info.packet_id - << ", sent_packet_info.transport_sequence_number=" - << sent_packet_info.transport_sequence_number.value_or(-1) - << ", sent_packet_info.ssrc=" - << sent_packet_info.ssrc.value_or(-1) - << ", receive_timestamp_ms=" - << ack.receive_timestamp.ms(); - - // If transport sequence number was not present in RTP packet, we do not need - // to propagate RTCP feedback. - if (!sent_packet_info.transport_sequence_number) { - return; - } - - // TODO(sukhanov): We noticed that datagram transport implementations can - // return zero timestamps in the middle of the call. This is workaround to - // avoid propagating zero timestamps, but we need to understand why we have - // them in the first place. - int64_t receive_timestamp_us = ack.receive_timestamp.us(); - - if (receive_timestamp_us == 0) { - receive_timestamp_us = previous_nonzero_timestamp_us_; - } else { - previous_nonzero_timestamp_us_ = receive_timestamp_us; - } - - // Ssrc must be provided in packet info if transport sequence number is set, - // which is guaranteed by SentPacketInfo constructor. - RTC_CHECK(sent_packet_info.ssrc); - - // Recreate RTCP feedback packet. - webrtc::rtcp::TransportFeedback feedback_packet; - feedback_packet.SetMediaSsrc(*sent_packet_info.ssrc); - - const uint16_t transport_sequence_number = - sent_packet_info.transport_sequence_number.value(); - - feedback_packet.SetBase(transport_sequence_number, receive_timestamp_us); - feedback_packet.AddReceivedPacket(transport_sequence_number, - receive_timestamp_us); - - rtc::Buffer buffer(kMaxRtcpFeedbackPacketSize); - size_t index = 0; - if (!feedback_packet.Create(buffer.data(), &index, buffer.capacity(), - nullptr)) { - RTC_NOTREACHED() << "Failed to create RTCP feedback packet"; - return; - } - - RTC_CHECK_GT(index, 0); - RTC_CHECK_LE(index, kMaxRtcpFeedbackPacketSize); - - // Propagage created RTCP packet as normal incoming packet. - buffer.SetSize(index); - PropagateReadPacket(buffer, /*packet_time_us=*/-1); -} - -void DatagramDtlsAdaptor::OnDatagramLost(webrtc::DatagramId datagram_id) { - RTC_DCHECK_RUN_ON(&thread_checker_); - - RTC_LOG(LS_INFO) << "Datagram lost, datagram_id=" << datagram_id; - - SentPacketInfo sent_packet_info; - if (!GetAndRemoveSentPacketInfo(datagram_id, &sent_packet_info)) { - RTC_NOTREACHED() << "Did not find sent packet info for lost datagram_id=" - << datagram_id; - } -} - -void DatagramDtlsAdaptor::OnSentPacket(rtc::PacketTransportInternal* transport, - const rtc::SentPacket& sent_packet) { - // Only used in bypass mode. - RTC_DCHECK(kBypassDatagramDtlsTestOnly); - RTC_DCHECK_RUN_ON(&thread_checker_); - - PropagateOnSentNotification(sent_packet); -} - -void DatagramDtlsAdaptor::PropagateOnSentNotification( - const rtc::SentPacket& sent_packet) { - RTC_DCHECK_RUN_ON(&thread_checker_); - SignalSentPacket(this, sent_packet); -} - -void DatagramDtlsAdaptor::PropagateReadPacket( - rtc::ArrayView data, - const int64_t& packet_time_us) { - RTC_DCHECK_RUN_ON(&thread_checker_); - SignalReadPacket(this, reinterpret_cast(data.data()), - data.size(), packet_time_us, /*flags=*/0); -} - -int DatagramDtlsAdaptor::component() const { - return kDatagramDtlsAdaptorComponent; -} -bool DatagramDtlsAdaptor::IsDtlsActive() const { - return false; -} -bool DatagramDtlsAdaptor::GetDtlsRole(rtc::SSLRole* role) const { - return false; -} -bool DatagramDtlsAdaptor::SetDtlsRole(rtc::SSLRole role) { - return false; -} -bool DatagramDtlsAdaptor::GetSrtpCryptoSuite(int* cipher) { - return false; -} -bool DatagramDtlsAdaptor::GetSslCipherSuite(int* cipher) { - return false; -} - -rtc::scoped_refptr -DatagramDtlsAdaptor::GetLocalCertificate() const { - return nullptr; -} - -bool DatagramDtlsAdaptor::SetLocalCertificate( - const rtc::scoped_refptr& certificate) { - return false; -} - -std::unique_ptr DatagramDtlsAdaptor::GetRemoteSSLCertChain() - const { - return nullptr; -} - -bool DatagramDtlsAdaptor::ExportKeyingMaterial(const std::string& label, - const uint8_t* context, - size_t context_len, - bool use_context, - uint8_t* result, - size_t result_len) { - return false; -} - -bool DatagramDtlsAdaptor::SetRemoteFingerprint(const std::string& digest_alg, - const uint8_t* digest, - size_t digest_len) { - // TODO(sukhanov): We probably should not called with fingerptints in - // datagram scenario, but we may need to change code up the stack before - // we can return false or DCHECK. - return true; -} - -bool DatagramDtlsAdaptor::SetSslMaxProtocolVersion( - rtc::SSLProtocolVersion version) { - // TODO(sukhanov): We may be able to return false and/or DCHECK that we - // are not called if datagram transport is used, but we need to change - // integration before we can do it. - return true; -} - -IceTransportInternal* DatagramDtlsAdaptor::ice_transport() { - return ice_transport_; -} - -// Similar implementaton as in p2p/base/dtls_transport.cc. -void DatagramDtlsAdaptor::OnReadyToSend( - rtc::PacketTransportInternal* transport) { - RTC_DCHECK_RUN_ON(&thread_checker_); - if (writable()) { - SignalReadyToSend(this); - } -} - -void DatagramDtlsAdaptor::OnWritableState( - rtc::PacketTransportInternal* transport) { - RTC_DCHECK_RUN_ON(&thread_checker_); - RTC_DCHECK(transport == ice_transport_); - RTC_LOG(LS_VERBOSE) << "ice_transport writable state changed to " - << ice_transport_->writable(); - - if (kBypassDatagramDtlsTestOnly) { - // Note: SignalWritableState fired by set_writable. - set_writable(ice_transport_->writable()); - return; - } - - switch (dtls_state()) { - case DTLS_TRANSPORT_NEW: - break; - case DTLS_TRANSPORT_CONNECTED: - // Note: SignalWritableState fired by set_writable. - // Do we also need set_receiving(ice_transport_->receiving()) here now, in - // case we lose that signal before "DTLS" connects? - // DtlsTransport::OnWritableState does not set_receiving in a similar - // case, so leaving it out for the time being, but it would be good to - // understand why. - set_writable(ice_transport_->writable()); - break; - case DTLS_TRANSPORT_CONNECTING: - // Do nothing. - break; - case DTLS_TRANSPORT_FAILED: - case DTLS_TRANSPORT_CLOSED: - // Should not happen. Do nothing. - break; - } -} - -void DatagramDtlsAdaptor::OnStateChanged(webrtc::MediaTransportState state) { - // Convert MediaTransportState to DTLS state. - switch (state) { - case webrtc::MediaTransportState::kPending: - set_dtls_state(DTLS_TRANSPORT_CONNECTING); - break; - - case webrtc::MediaTransportState::kWritable: - // Since we do not set writable state until datagram transport is - // connected, we need to call set_writable first. - set_writable(ice_transport_->writable()); - set_dtls_state(DTLS_TRANSPORT_CONNECTED); - break; - - case webrtc::MediaTransportState::kClosed: - set_dtls_state(DTLS_TRANSPORT_CLOSED); - break; - } -} - -DtlsTransportState DatagramDtlsAdaptor::dtls_state() const { - return dtls_state_; -} - -const std::string& DatagramDtlsAdaptor::transport_name() const { - return ice_transport_->transport_name(); -} - -bool DatagramDtlsAdaptor::writable() const { - // NOTE that even if ice is writable, writable_ maybe false, because we - // propagte writable only after DTLS is connect (this is consistent with - // implementation in dtls_transport.cc). - return writable_; -} - -bool DatagramDtlsAdaptor::receiving() const { - return receiving_; -} - -int DatagramDtlsAdaptor::SetOption(rtc::Socket::Option opt, int value) { - return ice_transport_->SetOption(opt, value); -} - -int DatagramDtlsAdaptor::GetError() { - return ice_transport_->GetError(); -} - -void DatagramDtlsAdaptor::OnNetworkRouteChanged( - absl::optional network_route) { - RTC_DCHECK_RUN_ON(&thread_checker_); - SignalNetworkRouteChanged(network_route); -} - -void DatagramDtlsAdaptor::OnReceivingState( - rtc::PacketTransportInternal* transport) { - RTC_DCHECK_RUN_ON(&thread_checker_); - RTC_DCHECK(transport == ice_transport_); - RTC_LOG(LS_VERBOSE) << "ice_transport receiving state changed to " - << ice_transport_->receiving(); - - if (kBypassDatagramDtlsTestOnly || dtls_state() == DTLS_TRANSPORT_CONNECTED) { - // Note: SignalReceivingState fired by set_receiving. - set_receiving(ice_transport_->receiving()); - } -} - -void DatagramDtlsAdaptor::set_receiving(bool receiving) { - if (receiving_ == receiving) { - return; - } - receiving_ = receiving; - SignalReceivingState(this); -} - -// Similar implementaton as in p2p/base/dtls_transport.cc. -void DatagramDtlsAdaptor::set_writable(bool writable) { - if (writable_ == writable) { - return; - } - if (event_log_) { - event_log_->Log( - absl::make_unique(writable)); - } - RTC_LOG(LS_VERBOSE) << "set_writable to: " << writable; - writable_ = writable; - if (writable_) { - SignalReadyToSend(this); - } - SignalWritableState(this); -} - -// Similar implementaton as in p2p/base/dtls_transport.cc. -void DatagramDtlsAdaptor::set_dtls_state(DtlsTransportState state) { - if (dtls_state_ == state) { - return; - } - if (event_log_) { - event_log_->Log(absl::make_unique( - ConvertDtlsTransportState(state))); - } - RTC_LOG(LS_VERBOSE) << "set_dtls_state from:" << dtls_state_ << " to " - << state; - dtls_state_ = state; - SignalDtlsState(this, state); -} - -} // namespace cricket diff --git a/pc/datagram_rtp_transport.cc b/pc/datagram_rtp_transport.cc new file mode 100644 index 0000000000..ebf82a7ab9 --- /dev/null +++ b/pc/datagram_rtp_transport.cc @@ -0,0 +1,387 @@ +/* + * 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/datagram_rtp_transport.h" + +#include +#include +#include + +#include "absl/memory/memory.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "api/array_view.h" +#include "api/rtc_error.h" +#include "media/base/rtp_utils.h" +#include "modules/rtp_rtcp/include/rtp_header_parser.h" +#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" +#include "modules/rtp_rtcp/source/rtp_packet.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "p2p/base/dtls_transport_internal.h" +#include "p2p/base/packet_transport_internal.h" +#include "rtc_base/buffer.h" +#include "rtc_base/checks.h" +#include "rtc_base/dscp.h" +#include "rtc_base/logging.h" +#include "rtc_base/message_queue.h" +#include "rtc_base/rtc_certificate.h" +#include "rtc_base/ssl_stream_adapter.h" +#include "rtc_base/stream.h" +#include "rtc_base/thread.h" +#include "system_wrappers/include/field_trial.h" + +namespace webrtc { + +namespace { + +// Field trials. +// Disable datagram to RTCP feedback translation and enable RTCP feedback loop +// on top of datagram feedback loop. Note that two +// feedback loops add unneccesary overhead, so it's preferable to use feedback +// loop provided by datagram transport and convert datagram ACKs to RTCP ACKs, +// but enabling RTCP feedback loop may be useful in tests and experiments. +const char kDisableDatagramToRtcpFeebackTranslationFieldTrial[] = + "WebRTC-kDisableDatagramToRtcpFeebackTranslation"; + +} // namespace + +// Maximum packet size of RTCP feedback packet for allocation. We re-create RTCP +// feedback packets when we get ACK notifications from datagram transport. Our +// rtcp feedback packets contain only 1 ACK, so they are much smaller than 1250. +constexpr size_t kMaxRtcpFeedbackPacketSize = 1250; + +DatagramRtpTransport::DatagramRtpTransport( + const std::vector& rtp_header_extensions, + cricket::IceTransportInternal* ice_transport, + DatagramTransportInterface* datagram_transport) + : ice_transport_(ice_transport), + datagram_transport_(datagram_transport), + disable_datagram_to_rtcp_feeback_translation_(field_trial::IsEnabled( + kDisableDatagramToRtcpFeebackTranslationFieldTrial)) { + // Save extension map for parsing RTP packets (we only need transport + // sequence numbers). + const RtpExtension* transport_sequence_number_extension = + RtpExtension::FindHeaderExtensionByUri(rtp_header_extensions, + TransportSequenceNumber::kUri); + + if (transport_sequence_number_extension != nullptr) { + rtp_header_extension_map_.Register( + transport_sequence_number_extension->id); + } else { + RTC_LOG(LS_ERROR) << "Transport sequence numbers are not supported in " + "datagram transport connection"; + } + + // TODO(sukhanov): Add CHECK to make sure that field trial + // WebRTC-ExcludeTransportSequenceNumberFromFecFieldTrial is enabled. + // If feedback loop is translation is enabled, FEC packets must exclude + // transport sequence numbers, otherwise recovered packets will be corrupt. + + RTC_DCHECK(ice_transport_); + RTC_DCHECK(datagram_transport_); + + ice_transport_->SignalNetworkRouteChanged.connect( + this, &DatagramRtpTransport::OnNetworkRouteChanged); + // Subscribe to DatagramTransport to read incoming packets. + datagram_transport_->SetDatagramSink(this); + datagram_transport_->SetTransportStateCallback(this); +} + +DatagramRtpTransport::~DatagramRtpTransport() { + // Unsubscribe from DatagramTransport sinks. + datagram_transport_->SetDatagramSink(nullptr); + datagram_transport_->SetTransportStateCallback(nullptr); +} + +bool DatagramRtpTransport::SendRtpPacket(rtc::CopyOnWriteBuffer* packet, + const rtc::PacketOptions& options, + int flags) { + RTC_DCHECK_RUN_ON(&thread_checker_); + + // Assign and increment datagram_id. + const DatagramId datagram_id = current_datagram_id_++; + + // Send as is (without extracting transport sequence number) for + // RTP packets if we are not doing datagram => RTCP feedback translation. + if (disable_datagram_to_rtcp_feeback_translation_) { + // Even if we are not extracting transport sequence number we need to + // propagate "Sent" notification for both RTP and RTCP packets. For this + // reason we need save options.packet_id in packet map. + sent_rtp_packet_map_[datagram_id] = SentPacketInfo(options.packet_id); + + return SendDatagram(*packet, datagram_id); + } + + // Parse RTP packet. + RtpPacket rtp_packet(&rtp_header_extension_map_); + // TODO(mellem): Verify that this doesn't mangle something (it shouldn't). + if (!rtp_packet.Parse(*packet)) { + RTC_NOTREACHED() << "Failed to parse outgoing RtpPacket, len=" + << packet->size() + << ", options.packet_id=" << options.packet_id; + return -1; + } + + // Try to get transport sequence number. + uint16_t transport_senquence_number; + if (!rtp_packet.GetExtension( + &transport_senquence_number)) { + // Save packet info without transport sequence number. + sent_rtp_packet_map_[datagram_id] = SentPacketInfo(options.packet_id); + + RTC_LOG(LS_VERBOSE) + << "Sending rtp packet without transport sequence number, packet=" + << rtp_packet.ToString(); + + return SendDatagram(*packet, datagram_id); + } + + // Save packet info with sequence number and ssrc so we could reconstruct + // RTCP feedback packet when we receive datagram ACK. + sent_rtp_packet_map_[datagram_id] = SentPacketInfo( + options.packet_id, rtp_packet.Ssrc(), transport_senquence_number); + + // Since datagram transport provides feedback and timestamps, we do not need + // to send transport sequence number, so we remove it from RTP packet. Later + // when we get Ack for sent datagram, we will re-create RTCP feedback packet. + if (!rtp_packet.RemoveExtension(TransportSequenceNumber::kId)) { + RTC_NOTREACHED() << "Failed to remove transport sequence number, packet=" + << rtp_packet.ToString(); + return -1; + } + + RTC_LOG(LS_VERBOSE) << "Removed transport_senquence_number=" + << transport_senquence_number + << " from packet=" << rtp_packet.ToString() + << ", saved bytes=" << packet->size() - rtp_packet.size(); + + return SendDatagram( + rtc::ArrayView(rtp_packet.data(), rtp_packet.size()), + datagram_id); +} + +bool DatagramRtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet, + const rtc::PacketOptions& options, + int flags) { + RTC_DCHECK_RUN_ON(&thread_checker_); + + // Assign and increment datagram_id. + const DatagramId datagram_id = current_datagram_id_++; + + // Even if we are not extracting transport sequence number we need to + // propagate "Sent" notification for both RTP and RTCP packets. For this + // reason we need save options.packet_id in packet map. + sent_rtp_packet_map_[datagram_id] = SentPacketInfo(options.packet_id); + return SendDatagram(*packet, datagram_id); +} + +bool DatagramRtpTransport::SendDatagram(rtc::ArrayView data, + DatagramId datagram_id) { + return datagram_transport_->SendDatagram(data, datagram_id).ok(); +} + +void DatagramRtpTransport::OnDatagramReceived( + rtc::ArrayView data) { + RTC_DCHECK_RUN_ON(&thread_checker_); + + rtc::ArrayView cdata(reinterpret_cast(data.data()), + data.size()); + if (cricket::InferRtpPacketType(cdata) == cricket::RtpPacketType::kRtcp) { + rtc::CopyOnWriteBuffer buffer(data.data(), data.size()); + SignalRtcpPacketReceived(&buffer, /*packet_time_us=*/-1); + return; + } + + // TODO(sukhanov): I am not filling out time, but on my video quality + // test in WebRTC the time was not set either and higher layers of the stack + // overwrite -1 with current current rtc time. Leaveing comment for now to + // make sure it works as expected. + RtpPacketReceived parsed_packet(&rtp_header_extension_map_); + if (!parsed_packet.Parse(data)) { + RTC_LOG(LS_ERROR) << "Failed to parse incoming RTP packet"; + return; + } + if (!rtp_demuxer_.OnRtpPacket(parsed_packet)) { + RTC_LOG(LS_WARNING) << "Failed to demux RTP packet: " + << RtpDemuxer::DescribePacket(parsed_packet); + } +} + +void DatagramRtpTransport::OnDatagramSent(DatagramId datagram_id) { + RTC_DCHECK_RUN_ON(&thread_checker_); + + // Find packet_id and propagate OnPacketSent notification. + const auto& it = sent_rtp_packet_map_.find(datagram_id); + if (it == sent_rtp_packet_map_.end()) { + RTC_NOTREACHED() << "Did not find sent packet info for sent datagram_id=" + << datagram_id; + return; + } + + // Also see how DatagramRtpTransport::OnSentPacket handles OnSentPacket + // notification from ICE in bypass mode. + rtc::SentPacket sent_packet(/*packet_id=*/it->second.packet_id, + rtc::TimeMillis()); + + SignalSentPacket(sent_packet); +} + +bool DatagramRtpTransport::GetAndRemoveSentPacketInfo( + DatagramId datagram_id, + SentPacketInfo* sent_packet_info) { + RTC_CHECK(sent_packet_info != nullptr); + + const auto& it = sent_rtp_packet_map_.find(datagram_id); + if (it == sent_rtp_packet_map_.end()) { + return false; + } + + *sent_packet_info = it->second; + sent_rtp_packet_map_.erase(it); + return true; +} + +void DatagramRtpTransport::OnDatagramAcked(const DatagramAck& ack) { + RTC_DCHECK_RUN_ON(&thread_checker_); + + SentPacketInfo sent_packet_info; + if (!GetAndRemoveSentPacketInfo(ack.datagram_id, &sent_packet_info)) { + // TODO(sukhanov): If OnDatagramAck() can come after OnDatagramLost(), + // datagram_id is already deleted and we may need to relax the CHECK below. + // It's probably OK to ignore such datagrams, because it's been a few RTTs + // anyway since they were sent. + RTC_NOTREACHED() << "Did not find sent packet info for datagram_id=" + << ack.datagram_id; + return; + } + + RTC_LOG(LS_VERBOSE) << "Datagram acked, ack.datagram_id=" << ack.datagram_id + << ", sent_packet_info.packet_id=" + << sent_packet_info.packet_id + << ", sent_packet_info.transport_sequence_number=" + << sent_packet_info.transport_sequence_number.value_or(-1) + << ", sent_packet_info.ssrc=" + << sent_packet_info.ssrc.value_or(-1) + << ", receive_timestamp_ms=" + << ack.receive_timestamp.ms(); + + // If transport sequence number was not present in RTP packet, we do not need + // to propagate RTCP feedback. + if (!sent_packet_info.transport_sequence_number) { + return; + } + + // TODO(sukhanov): We noticed that datagram transport implementations can + // return zero timestamps in the middle of the call. This is workaround to + // avoid propagating zero timestamps, but we need to understand why we have + // them in the first place. + int64_t receive_timestamp_us = ack.receive_timestamp.us(); + + if (receive_timestamp_us == 0) { + receive_timestamp_us = previous_nonzero_timestamp_us_; + } else { + previous_nonzero_timestamp_us_ = receive_timestamp_us; + } + + // Ssrc must be provided in packet info if transport sequence number is set, + // which is guaranteed by SentPacketInfo constructor. + RTC_CHECK(sent_packet_info.ssrc); + + // Recreate RTCP feedback packet. + rtcp::TransportFeedback feedback_packet; + feedback_packet.SetMediaSsrc(*sent_packet_info.ssrc); + + const uint16_t transport_sequence_number = + sent_packet_info.transport_sequence_number.value(); + + feedback_packet.SetBase(transport_sequence_number, receive_timestamp_us); + feedback_packet.AddReceivedPacket(transport_sequence_number, + receive_timestamp_us); + + rtc::CopyOnWriteBuffer buffer(kMaxRtcpFeedbackPacketSize); + size_t index = 0; + if (!feedback_packet.Create(buffer.data(), &index, buffer.capacity(), + nullptr)) { + RTC_NOTREACHED() << "Failed to create RTCP feedback packet"; + return; + } + + RTC_CHECK_GT(index, 0); + RTC_CHECK_LE(index, kMaxRtcpFeedbackPacketSize); + + // Propagage created RTCP packet as normal incoming packet. + buffer.SetSize(index); + SignalRtcpPacketReceived(&buffer, /*packet_time_us=*/-1); +} + +void DatagramRtpTransport::OnDatagramLost(DatagramId datagram_id) { + RTC_DCHECK_RUN_ON(&thread_checker_); + + RTC_LOG(LS_INFO) << "Datagram lost, datagram_id=" << datagram_id; + + SentPacketInfo sent_packet_info; + if (!GetAndRemoveSentPacketInfo(datagram_id, &sent_packet_info)) { + RTC_NOTREACHED() << "Did not find sent packet info for lost datagram_id=" + << datagram_id; + } +} + +void DatagramRtpTransport::OnStateChanged(MediaTransportState state) { + state_ = state; + SignalWritableState(state_ == MediaTransportState::kWritable); + if (state_ == MediaTransportState::kWritable) { + SignalReadyToSend(true); + } +} + +const std::string& DatagramRtpTransport::transport_name() const { + return ice_transport_->transport_name(); +} + +int DatagramRtpTransport::SetRtpOption(rtc::Socket::Option opt, int value) { + return ice_transport_->SetOption(opt, value); +} + +int DatagramRtpTransport::SetRtcpOption(rtc::Socket::Option opt, int value) { + return -1; +} + +bool DatagramRtpTransport::IsReadyToSend() const { + return state_ == MediaTransportState::kWritable; +} + +bool DatagramRtpTransport::IsWritable(bool /*rtcp*/) const { + return state_ == MediaTransportState::kWritable; +} + +void DatagramRtpTransport::UpdateRtpHeaderExtensionMap( + const cricket::RtpHeaderExtensions& header_extensions) { + rtp_header_extension_map_ = RtpHeaderExtensionMap(header_extensions); +} + +bool DatagramRtpTransport::RegisterRtpDemuxerSink( + const RtpDemuxerCriteria& criteria, + RtpPacketSinkInterface* sink) { + rtp_demuxer_.RemoveSink(sink); + return rtp_demuxer_.AddSink(criteria, sink); +} + +bool DatagramRtpTransport::UnregisterRtpDemuxerSink( + RtpPacketSinkInterface* sink) { + return rtp_demuxer_.RemoveSink(sink); +} + +void DatagramRtpTransport::OnNetworkRouteChanged( + absl::optional network_route) { + RTC_DCHECK_RUN_ON(&thread_checker_); + SignalNetworkRouteChanged(network_route); +} + +} // namespace webrtc diff --git a/pc/datagram_dtls_adaptor.h b/pc/datagram_rtp_transport.h similarity index 51% rename from pc/datagram_dtls_adaptor.h rename to pc/datagram_rtp_transport.h index 7ebd15bca1..1dfa37b77c 100644 --- a/pc/datagram_dtls_adaptor.h +++ b/pc/datagram_rtp_transport.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef PC_DATAGRAM_DTLS_ADAPTOR_H_ -#define PC_DATAGRAM_DTLS_ADAPTOR_H_ +#ifndef PC_DATAGRAM_RTP_TRANSPORT_H_ +#define PC_DATAGRAM_RTP_TRANSPORT_H_ #include #include @@ -20,9 +20,9 @@ #include "api/datagram_transport_interface.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" -#include "p2p/base/dtls_transport_internal.h" #include "p2p/base/ice_transport_internal.h" #include "p2p/base/packet_transport_internal.h" +#include "pc/rtp_transport_internal.h" #include "rtc_base/buffer.h" #include "rtc_base/buffer_queue.h" #include "rtc_base/constructor_magic.h" @@ -31,31 +31,22 @@ #include "rtc_base/strings/string_builder.h" #include "rtc_base/thread_checker.h" -namespace cricket { +namespace webrtc { constexpr int kDatagramDtlsAdaptorComponent = -1; -// DTLS wrapper around DatagramTransportInterface. -// Does not encrypt. -// Owns Datagram and Ice transports. -class DatagramDtlsAdaptor : public DtlsTransportInternal, - public webrtc::DatagramSinkInterface, - public webrtc::MediaTransportStateCallback { +// RTP transport which uses the DatagramTransportInterface to send and receive +// packets. +class DatagramRtpTransport : public RtpTransportInternal, + public webrtc::DatagramSinkInterface, + public webrtc::MediaTransportStateCallback { public: - // TODO(sukhanov): Taking crypto options, because DtlsTransportInternal - // has a virtual getter crypto_options(). Consider removing getter and - // removing crypto_options from DatagramDtlsAdaptor. - DatagramDtlsAdaptor( + DatagramRtpTransport( const std::vector& rtp_header_extensions, - IceTransportInternal* ice_transport, - webrtc::DatagramTransportInterface* datagram_transport, - const webrtc::CryptoOptions& crypto_options, - webrtc::RtcEventLog* event_log); + cricket::IceTransportInternal* ice_transport, + DatagramTransportInterface* datagram_transport); - ~DatagramDtlsAdaptor() override; - - // Connects to ICE transport callbacks. - void ConnectToIceTransport(); + ~DatagramRtpTransport() override; // ===================================================== // Overrides for webrtc::DatagramTransportSinkInterface @@ -72,35 +63,38 @@ class DatagramDtlsAdaptor : public DtlsTransportInternal, void OnStateChanged(webrtc::MediaTransportState state) override; // ===================================================== - // DtlsTransportInternal overrides + // RtpTransportInternal overrides // ===================================================== - const webrtc::CryptoOptions& crypto_options() const override; - DtlsTransportState dtls_state() const override; - int component() const override; - bool IsDtlsActive() const override; - bool GetDtlsRole(rtc::SSLRole* role) const override; - bool SetDtlsRole(rtc::SSLRole role) override; - bool GetSrtpCryptoSuite(int* cipher) override; - bool GetSslCipherSuite(int* cipher) override; - rtc::scoped_refptr GetLocalCertificate() const override; - bool SetLocalCertificate( - const rtc::scoped_refptr& certificate) override; - std::unique_ptr GetRemoteSSLCertChain() const override; - bool ExportKeyingMaterial(const std::string& label, - const uint8_t* context, - size_t context_len, - bool use_context, - uint8_t* result, - size_t result_len) override; - bool SetRemoteFingerprint(const std::string& digest_alg, - const uint8_t* digest, - size_t digest_len) override; - bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override; - IceTransportInternal* ice_transport() override; + bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet, + const rtc::PacketOptions& options, + int flags) override; + + bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet, + const rtc::PacketOptions& options, + int flags) override; const std::string& transport_name() const override; - bool writable() const override; - bool receiving() const override; + + // Datagram transport always muxes RTCP. + bool rtcp_mux_enabled() const override { return true; } + void SetRtcpMuxEnabled(bool enable) override {} + + int SetRtpOption(rtc::Socket::Option opt, int value) override; + int SetRtcpOption(rtc::Socket::Option opt, int value) override; + + bool IsReadyToSend() const override; + + bool IsWritable(bool rtcp) const override; + + bool IsSrtpActive() const override { return false; } + + void UpdateRtpHeaderExtensionMap( + const cricket::RtpHeaderExtensions& header_extensions) override; + + bool RegisterRtpDemuxerSink(const RtpDemuxerCriteria& criteria, + RtpPacketSinkInterface* sink) override; + + bool UnregisterRtpDemuxerSink(RtpPacketSinkInterface* sink) override; private: // RTP/RTCP packet info stored for each sent packet. @@ -137,60 +131,19 @@ class DatagramDtlsAdaptor : public DtlsTransportInternal, SentPacketInfo* sent_packet_info); // Sends datagram to datagram_transport. - int SendDatagram(rtc::ArrayView data, - webrtc::DatagramId datagram_id); + bool SendDatagram(rtc::ArrayView data, + webrtc::DatagramId datagram_id); - void set_receiving(bool receiving); - void set_writable(bool writable); - void set_dtls_state(DtlsTransportState state); - - // Forwards incoming packet up the stack. - void PropagateReadPacket(rtc::ArrayView data, - const int64_t& packet_time_us); - - // Signals SentPacket notification. - void PropagateOnSentNotification(const rtc::SentPacket& sent_packet); - - // Listens to read packet notifications from ICE (only used in bypass mode). - void OnReadPacket(rtc::PacketTransportInternal* transport, - const char* data, - size_t size, - const int64_t& packet_time_us, - int flags); - - void OnReadyToSend(rtc::PacketTransportInternal* transport); - void OnWritableState(rtc::PacketTransportInternal* transport); + // Propagates network route changes from ICE. void OnNetworkRouteChanged(absl::optional network_route); - void OnReceivingState(rtc::PacketTransportInternal* transport); - - int SendPacket(const char* data, - size_t len, - const rtc::PacketOptions& options, - int flags) override; - int SetOption(rtc::Socket::Option opt, int value) override; - int GetError() override; - void OnSentPacket(rtc::PacketTransportInternal* transport, - const rtc::SentPacket& sent_packet); rtc::ThreadChecker thread_checker_; - webrtc::CryptoOptions crypto_options_; - IceTransportInternal* ice_transport_; - + cricket::IceTransportInternal* ice_transport_; webrtc::DatagramTransportInterface* datagram_transport_; - // Current ICE writable state. Must be modified by calling set_ice_writable(), - // which propagates change notifications. - bool writable_ = false; + RtpDemuxer rtp_demuxer_; - // Current receiving state. Must be modified by calling set_receiving(), which - // propagates change notifications. - bool receiving_ = false; - - // Current DTLS state. Must be modified by calling set_dtls_state(), which - // propagates change notifications. - DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW; - - webrtc::RtcEventLog* const event_log_; + MediaTransportState state_ = MediaTransportState::kPending; // Extension map for parsing transport sequence numbers. webrtc::RtpHeaderExtensionMap rtp_header_extension_map_; @@ -214,6 +167,6 @@ class DatagramDtlsAdaptor : public DtlsTransportInternal, const bool disable_datagram_to_rtcp_feeback_translation_; }; -} // namespace cricket +} // namespace webrtc -#endif // PC_DATAGRAM_DTLS_ADAPTOR_H_ +#endif // PC_DATAGRAM_RTP_TRANSPORT_H_ diff --git a/pc/jsep_transport.cc b/pc/jsep_transport.cc index e32f279de2..e710f09fa9 100644 --- a/pc/jsep_transport.cc +++ b/pc/jsep_transport.cc @@ -99,10 +99,9 @@ JsepTransport::JsepTransport( std::unique_ptr unencrypted_rtp_transport, std::unique_ptr sdes_transport, std::unique_ptr dtls_srtp_transport, - std::unique_ptr datagram_rtp_transport, + std::unique_ptr datagram_rtp_transport, std::unique_ptr rtp_dtls_transport, std::unique_ptr rtcp_dtls_transport, - std::unique_ptr datagram_dtls_transport, std::unique_ptr media_transport, std::unique_ptr datagram_transport) : network_thread_(rtc::Thread::Current()), @@ -123,11 +122,6 @@ JsepTransport::JsepTransport( ? new rtc::RefCountedObject( std::move(rtcp_dtls_transport)) : nullptr), - datagram_dtls_transport_( - datagram_dtls_transport - ? new rtc::RefCountedObject( - std::move(datagram_dtls_transport)) - : nullptr), media_transport_(std::move(media_transport)), datagram_transport_(std::move(datagram_transport)) { RTC_DCHECK(ice_transport_); @@ -176,13 +170,8 @@ JsepTransport::~JsepTransport() { rtcp_dtls_transport_->Clear(); } - // Datagram dtls transport must be disconnected before the datagram transport - // is released. - if (datagram_dtls_transport_) { - datagram_dtls_transport_->Clear(); - } - - // Delete datagram transport before ICE, but after DTLS transport. + // Delete datagram transport before ICE, but after its RTP transport. + datagram_rtp_transport_.reset(); datagram_transport_.reset(); // ICE will be the last transport to be deleted. @@ -533,9 +522,6 @@ void JsepTransport::ActivateRtcpMux() { } { rtc::CritScope scope(&accessor_lock_); - if (datagram_rtp_transport_) { - datagram_rtp_transport_->SetRtcpPacketTransport(nullptr); - } if (unencrypted_rtp_transport_) { RTC_DCHECK(!sdes_transport_); RTC_DCHECK(!dtls_srtp_transport_); @@ -822,9 +808,6 @@ void JsepTransport::NegotiateRtpTransport(SdpType type) { RTC_LOG(INFO) << "Datagram transport rejected"; composite_rtp_transport_->RemoveTransport(datagram_rtp_transport_.get()); datagram_rtp_transport_ = nullptr; - // This one is ref-counted, so it can't be deleted directly. - datagram_dtls_transport_->Clear(); - datagram_dtls_transport_ = nullptr; datagram_transport_ = nullptr; } } diff --git a/pc/jsep_transport.h b/pc/jsep_transport.h index 479c0ae6af..59b227606b 100644 --- a/pc/jsep_transport.h +++ b/pc/jsep_transport.h @@ -93,10 +93,9 @@ class JsepTransport : public sigslot::has_slots<>, std::unique_ptr unencrypted_rtp_transport, std::unique_ptr sdes_transport, std::unique_ptr dtls_srtp_transport, - std::unique_ptr datagram_rtp_transport, + std::unique_ptr datagram_rtp_transport, std::unique_ptr rtp_dtls_transport, std::unique_ptr rtcp_dtls_transport, - std::unique_ptr datagram_dtls_transport, std::unique_ptr media_transport, std::unique_ptr datagram_transport); @@ -349,7 +348,7 @@ class JsepTransport : public sigslot::has_slots<>, RTC_GUARDED_BY(accessor_lock_); std::unique_ptr dtls_srtp_transport_ RTC_GUARDED_BY(accessor_lock_); - std::unique_ptr datagram_rtp_transport_ + std::unique_ptr datagram_rtp_transport_ RTC_GUARDED_BY(accessor_lock_); // If multiple RTP transports are in use, |composite_rtp_transport_| will be diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc index 980deb690b..ea14523ddb 100644 --- a/pc/jsep_transport_controller.cc +++ b/pc/jsep_transport_controller.cc @@ -20,7 +20,7 @@ #include "p2p/base/ice_transport_internal.h" #include "p2p/base/no_op_dtls_transport.h" #include "p2p/base/port.h" -#include "pc/datagram_dtls_adaptor.h" +#include "pc/datagram_rtp_transport.h" #include "pc/srtp_filter.h" #include "rtc_base/bind.h" #include "rtc_base/checks.h" @@ -483,11 +483,6 @@ JsepTransportController::CreateDtlsTransport( if (datagram_transport) { RTC_DCHECK(config_.use_datagram_transport); - - // Create DTLS wrapper around DatagramTransportInterface. - dtls = absl::make_unique( - content_info.media_description()->rtp_header_extensions(), ice, - datagram_transport, config_.crypto_options, config_.event_log); } else if (config_.media_transport_factory && config_.use_media_transport_for_media && config_.use_media_transport_for_data_channels) { @@ -1164,11 +1159,8 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( std::unique_ptr datagram_transport = MaybeCreateDatagramTransport(content_info, description, local); - std::unique_ptr datagram_dtls_transport; if (datagram_transport) { datagram_transport->Connect(ice.get()); - datagram_dtls_transport = - CreateDtlsTransport(content_info, ice.get(), datagram_transport.get()); } std::unique_ptr rtp_dtls_transport = @@ -1178,7 +1170,7 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( std::unique_ptr unencrypted_rtp_transport; std::unique_ptr sdes_transport; std::unique_ptr dtls_srtp_transport; - std::unique_ptr datagram_rtp_transport; + std::unique_ptr datagram_rtp_transport; std::unique_ptr rtcp_ice; if (config_.rtcp_mux_policy != @@ -1202,8 +1194,9 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( RTC_LOG(LS_INFO) << "Creating UnencryptedRtpTransport, because datagram " "transport is used."; RTC_DCHECK(!rtcp_dtls_transport); - datagram_rtp_transport = CreateUnencryptedRtpTransport( - content_info.name, datagram_dtls_transport.get(), nullptr); + datagram_rtp_transport = absl::make_unique( + content_info.media_description()->rtp_header_extensions(), ice.get(), + datagram_transport.get()); } if (config_.disable_encryption) { @@ -1227,8 +1220,7 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( std::move(unencrypted_rtp_transport), std::move(sdes_transport), std::move(dtls_srtp_transport), std::move(datagram_rtp_transport), std::move(rtp_dtls_transport), std::move(rtcp_dtls_transport), - std::move(datagram_dtls_transport), std::move(media_transport), - std::move(datagram_transport)); + std::move(media_transport), std::move(datagram_transport)); jsep_transport->SignalRtcpMuxActive.connect( this, &JsepTransportController::UpdateAggregateStates_n); diff --git a/pc/jsep_transport_unittest.cc b/pc/jsep_transport_unittest.cc index 068002749b..1e51392f08 100644 --- a/pc/jsep_transport_unittest.cc +++ b/pc/jsep_transport_unittest.cc @@ -111,7 +111,6 @@ class JsepTransport2Test : public ::testing::Test, public sigslot::has_slots<> { std::move(sdes_transport), std::move(dtls_srtp_transport), /*datagram_rtp_transport=*/nullptr, std::move(rtp_dtls_transport), std::move(rtcp_dtls_transport), - /*datagram_dtls_transport=*/nullptr, /*media_transport=*/nullptr, /*datagram_transport=*/nullptr);