Add support for sending packets with ECT(1) based on packet options in native WebRTC.

With L4S in WebRTC, only RTP packets are supposed to be send with ECT(1)

Bug: webrtc:42225697
Change-Id: If10bf74a867d3ea04fd1fb931cdc2a6380176270
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/367220
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43343}
This commit is contained in:
Per Kjellander 2024-10-31 14:10:19 +00:00 committed by WebRTC LUCI CQ
parent 0469847357
commit 906deafff4
10 changed files with 86 additions and 30 deletions

View File

@ -654,6 +654,7 @@ if (rtc_include_tests && !build_with_chromium) {
"p2p:rtc_p2p_unittests",
"rtc_base:async_dns_resolver_unittests",
"rtc_base:async_packet_socket_unittest",
"rtc_base:async_udp_socket_unittest",
"rtc_base:callback_list_unittests",
"rtc_base:rtc_base_approved_unittests",
"rtc_base:rtc_base_unittests",

View File

@ -781,6 +781,7 @@ rtc_library("stun_port") {
"../rtc_base:ip_address",
"../rtc_base:logging",
"../rtc_base:stringutils",
"../rtc_base:timeutils",
"../rtc_base/experiments:field_trial_parser",
"../rtc_base/network:received_packet",
"../rtc_base/system:rtc_export",
@ -826,6 +827,7 @@ rtc_library("tcp_port") {
"../rtc_base:net_helper",
"../rtc_base:rate_tracker",
"../rtc_base:threading",
"../rtc_base:timeutils",
"../rtc_base/containers:flat_map",
"../rtc_base/network:received_packet",
"//third_party/abseil-cpp/absl/algorithm:container",
@ -1218,6 +1220,7 @@ rtc_library("p2p_server_utils") {
"../rtc_base:ssl",
"../rtc_base:ssl_adapter",
"../rtc_base:stringutils",
"../rtc_base:timeutils",
"../rtc_base/network:received_packet",
"../rtc_base/third_party/sigslot",
"//third_party/abseil-cpp/absl/algorithm:container",

View File

@ -26,6 +26,7 @@
#include "rtc_base/logging.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/time_utils.h"
namespace cricket {

View File

@ -84,6 +84,7 @@
#include "rtc_base/network/received_packet.h"
#include "rtc_base/rate_tracker.h"
#include "rtc_base/thread.h"
#include "rtc_base/time_utils.h"
namespace cricket {
using ::webrtc::IceCandidateType;

View File

@ -30,6 +30,7 @@
#include "rtc_base/message_digest.h"
#include "rtc_base/socket_adapters.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/time_utils.h"
namespace cricket {
namespace {

View File

@ -1302,6 +1302,7 @@ rtc_library("async_udp_socket") {
]
deps = [
":async_packet_socket",
":buffer",
":checks",
":logging",
":macromagic",
@ -1311,6 +1312,7 @@ rtc_library("async_udp_socket") {
":timeutils",
"../api:sequence_checker",
"../api/units:time_delta",
"../api/units:timestamp",
"../system_wrappers:field_trial",
"network:received_packet",
"network:sent_packet",
@ -1328,7 +1330,9 @@ rtc_library("async_packet_socket") {
":callback_list",
":checks",
":dscp",
":macromagic",
":socket",
":socket_address",
":timeutils",
"../api:sequence_checker",
"network:received_packet",
@ -1336,6 +1340,7 @@ rtc_library("async_packet_socket") {
"system:no_unique_address",
"system:rtc_export",
"third_party/sigslot",
"//third_party/abseil-cpp/absl/functional:any_invocable",
]
}
@ -1353,6 +1358,24 @@ if (rtc_include_tests) {
"third_party/sigslot",
]
}
rtc_library("async_udp_socket_unittest") {
testonly = true
visibility = [ "*" ]
sources = [ "async_udp_socket_unittest.cc" ]
deps = [
":async_packet_socket",
":async_udp_socket",
":gunit_helpers",
":rtc_base_tests_utils",
":socket",
":socket_address",
"../test:test_support",
"network:received_packet",
"third_party/sigslot",
"//third_party/abseil-cpp/absl/memory",
]
}
}
rtc_library("mdns_responder_interface") {

View File

@ -11,18 +11,24 @@
#ifndef RTC_BASE_ASYNC_PACKET_SOCKET_H_
#define RTC_BASE_ASYNC_PACKET_SOCKET_H_
#include <cstddef>
#include <cstdint>
#include <functional>
#include <vector>
#include "absl/functional/any_invocable.h"
#include "api/sequence_checker.h"
#include "rtc_base/callback_list.h"
#include "rtc_base/checks.h"
#include "rtc_base/dscp.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/system/rtc_export.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/time_utils.h"
namespace rtc {
@ -54,8 +60,6 @@ struct RTC_EXPORT PacketOptions {
// Packet will be sent with ECN(1), RFC-3168, Section 5.
// Intended to be used with L4S
// https://www.rfc-editor.org/rfc/rfc9331.html
// TODO(https://bugs.webrtc.org/15368): Actually implement support for sending
// packets with different marking.
bool ecn_1 = false;
// When used with RTP packets (for example, webrtc::PacketOptions), the value

View File

@ -10,15 +10,22 @@
#include "rtc_base/async_udp_socket.h"
#include <cstddef>
#include <memory>
#include <optional>
#include "api/sequence_checker.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/socket_factory.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/field_trial.h"
namespace rtc {
@ -73,6 +80,15 @@ int AsyncUDPSocket::SendTo(const void* pv,
rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis(),
options.info_signaled_after_sent);
CopySocketInformationToPacketInfo(cb, *this, &sent_packet.info);
if (has_set_ect1_options_ != options.ecn_1) {
// It is unclear what is most efficient, setting options on every sent
// packet or when changed. Potentially, can separate send sockets be used?
// This is the easier implementation.
if (socket_->SetOption(Socket::Option::OPT_SEND_ECN,
options.ecn_1 ? 1 : 0) == 0) {
has_set_ect1_options_ = options.ecn_1;
}
}
int ret = socket_->SendTo(pv, cb, addr);
SignalSentPacket(this, sent_packet);
return ret;

View File

@ -13,13 +13,13 @@
#include <stddef.h>
#include <cstdint>
#include <memory>
#include <optional>
#include "api/sequence_checker.h"
#include "api/units/time_delta.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/buffer.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/socket_factory.h"
@ -69,6 +69,7 @@ class AsyncUDPSocket : public AsyncPacketSocket {
RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker sequence_checker_;
std::unique_ptr<Socket> socket_;
bool has_set_ect1_options_ = false;
rtc::Buffer buffer_ RTC_GUARDED_BY(sequence_checker_);
std::optional<webrtc::TimeDelta> socket_time_offset_
RTC_GUARDED_BY(sequence_checker_);

View File

@ -10,41 +10,46 @@
#include "rtc_base/async_udp_socket.h"
#include <cstdint>
#include <memory>
#include <string>
#include "rtc_base/gunit.h"
#include "rtc_base/physical_socket_server.h"
#include "absl/memory/memory.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/virtual_socket_server.h"
#include "test/gtest.h"
namespace rtc {
class AsyncUdpSocketTest : public ::testing::Test, public sigslot::has_slots<> {
public:
AsyncUdpSocketTest()
: pss_(new rtc::PhysicalSocketServer),
vss_(new rtc::VirtualSocketServer(pss_.get())),
socket_(vss_->CreateSocket(SOCK_DGRAM)),
udp_socket_(new AsyncUDPSocket(socket_)),
ready_to_send_(false) {
udp_socket_->SignalReadyToSend.connect(this,
&AsyncUdpSocketTest::OnReadyToSend);
}
static const SocketAddress kAddr("22.22.22.22", 0);
void OnReadyToSend(rtc::AsyncPacketSocket* socket) { ready_to_send_ = true; }
TEST(AsyncUDPSocketTest, SetSocketOptionIfEctChange) {
VirtualSocketServer socket_server;
Socket* socket = socket_server.CreateSocket(kAddr.family(), SOCK_DGRAM);
std::unique_ptr<AsyncUDPSocket> udp__socket =
absl::WrapUnique(AsyncUDPSocket::Create(socket, kAddr));
protected:
std::unique_ptr<PhysicalSocketServer> pss_;
std::unique_ptr<VirtualSocketServer> vss_;
Socket* socket_;
std::unique_ptr<AsyncUDPSocket> udp_socket_;
bool ready_to_send_;
};
int ect = 0;
socket->GetOption(Socket::OPT_SEND_ECN, &ect);
ASSERT_EQ(ect, 0);
TEST_F(AsyncUdpSocketTest, OnWriteEvent) {
EXPECT_FALSE(ready_to_send_);
socket_->SignalWriteEvent(socket_);
EXPECT_TRUE(ready_to_send_);
uint8_t buffer[] = "hello";
rtc::PacketOptions packet_options;
packet_options.ecn_1 = false;
udp__socket->SendTo(buffer, 5, kAddr, packet_options);
socket->GetOption(Socket::OPT_SEND_ECN, &ect);
EXPECT_EQ(ect, 0);
packet_options.ecn_1 = true;
udp__socket->SendTo(buffer, 5, kAddr, packet_options);
socket->GetOption(Socket::OPT_SEND_ECN, &ect);
EXPECT_EQ(ect, 1);
packet_options.ecn_1 = false;
udp__socket->SendTo(buffer, 5, kAddr, packet_options);
socket->GetOption(Socket::OPT_SEND_ECN, &ect);
EXPECT_EQ(ect, 0);
}
} // namespace rtc