Reland "Move piggybacking controller from P2PTC to DTLS transport"
This reverts commit 4de5839c1117e5bb96148c8575a74a69bde02768.
Reason for revert: Bug fixed + DCHECK added
Original change's description:
> Revert "Move piggybacking controller from P2PTC to DTLS transport"
>
> This reverts commit 29e639e0a495a537c610182ab9b04aed8cf10426.
>
> Reason for revert: found bug accessing variable after it has been moved.
>
> Original change's description:
> > Move piggybacking controller from P2PTC to DTLS transport
> >
> > The DTLS-STUN piggybacking controller is associated with both the DTLS
> > transport and the ICE transport (P2PTransportChannel). It turned out to
> > be more closely associated with the DTLS transport and requires less
> > plumbing when moved there.
> >
> > The config option to enable the feature remains as part of the ICE
> > transport config since the ICE transport does not know its "upstream"
> > DTLS transport and hence can not query the config from it.
> >
> > BUG=webrtc:367395350
> >
> > Change-Id: Iafd5abd8b65855bcf32bf840414d96513d8e6300
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/375283
> > Reviewed-by: Jonas Oreland <jonaso@webrtc.org>
> > Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
> > Cr-Commit-Position: refs/heads/main@{#43823}
>
> Bug: webrtc:367395350
> Change-Id: I2d83de8890b0aa230dd9e21cb5ce2eb03c8d3564
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/375861
> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
> Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#43824}
Bug: webrtc:367395350
Change-Id: I4b4acccf15de565736b072ca2de88a1551a6378e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/375862
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43825}
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index 760b602..7708f72 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -245,6 +245,7 @@
"dtls/dtls_transport.h",
]
deps = [
+ ":dtls_stun_piggyback_controller",
":dtls_transport_internal",
":dtls_utils",
":ice_transport_internal",
@@ -256,6 +257,7 @@
"../api:sequence_checker",
"../api/crypto:options",
"../api/rtc_event_log",
+ "../api/transport:stun_types",
"../api/units:timestamp",
"../logging:ice_log",
"../rtc_base:async_packet_socket",
@@ -278,6 +280,7 @@
"../rtc_base/network:received_packet",
"../rtc_base/network:sent_packet",
"../rtc_base/system:no_unique_address",
+ "//third_party/abseil-cpp/absl/functional:any_invocable",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings:string_view",
]
@@ -383,6 +386,7 @@
"../api:field_trials_view",
"../api:rtc_error",
"../api/transport:enums",
+ "../api/transport:stun_types",
"../rtc_base:callback_list",
"../rtc_base:checks",
"../rtc_base:network_constants",
@@ -415,7 +419,6 @@
":candidate_pair_interface",
":connection",
":connection_info",
- ":dtls_stun_piggyback_controller",
":ice_agent_interface",
":ice_controller_factory_interface",
":ice_controller_interface",
@@ -467,6 +470,7 @@
"../system_wrappers:metrics",
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/functional:any_invocable",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
diff --git a/p2p/base/ice_transport_internal.h b/p2p/base/ice_transport_internal.h
index d2f32de..85f48aa 100644
--- a/p2p/base/ice_transport_internal.h
+++ b/p2p/base/ice_transport_internal.h
@@ -26,6 +26,7 @@
#include "api/field_trials_view.h"
#include "api/rtc_error.h"
#include "api/transport/enums.h"
+#include "api/transport/stun.h"
#include "p2p/base/candidate_pair_interface.h"
#include "p2p/base/connection.h"
#include "p2p/base/connection_info.h"
@@ -35,7 +36,6 @@
#include "p2p/base/transport_description.h"
#include "rtc_base/callback_list.h"
#include "rtc_base/checks.h"
-#include "rtc_base/network/received_packet.h"
#include "rtc_base/network_constants.h"
#include "rtc_base/system/rtc_export.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
@@ -403,15 +403,14 @@
virtual const webrtc::FieldTrialsView* field_trials() const {
return nullptr;
}
- void SetPiggybackDtlsDataCallback(
- absl::AnyInvocable<void(rtc::PacketTransportInternal* transport,
- const rtc::ReceivedPacket& packet)> callback) {
- RTC_DCHECK(callback == nullptr || !piggybacked_dtls_callback_);
- piggybacked_dtls_callback_ = std::move(callback);
- }
- virtual void SetDtlsDataToPiggyback(rtc::ArrayView<const uint8_t>) {}
- virtual void SetDtlsHandshakeComplete(bool is_dtls_client, bool is_dtls13) {}
- virtual bool IsDtlsPiggybackSupportedByPeer() { return false; }
+ virtual void SetDtlsPiggybackingCallbacks(
+ absl::AnyInvocable<std::optional<absl::string_view>(StunMessageType)>
+ dtls_piggyback_get_data,
+ absl::AnyInvocable<std::optional<absl::string_view>(StunMessageType)>
+ dtls_piggyback_get_ack,
+ absl::AnyInvocable<void(const StunByteStringAttribute*,
+ const StunByteStringAttribute*)>
+ dtls_piggyback_report_data) {}
protected:
void SendGatheringStateEvent() { gathering_state_callback_list_.Send(this); }
@@ -433,9 +432,6 @@
absl::AnyInvocable<void(const cricket::CandidatePairChangeEvent&)>
candidate_pair_change_callback_;
- absl::AnyInvocable<void(rtc::PacketTransportInternal*,
- const rtc::ReceivedPacket&)>
- piggybacked_dtls_callback_;
};
} // namespace cricket
diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index 5b0d48a..8c7d91a 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -26,6 +26,7 @@
#include <vector>
#include "absl/algorithm/container.h"
+#include "absl/functional/any_invocable.h"
#include "absl/memory/memory.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
@@ -200,16 +201,7 @@
true /* presume_writable_when_fully_relayed */,
REGATHER_ON_FAILED_NETWORKS_INTERVAL,
RECEIVING_SWITCHING_DELAY),
- field_trials_(field_trials),
- dtls_stun_piggyback_controller_(
- [this](rtc::ArrayView<const uint8_t> piggybacked_dtls_packet) {
- if (piggybacked_dtls_callback_ == nullptr) {
- return;
- }
- piggybacked_dtls_callback_(
- this, rtc::ReceivedPacket(piggybacked_dtls_packet,
- rtc::SocketAddress()));
- }) {
+ field_trials_(field_trials) {
TRACE_EVENT0("webrtc", "P2PTransportChannel::P2PTransportChannel");
RTC_DCHECK(allocator_ != nullptr);
// Validate IceConfig even for mostly built-in constant default values in case
@@ -322,16 +314,14 @@
if (config_.dtls_handshake_in_stun) {
connection->RegisterDtlsPiggyback(
[this](StunMessageType stun_message_type) {
- return dtls_stun_piggyback_controller_.GetDataToPiggyback(
- stun_message_type);
+ return dtls_piggyback_get_data_(stun_message_type);
},
[this](StunMessageType stun_message_type) {
- return dtls_stun_piggyback_controller_.GetAckToPiggyback(
- stun_message_type);
+ return dtls_piggyback_get_ack_(stun_message_type);
},
[this](const StunByteStringAttribute* data,
const StunByteStringAttribute* ack) {
- dtls_stun_piggyback_controller_.ReportDataPiggybacked(data, ack);
+ dtls_piggyback_report_data_(data, ack);
});
}
@@ -1634,15 +1624,6 @@
return -1;
}
- // If we try to use DTLS-in-STUN, DTLS packets will be sent as part of STUN
- // packets and are consumed here.
- rtc::ArrayView<const uint8_t> data_view =
- rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), len);
- if (config_.dtls_handshake_in_stun &&
- dtls_stun_piggyback_controller_.MaybeConsumePacket(data_view)) {
- return len;
- }
-
// If we don't think the connection is working yet, return ENOTCONN
// instead of sending a packet that will probably be dropped.
if (!ReadyToSend(selected_connection_)) {
@@ -2314,9 +2295,11 @@
}
SignalWritableState(this);
- if (config_.dtls_handshake_in_stun && IsDtlsPiggybackSupportedByPeer()) {
+ if (config_.dtls_handshake_in_stun &&
+ dtls_piggyback_report_data_ != nullptr) {
// Need to STUN ping here to get the last bit of the DTLS handshake across
- // as quickly as possible.
+ // as quickly as possible. Only done when DTLS-in-STUN is configured
+ // and the data callback has not been reset due to lack of support.
SendPingRequestInternal(selected_connection_);
}
}
@@ -2391,4 +2374,36 @@
}
}
+void P2PTransportChannel::SetDtlsPiggybackingCallbacks(
+ absl::AnyInvocable<std::optional<absl::string_view>(StunMessageType)>
+ dtls_piggyback_get_data,
+ absl::AnyInvocable<std::optional<absl::string_view>(StunMessageType)>
+ dtls_piggyback_get_ack,
+ absl::AnyInvocable<void(const StunByteStringAttribute*,
+ const StunByteStringAttribute*)>
+ dtls_piggyback_report_data) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ dtls_piggyback_get_data_ = std::move(dtls_piggyback_get_data);
+ dtls_piggyback_get_ack_ = std::move(dtls_piggyback_get_ack);
+ dtls_piggyback_report_data_ = std::move(dtls_piggyback_report_data);
+
+ RTC_DCHECK( // either all set
+ (dtls_piggyback_get_data_ != nullptr &&
+ dtls_piggyback_get_ack_ != nullptr &&
+ dtls_piggyback_report_data_ != nullptr) ||
+ // or all nullptr
+ (dtls_piggyback_get_data_ == nullptr &&
+ dtls_piggyback_get_ack_ == nullptr &&
+ dtls_piggyback_report_data_ == nullptr));
+
+ if (dtls_piggyback_get_data_ == nullptr &&
+ dtls_piggyback_get_ack_ == nullptr &&
+ dtls_piggyback_report_data_ == nullptr) {
+ // Iterate over connections, deregister.
+ for (auto& connection : connections_) {
+ connection->DeregisterDtlsPiggyback();
+ }
+ }
+}
+
} // namespace cricket
diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h
index 7367391..0e39a82 100644
--- a/p2p/base/p2p_transport_channel.h
+++ b/p2p/base/p2p_transport_channel.h
@@ -30,6 +30,7 @@
#include <string>
#include <vector>
+#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/async_dns_resolver.h"
@@ -58,7 +59,6 @@
#include "p2p/base/regathering_controller.h"
#include "p2p/base/stun_dictionary.h"
#include "p2p/base/transport_description.h"
-#include "p2p/dtls/dtls_stun_piggyback_controller.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/checks.h"
#include "rtc_base/dscp.h"
@@ -252,27 +252,14 @@
const webrtc::FieldTrialsView* field_trials() const override {
return field_trials_;
}
-
- void SetDtlsHandshakeComplete(bool is_dtls_client, bool is_dtls13) override {
- dtls_stun_piggyback_controller_.SetDtlsHandshakeComplete(is_dtls_client,
- is_dtls13);
- }
-
- bool IsDtlsPiggybackSupportedByPeer() override {
- RTC_DCHECK_RUN_ON(network_thread_);
- return config_.dtls_handshake_in_stun &&
- dtls_stun_piggyback_controller_.state() !=
- DtlsStunPiggybackController::State::OFF;
- }
-
- bool IsDtlsPiggybackHandshaking() {
- RTC_DCHECK_RUN_ON(network_thread_);
- return config_.dtls_handshake_in_stun &&
- (dtls_stun_piggyback_controller_.state() ==
- DtlsStunPiggybackController::State::TENTATIVE ||
- dtls_stun_piggyback_controller_.state() ==
- DtlsStunPiggybackController::State::CONFIRMED);
- }
+ void SetDtlsPiggybackingCallbacks(
+ absl::AnyInvocable<std::optional<absl::string_view>(StunMessageType)>
+ dtls_piggyback_get_data,
+ absl::AnyInvocable<std::optional<absl::string_view>(StunMessageType)>
+ dtls_piggyback_get_ack,
+ absl::AnyInvocable<void(const StunByteStringAttribute*,
+ const StunByteStringAttribute*)>
+ dtls_piggyback_report_data) override;
private:
P2PTransportChannel(
@@ -538,8 +525,14 @@
// A dictionary that tracks attributes from peer.
StunDictionaryView stun_dict_view_;
- // A controller for piggybacking DTLS in STUN.
- DtlsStunPiggybackController dtls_stun_piggyback_controller_;
+ // DTLS-STUN piggybacking callbacks.
+ absl::AnyInvocable<std::optional<absl::string_view>(StunMessageType)>
+ dtls_piggyback_get_data_;
+ absl::AnyInvocable<std::optional<absl::string_view>(StunMessageType)>
+ dtls_piggyback_get_ack_;
+ absl::AnyInvocable<void(const StunByteStringAttribute*,
+ const StunByteStringAttribute*)>
+ dtls_piggyback_report_data_;
};
} // namespace cricket
diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc
index 22feecc..548961b 100644
--- a/p2p/base/p2p_transport_channel_unittest.cc
+++ b/p2p/base/p2p_transport_channel_unittest.cc
@@ -7441,66 +7441,4 @@
DestroyChannels();
}
-class P2PTransportChannelTestDtlsInStun : public P2PTransportChannelTestBase {
- public:
- P2PTransportChannelTestDtlsInStun() : P2PTransportChannelTestBase() {}
-
- protected:
- void Run(bool ep1_support, bool ep2_support) {
- IceConfig ep1_config;
- ep1_config.dtls_handshake_in_stun = ep1_support;
- IceConfig ep2_config;
- ep2_config.dtls_handshake_in_stun = ep2_support;
- CreateChannels(ep1_config, ep2_config);
- // DTLS server hello done message as test data.
- std::vector<uint8_t> dtls_data = {
- 0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- if (ep1_support) {
- ep1_ch1()->SetDtlsDataToPiggyback(dtls_data);
- }
- if (ep2_support) {
- ep2_ch1()->SetDtlsDataToPiggyback(dtls_data);
- }
- EXPECT_THAT(
- webrtc::WaitUntil(
- [&] { return CheckConnected(ep1_ch1(), ep2_ch1()); }, IsTrue(),
- {.timeout = webrtc::TimeDelta::Millis(kDefaultTimeout),
- .clock = &clock_}),
- webrtc::IsRtcOk());
- }
-
- rtc::ScopedFakeClock clock_;
-};
-
-TEST_F(P2PTransportChannelTestDtlsInStun, NotSupportedByEither) {
- Run(false, false);
- EXPECT_FALSE(ep1_ch1()->IsDtlsPiggybackSupportedByPeer());
- EXPECT_FALSE(ep2_ch1()->IsDtlsPiggybackSupportedByPeer());
- DestroyChannels();
-}
-
-TEST_F(P2PTransportChannelTestDtlsInStun, SupportedByClient) {
- Run(true, false);
- EXPECT_FALSE(ep1_ch1()->IsDtlsPiggybackSupportedByPeer());
- EXPECT_FALSE(ep2_ch1()->IsDtlsPiggybackSupportedByPeer());
- DestroyChannels();
-}
-
-TEST_F(P2PTransportChannelTestDtlsInStun, SupportedByServer) {
- Run(false, true);
- EXPECT_FALSE(ep1_ch1()->IsDtlsPiggybackSupportedByPeer());
- EXPECT_FALSE(ep2_ch1()->IsDtlsPiggybackSupportedByPeer());
- DestroyChannels();
-}
-
-TEST_F(P2PTransportChannelTestDtlsInStun, SupportedByBoth) {
- Run(true, true);
- EXPECT_TRUE(ep1_ch1()->IsDtlsPiggybackSupportedByPeer());
- EXPECT_TRUE(ep2_ch1()->IsDtlsPiggybackSupportedByPeer());
- DestroyChannels();
-}
-
} // namespace cricket
diff --git a/p2p/dtls/dtls_ice_integrationtest.cc b/p2p/dtls/dtls_ice_integrationtest.cc
index 21145ee..15aff16 100644
--- a/p2p/dtls/dtls_ice_integrationtest.cc
+++ b/p2p/dtls/dtls_ice_integrationtest.cc
@@ -184,9 +184,9 @@
{.timeout = webrtc::TimeDelta::Millis(kDefaultTimeout),
.clock = &fake_clock_}),
webrtc::IsRtcOk());
- EXPECT_EQ(client_ice_->IsDtlsPiggybackSupportedByPeer(),
+ EXPECT_EQ(client_dtls_.IsDtlsPiggybackSupportedByPeer(),
client_dtls_stun_piggyback_ && server_dtls_stun_piggyback_);
- EXPECT_EQ(server_ice_->IsDtlsPiggybackSupportedByPeer(),
+ EXPECT_EQ(server_dtls_.IsDtlsPiggybackSupportedByPeer(),
client_dtls_stun_piggyback_ && server_dtls_stun_piggyback_);
}
diff --git a/p2p/dtls/dtls_transport.cc b/p2p/dtls/dtls_transport.cc
index 41ebe78..f6da36f 100644
--- a/p2p/dtls/dtls_transport.cc
+++ b/p2p/dtls/dtls_transport.cc
@@ -18,6 +18,7 @@
#include <string>
#include <utility>
+#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/crypto/crypto_options.h"
@@ -26,11 +27,13 @@
#include "api/rtc_event_log/rtc_event_log.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
+#include "api/transport/stun.h"
#include "api/units/timestamp.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 "p2p/base/ice_transport_internal.h"
#include "p2p/base/packet_transport_internal.h"
+#include "p2p/dtls/dtls_stun_piggyback_controller.h"
#include "p2p/dtls/dtls_transport_internal.h"
#include "p2p/dtls/dtls_utils.h"
#include "rtc_base/buffer.h"
@@ -76,6 +79,11 @@
state_(rtc::SS_OPEN),
packets_(kMaxPendingPackets, kMaxDtlsPacketLen) {}
+void StreamInterfaceChannel::SetDtlsStunPiggybackController(
+ DtlsStunPiggybackController* dtls_stun_piggyback_controller) {
+ dtls_stun_piggyback_controller_ = dtls_stun_piggyback_controller;
+}
+
rtc::StreamResult StreamInterfaceChannel::Read(rtc::ArrayView<uint8_t> buffer,
size_t& read,
int& /* error */) {
@@ -99,6 +107,15 @@
int& /* error */) {
RTC_DCHECK_RUN_ON(&callback_sequence_);
+ // If we try to use DTLS-in-STUN, DTLS packets will be sent as part of STUN
+ // packets and are consumed here.
+ if (ice_transport_->config().dtls_handshake_in_stun &&
+ dtls_stun_piggyback_controller_ &&
+ dtls_stun_piggyback_controller_->MaybeConsumePacket(data)) {
+ written = data.size();
+ return rtc::SR_SUCCESS;
+ }
+
// Always succeeds, since this is an unreliable transport anyway.
// TODO(zhihuang): Should this block if ice_transport_'s temporarily
// unwritable?
@@ -143,17 +160,26 @@
rtc::SSLProtocolVersion max_version)
: component_(ice_transport->component()),
ice_transport_(ice_transport),
- downward_(NULL),
+ downward_(nullptr),
srtp_ciphers_(crypto_options.GetSupportedDtlsSrtpCryptoSuites()),
ssl_max_version_(max_version),
- event_log_(event_log) {
+ event_log_(event_log),
+ dtls_stun_piggyback_controller_(
+ [this](rtc::ArrayView<const uint8_t> piggybacked_dtls_packet) {
+ if (piggybacked_dtls_callback_ == nullptr) {
+ return;
+ }
+ piggybacked_dtls_callback_(
+ this, rtc::ReceivedPacket(piggybacked_dtls_packet,
+ rtc::SocketAddress()));
+ }) {
RTC_DCHECK(ice_transport_);
ConnectToIceTransport();
}
DtlsTransport::~DtlsTransport() {
if (ice_transport_) {
- ice_transport_->SetPiggybackDtlsDataCallback(nullptr);
+ ice_transport_->SetDtlsPiggybackingCallbacks(nullptr, nullptr, nullptr);
ice_transport_->DeregisterReceivedPacketCallback(this);
}
}
@@ -365,6 +391,8 @@
auto downward = std::make_unique<StreamInterfaceChannel>(ice_transport_);
StreamInterfaceChannel* downward_ptr = downward.get();
+ downward_ptr->SetDtlsStunPiggybackController(
+ &dtls_stun_piggyback_controller_);
dtls_ = rtc::SSLStreamAdapter::Create(
std::move(downward),
[this](rtc::SSLHandshakeError error) { OnDtlsHandshakeError(error); },
@@ -535,20 +563,33 @@
this, &DtlsTransport::OnReceivingState);
ice_transport_->SignalNetworkRouteChanged.connect(
this, &DtlsTransport::OnNetworkRouteChanged);
- ice_transport_->SetPiggybackDtlsDataCallback(
- [this](rtc::PacketTransportInternal* transport,
- const rtc::ReceivedPacket& packet) {
- RTC_DCHECK(dtls_active_);
- RTC_DCHECK(IsDtlsPacket(packet.payload()));
- if (!dtls_active_) {
- // Not doing DTLS.
- return;
- }
- if (!IsDtlsPacket(packet.payload())) {
- return;
- }
- OnReadPacket(transport, packet);
+ ice_transport_->SetDtlsPiggybackingCallbacks(
+ [this](StunMessageType stun_message_type) {
+ return dtls_stun_piggyback_controller_.GetDataToPiggyback(
+ stun_message_type);
+ },
+ [this](StunMessageType stun_message_type) {
+ return dtls_stun_piggyback_controller_.GetAckToPiggyback(
+ stun_message_type);
+ },
+ [this](const StunByteStringAttribute* data,
+ const StunByteStringAttribute* ack) {
+ dtls_stun_piggyback_controller_.ReportDataPiggybacked(data, ack);
});
+
+ SetPiggybackDtlsDataCallback([this](rtc::PacketTransportInternal* transport,
+ const rtc::ReceivedPacket& packet) {
+ RTC_DCHECK(dtls_active_);
+ RTC_DCHECK(IsDtlsPacket(packet.payload()));
+ if (!dtls_active_) {
+ // Not doing DTLS.
+ return;
+ }
+ if (!IsDtlsPacket(packet.payload())) {
+ return;
+ }
+ OnReadPacket(ice_transport_, packet);
+ });
}
// The state transition logic here is as follows:
@@ -580,13 +621,13 @@
// the previous DTLS session state beyond repair and no packet
// reached the peer.
if (ice_transport_->config().dtls_handshake_in_stun && dtls_ &&
- !was_ever_connected_ &&
- !ice_transport_->IsDtlsPiggybackSupportedByPeer() &&
+ !was_ever_connected_ && !IsDtlsPiggybackSupportedByPeer() &&
(dtls_state() == webrtc::DtlsTransportState::kConnecting ||
dtls_state() == webrtc::DtlsTransportState::kNew)) {
RTC_LOG(LS_INFO) << "DTLS piggybacking not supported, restarting...";
- ice_transport_->SetPiggybackDtlsDataCallback(nullptr);
+ ice_transport_->SetDtlsPiggybackingCallbacks(nullptr, nullptr, nullptr);
+ downward_->SetDtlsStunPiggybackController(nullptr);
dtls_.reset(nullptr);
set_dtls_state(webrtc::DtlsTransportState::kNew);
set_writable(false);
@@ -753,9 +794,10 @@
int ssl_version_bytes;
bool ret = dtls_->GetSslVersionBytes(&ssl_version_bytes);
RTC_DCHECK(ret);
- ice_transport_->SetDtlsHandshakeComplete(
+ dtls_stun_piggyback_controller_.SetDtlsHandshakeComplete(
dtls_role_ == rtc::SSL_CLIENT,
ssl_version_bytes == rtc::kDtls13VersionBytes);
+ downward_->SetDtlsStunPiggybackController(nullptr);
set_dtls_state(webrtc::DtlsTransportState::kConnected);
set_writable(true);
}
@@ -936,4 +978,29 @@
}
}
+void DtlsTransport::SetPiggybackDtlsDataCallback(
+ absl::AnyInvocable<void(rtc::PacketTransportInternal* transport,
+ const rtc::ReceivedPacket& packet)> callback) {
+ RTC_DCHECK(callback == nullptr || !piggybacked_dtls_callback_);
+ piggybacked_dtls_callback_ = std::move(callback);
+}
+
+bool DtlsTransport::IsDtlsPiggybackSupportedByPeer() {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ RTC_DCHECK(ice_transport_);
+ return ice_transport_->config().dtls_handshake_in_stun &&
+ dtls_stun_piggyback_controller_.state() !=
+ DtlsStunPiggybackController::State::OFF;
+}
+
+bool DtlsTransport::IsDtlsPiggybackHandshaking() {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ RTC_DCHECK(ice_transport_);
+ return ice_transport_->config().dtls_handshake_in_stun &&
+ (dtls_stun_piggyback_controller_.state() ==
+ DtlsStunPiggybackController::State::TENTATIVE ||
+ dtls_stun_piggyback_controller_.state() ==
+ DtlsStunPiggybackController::State::CONFIRMED);
+}
+
} // namespace cricket
diff --git a/p2p/dtls/dtls_transport.h b/p2p/dtls/dtls_transport.h
index a2ee3db..b0953b5 100644
--- a/p2p/dtls/dtls_transport.h
+++ b/p2p/dtls/dtls_transport.h
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
+#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/crypto/crypto_options.h"
@@ -27,6 +28,7 @@
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "p2p/base/ice_transport_internal.h"
+#include "p2p/dtls/dtls_stun_piggyback_controller.h"
#include "p2p/dtls/dtls_transport_internal.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/buffer.h"
@@ -55,6 +57,9 @@
public:
explicit StreamInterfaceChannel(IceTransportInternal* ice_transport);
+ void SetDtlsStunPiggybackController(
+ DtlsStunPiggybackController* dtls_stun_piggyback_controller);
+
StreamInterfaceChannel(const StreamInterfaceChannel&) = delete;
StreamInterfaceChannel& operator=(const StreamInterfaceChannel&) = delete;
@@ -73,6 +78,8 @@
private:
IceTransportInternal* const ice_transport_; // owned by DtlsTransport
+ DtlsStunPiggybackController*
+ dtls_stun_piggyback_controller_; // owned by DtlsTransport
rtc::StreamState state_ RTC_GUARDED_BY(callback_sequence_);
rtc::BufferQueue packets_ RTC_GUARDED_BY(callback_sequence_);
};
@@ -221,6 +228,11 @@
return sb.Release();
}
+ void SetPiggybackDtlsDataCallback(
+ absl::AnyInvocable<void(rtc::PacketTransportInternal* transport,
+ const rtc::ReceivedPacket& packet)> callback);
+ bool IsDtlsPiggybackSupportedByPeer();
+
private:
void ConnectToIceTransport();
@@ -272,6 +284,15 @@
bool was_ever_connected_ = false;
webrtc::RtcEventLog* const event_log_;
+
+ // A controller for piggybacking DTLS in STUN.
+ DtlsStunPiggybackController dtls_stun_piggyback_controller_;
+
+ bool IsDtlsPiggybackHandshaking();
+
+ absl::AnyInvocable<void(rtc::PacketTransportInternal*,
+ const rtc::ReceivedPacket&)>
+ piggybacked_dtls_callback_;
};
} // namespace cricket