diff options
author | Erwin Jansen <jansene@google.com> | 2023-12-15 11:49:13 -0800 |
---|---|---|
committer | Erwin Jansen <jansene@google.com> | 2023-12-15 11:49:13 -0800 |
commit | 3828327c300510e0d542f0e7c9a46e75363c7a96 (patch) | |
tree | 3cecdfdd9c8114b079c2875e5c0737adb22ef0e7 /rtc_base | |
parent | 6b2545f8bc9c20c375497afad71e11d271ebf705 (diff) | |
parent | 7e6315a61994be57daaf5fc491564cd543072be4 (diff) | |
download | webrtc-3828327c300510e0d542f0e7c9a46e75363c7a96.tar.gz |
Partial merge of WebRTC
This is a partial merge. This is needed since we do not accept changes
to OWNER files from the chrome domain, so those cannot come in a single
merge.
Change-Id: I37473f53ec79e422e8b77761a5859ebcd73f2e3e
Diffstat (limited to 'rtc_base')
49 files changed, 754 insertions, 559 deletions
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index fdc2adf639..51e15b57f7 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -156,8 +156,12 @@ rtc_library("byte_buffer") { deps = [ ":buffer", ":byte_order", + "../api:array_view", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/strings", ] - absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] } rtc_library("buffer_queue") { @@ -369,6 +373,7 @@ rtc_source_set("refcount") { ] deps = [ ":macromagic", + "../api:ref_count", "../api:scoped_refptr", ] } @@ -525,7 +530,6 @@ rtc_library("rate_limiter") { ":macromagic", ":rate_statistics", "../system_wrappers", - "../system_wrappers:field_trial", "synchronization:mutex", ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] @@ -606,6 +610,7 @@ rtc_library("stringutils") { "string_to_number.h", "string_utils.cc", "string_utils.h", + "strings/str_join.h", "strings/string_builder.cc", "strings/string_builder.h", "strings/string_format.cc", @@ -856,8 +861,8 @@ config("rtc_json_suppressions") { } rtc_library("rtc_json") { + testonly = true public_configs = [ ":rtc_json_suppressions" ] - poisonous = [ "rtc_json" ] defines = [] sources = [ "strings/json.cc", @@ -940,6 +945,7 @@ rtc_library("async_dns_resolver") { "../api:make_ref_counted", "../api:sequence_checker", "../api/task_queue:pending_task_safety_flag", + "system:rtc_export", ] } @@ -1045,6 +1051,7 @@ rtc_library("threading") { "//third_party/abseil-cpp/absl/strings", ] deps = [ + ":async_dns_resolver", ":async_resolver_interface", ":byte_order", ":checks", @@ -1060,9 +1067,11 @@ rtc_library("threading") { ":refcount", ":rtc_event", ":rtc_task_queue", + ":socket", ":socket_address", ":socket_server", ":timeutils", + "../api:async_dns_resolver", "../api:function_view", "../api:location", "../api:refcountedbase", @@ -1365,10 +1374,12 @@ rtc_library("async_packet_socket") { ] deps = [ ":callback_list", + ":checks", ":dscp", ":socket", ":timeutils", "../api:sequence_checker", + "network:received_packet", "network:sent_packet", "system:no_unique_address", "system:rtc_export", @@ -1376,6 +1387,21 @@ rtc_library("async_packet_socket") { ] } +if (rtc_include_tests) { + rtc_library("async_packet_socket_unittest") { + testonly = true + visibility = [ "*" ] + sources = [ "async_packet_socket_unittest.cc" ] + deps = [ + ":async_packet_socket", + ":gunit_helpers", + "../test:test_support", + "network:received_packet", + "third_party/sigslot", + ] + } +} + rtc_library("mdns_responder_interface") { sources = [ "mdns_responder_interface.h" ] deps = [ ":ip_address" ] @@ -1639,10 +1665,13 @@ rtc_library("testclient") { ] deps = [ ":async_udp_socket", + ":buffer", ":gunit_helpers", ":rtc_base_tests_utils", ":threading", ":timeutils", + "../api/units:timestamp", + "network:received_packet", "synchronization:mutex", ] } @@ -1888,6 +1917,7 @@ if (rtc_include_tests) { "string_encode_unittest.cc", "string_to_number_unittest.cc", "string_utils_unittest.cc", + "strings/str_join_unittest.cc", "strings/string_builder_unittest.cc", "strings/string_format_unittest.cc", "strong_alias_unittest.cc", @@ -1952,6 +1982,7 @@ if (rtc_include_tests) { ":zero_memory", "../api:array_view", "../api:make_ref_counted", + "../api:ref_count", "../api:scoped_refptr", "../api/numerics", "../api/units:data_rate", @@ -1960,7 +1991,6 @@ if (rtc_include_tests) { "../api/units:time_delta", "../api/units:timestamp", "../system_wrappers", - "../test:field_trial", "../test:fileutils", "../test:test_main", "../test:test_support", diff --git a/rtc_base/async_dns_resolver.h b/rtc_base/async_dns_resolver.h index c15af7a1cb..288751efa4 100644 --- a/rtc_base/async_dns_resolver.h +++ b/rtc_base/async_dns_resolver.h @@ -16,6 +16,7 @@ #include "api/sequence_checker.h" #include "api/task_queue/pending_task_safety_flag.h" #include "rtc_base/ref_counted_object.h" +#include "rtc_base/system/rtc_export.h" #include "rtc_base/thread_annotations.h" namespace webrtc { @@ -37,7 +38,7 @@ class AsyncDnsResolverResultImpl : public AsyncDnsResolverResult { int error_ RTC_GUARDED_BY(sequence_checker_); }; -class AsyncDnsResolver : public AsyncDnsResolverInterface { +class RTC_EXPORT AsyncDnsResolver : public AsyncDnsResolverInterface { public: AsyncDnsResolver(); ~AsyncDnsResolver(); diff --git a/rtc_base/async_packet_socket.cc b/rtc_base/async_packet_socket.cc index f50138cb62..3721366099 100644 --- a/rtc_base/async_packet_socket.cc +++ b/rtc_base/async_packet_socket.cc @@ -10,6 +10,8 @@ #include "rtc_base/async_packet_socket.h" +#include "rtc_base/checks.h" + namespace rtc { PacketTimeUpdateParams::PacketTimeUpdateParams() = default; @@ -38,6 +40,41 @@ void AsyncPacketSocket::UnsubscribeCloseEvent(const void* removal_tag) { on_close_.RemoveReceivers(removal_tag); } +void AsyncPacketSocket::RegisterReceivedPacketCallback( + absl::AnyInvocable<void(AsyncPacketSocket*, const rtc::ReceivedPacket&)> + received_packet_callback) { + RTC_DCHECK_RUN_ON(&network_checker_); + RTC_CHECK(!received_packet_callback_); + SignalReadPacket.connect(this, &AsyncPacketSocket::NotifyPacketReceived); + received_packet_callback_ = std::move(received_packet_callback); +} + +void AsyncPacketSocket::DeregisterReceivedPacketCallback() { + RTC_DCHECK_RUN_ON(&network_checker_); + SignalReadPacket.disconnect(this); + received_packet_callback_ = nullptr; +} + +void AsyncPacketSocket::NotifyPacketReceived( + const rtc::ReceivedPacket& packet) { + RTC_DCHECK_RUN_ON(&network_checker_); + if (received_packet_callback_) { + received_packet_callback_(this, packet); + return; + } + if (SignalReadPacket.is_empty()) { + RTC_DCHECK_NOTREACHED() << " No listener registered"; + return; + } + // TODO(bugs.webrtc.org:15368): Remove. This code path is only used if + // SignalReadyPacket is used by clients to get notification of received + // packets but actual socket implementation use NotifyPacketReceived to + // trigger the notification. + SignalReadPacket(this, reinterpret_cast<const char*>(packet.payload().data()), + packet.payload().size(), packet.source_address(), + packet.arrival_time() ? packet.arrival_time()->us() : -1); +} + void CopySocketInformationToPacketInfo(size_t packet_size_bytes, const AsyncPacketSocket& socket_from, bool is_connectionless, diff --git a/rtc_base/async_packet_socket.h b/rtc_base/async_packet_socket.h index 0d3ceb94e7..768fcd446b 100644 --- a/rtc_base/async_packet_socket.h +++ b/rtc_base/async_packet_socket.h @@ -11,11 +11,13 @@ #ifndef RTC_BASE_ASYNC_PACKET_SOCKET_H_ #define RTC_BASE_ASYNC_PACKET_SOCKET_H_ +#include <cstdint> #include <vector> #include "api/sequence_checker.h" #include "rtc_base/callback_list.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/system/no_unique_address.h" @@ -115,8 +117,14 @@ class RTC_EXPORT AsyncPacketSocket : public sigslot::has_slots<> { std::function<void(AsyncPacketSocket*, int)> callback); void UnsubscribeCloseEvent(const void* removal_tag); + void RegisterReceivedPacketCallback( + absl::AnyInvocable<void(AsyncPacketSocket*, const rtc::ReceivedPacket&)> + received_packet_callback); + void DeregisterReceivedPacketCallback(); + // Emitted each time a packet is read. Used only for UDP and // connected TCP sockets. + // TODO(bugs.webrtc.org:15368): Deprecate and remove. sigslot::signal5<AsyncPacketSocket*, const char*, size_t, @@ -155,12 +163,26 @@ class RTC_EXPORT AsyncPacketSocket : public sigslot::has_slots<> { on_close_.Send(this, err); } + // TODO(bugs.webrtc.org:15368): Deprecate and remove. + void NotifyPacketReceived(AsyncPacketSocket*, + const char* data, + size_t size, + const SocketAddress& address, + const int64_t& packet_time_us) { + NotifyPacketReceived( + ReceivedPacket::CreateFromLegacy(data, size, packet_time_us, address)); + } + + void NotifyPacketReceived(const rtc::ReceivedPacket& packet); + RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker network_checker_{ webrtc::SequenceChecker::kDetached}; private: webrtc::CallbackList<AsyncPacketSocket*, int> on_close_ RTC_GUARDED_BY(&network_checker_); + absl::AnyInvocable<void(AsyncPacketSocket*, const rtc::ReceivedPacket&)> + received_packet_callback_ RTC_GUARDED_BY(&network_checker_); }; // Listen socket, producing an AsyncPacketSocket when a peer connects. diff --git a/rtc_base/async_packet_socket_unittest.cc b/rtc_base/async_packet_socket_unittest.cc new file mode 100644 index 0000000000..6cd4f09459 --- /dev/null +++ b/rtc_base/async_packet_socket_unittest.cc @@ -0,0 +1,110 @@ +/* + * Copyright 2023 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 "rtc_base/async_packet_socket.h" + +#include "rtc_base/third_party/sigslot/sigslot.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace rtc { +namespace { + +using ::testing::MockFunction; + +class MockAsyncPacketSocket : public rtc::AsyncPacketSocket { + public: + ~MockAsyncPacketSocket() = default; + + MOCK_METHOD(SocketAddress, GetLocalAddress, (), (const, override)); + MOCK_METHOD(SocketAddress, GetRemoteAddress, (), (const, override)); + MOCK_METHOD(int, + Send, + (const void* pv, size_t cb, const rtc::PacketOptions& options), + (override)); + + MOCK_METHOD(int, + SendTo, + (const void* pv, + size_t cb, + const SocketAddress& addr, + const rtc::PacketOptions& options), + (override)); + MOCK_METHOD(int, Close, (), (override)); + MOCK_METHOD(State, GetState, (), (const, override)); + MOCK_METHOD(int, + GetOption, + (rtc::Socket::Option opt, int* value), + (override)); + MOCK_METHOD(int, SetOption, (rtc::Socket::Option opt, int value), (override)); + MOCK_METHOD(int, GetError, (), (const, override)); + MOCK_METHOD(void, SetError, (int error), (override)); + + void NotifyPacketReceived() { + char data[1] = {'a'}; + AsyncPacketSocket::NotifyPacketReceived(this, data, 1, SocketAddress(), -1); + } +}; + +TEST(AsyncPacketSocket, RegisteredCallbackReceivePacketsFromNotify) { + MockAsyncPacketSocket mock_socket; + MockFunction<void(AsyncPacketSocket*, const rtc::ReceivedPacket&)> + received_packet; + + EXPECT_CALL(received_packet, Call); + mock_socket.RegisterReceivedPacketCallback(received_packet.AsStdFunction()); + mock_socket.NotifyPacketReceived(); +} + +TEST(AsyncPacketSocket, RegisteredCallbackReceivePacketsFromSignalReadPacket) { + MockAsyncPacketSocket mock_socket; + MockFunction<void(AsyncPacketSocket*, const rtc::ReceivedPacket&)> + received_packet; + + EXPECT_CALL(received_packet, Call); + mock_socket.RegisterReceivedPacketCallback(received_packet.AsStdFunction()); + char data[1] = {'a'}; + mock_socket.SignalReadPacket(&mock_socket, data, 1, SocketAddress(), -1); +} + +TEST(AsyncPacketSocket, SignalReadPacketTriggeredByNotifyPacketReceived) { + class SigslotPacketReceiver : public sigslot::has_slots<> { + public: + explicit SigslotPacketReceiver(rtc::AsyncPacketSocket& socket) { + socket.SignalReadPacket.connect(this, + &SigslotPacketReceiver::OnPacketReceived); + } + + bool packet_received() const { return packet_received_; } + + private: + void OnPacketReceived(AsyncPacketSocket*, + const char*, + size_t, + const SocketAddress&, + // TODO(bugs.webrtc.org/9584): Change to passing the + // int64_t timestamp by value. + const int64_t&) { + packet_received_ = true; + } + + bool packet_received_ = false; + }; + + MockAsyncPacketSocket mock_socket; + SigslotPacketReceiver receiver(mock_socket); + ASSERT_FALSE(receiver.packet_received()); + + mock_socket.NotifyPacketReceived(); + EXPECT_TRUE(receiver.packet_received()); +} + +} // namespace +} // namespace rtc diff --git a/rtc_base/async_resolver.h b/rtc_base/async_resolver.h index 46be43860e..9de4d12fed 100644 --- a/rtc_base/async_resolver.h +++ b/rtc_base/async_resolver.h @@ -39,7 +39,12 @@ namespace rtc { // happen from the same rtc::Thread, except for Destroy which is allowed to // happen on another context provided it's not happening concurrently to another // public API call, and is the last access to the object. -class RTC_EXPORT AsyncResolver : public AsyncResolverInterface { +// TODO(bugs.webrtc.org/12598): Deprecate and remove +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wstrict-aliasing" +class [[deprecated("Use AsyncDnsResolver")]] RTC_EXPORT AsyncResolver + : public AsyncResolverInterface { +#pragma clang diagnostic pop public: AsyncResolver(); ~AsyncResolver() override; diff --git a/rtc_base/async_resolver_interface.h b/rtc_base/async_resolver_interface.h index 851fa38ce1..a0bda2774a 100644 --- a/rtc_base/async_resolver_interface.h +++ b/rtc_base/async_resolver_interface.h @@ -20,7 +20,7 @@ namespace rtc { // This interface defines the methods to resolve the address asynchronously. // TODO(bugs.webrtc.org/12598): Deprecate and remove. -class RTC_EXPORT AsyncResolverInterface { +class [[deprecated("Use AsyncDnsResolver")]] RTC_EXPORT AsyncResolverInterface { public: AsyncResolverInterface(); virtual ~AsyncResolverInterface(); diff --git a/rtc_base/async_tcp_socket.cc b/rtc_base/async_tcp_socket.cc index 367c5b04e7..eed4a31c38 100644 --- a/rtc_base/async_tcp_socket.cc +++ b/rtc_base/async_tcp_socket.cc @@ -294,8 +294,8 @@ void AsyncTCPSocket::ProcessInput(char* data, size_t* len) { if (*len < kPacketLenSize + pkt_len) return; - SignalReadPacket(this, data + kPacketLenSize, pkt_len, remote_addr, - TimeMicros()); + NotifyPacketReceived(rtc::ReceivedPacket::CreateFromLegacy( + data + kPacketLenSize, pkt_len, rtc::TimeMicros(), remote_addr)); *len -= kPacketLenSize + pkt_len; if (*len > 0) { diff --git a/rtc_base/async_tcp_socket.h b/rtc_base/async_tcp_socket.h index 541080fba7..90f77d618e 100644 --- a/rtc_base/async_tcp_socket.h +++ b/rtc_base/async_tcp_socket.h @@ -13,6 +13,7 @@ #include <stddef.h> +#include <cstdint> #include <memory> #include "rtc_base/async_packet_socket.h" diff --git a/rtc_base/async_udp_socket.cc b/rtc_base/async_udp_socket.cc index af7ae56fb6..358420a5de 100644 --- a/rtc_base/async_udp_socket.cc +++ b/rtc_base/async_udp_socket.cc @@ -136,8 +136,8 @@ void AsyncUDPSocket::OnReadEvent(Socket* socket) { // TODO: Make sure that we got all of the packet. // If we did not, then we should resize our buffer to be large enough. - SignalReadPacket(this, buf_, static_cast<size_t>(len), remote_addr, - timestamp); + NotifyPacketReceived( + rtc::ReceivedPacket::CreateFromLegacy(buf_, len, timestamp, remote_addr)); } void AsyncUDPSocket::OnWriteEvent(Socket* socket) { diff --git a/rtc_base/byte_buffer.cc b/rtc_base/byte_buffer.cc index e1278337a4..3f0e61e59c 100644 --- a/rtc_base/byte_buffer.cc +++ b/rtc_base/byte_buffer.cc @@ -19,23 +19,23 @@ ByteBufferWriter::ByteBufferWriter() : ByteBufferWriterT() {} ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len) : ByteBufferWriterT(bytes, len) {} -ByteBufferReader::ByteBufferReader(const char* bytes, size_t len) { - Construct(bytes, len); +ByteBufferReader::ByteBufferReader(rtc::ArrayView<const uint8_t> bytes) { + Construct(bytes.data(), bytes.size()); } -ByteBufferReader::ByteBufferReader(const char* bytes) { - Construct(bytes, strlen(bytes)); +ByteBufferReader::ByteBufferReader(const char* bytes, size_t len) { + Construct(reinterpret_cast<const uint8_t*>(bytes), len); } -ByteBufferReader::ByteBufferReader(const Buffer& buf) { - Construct(buf.data<char>(), buf.size()); +ByteBufferReader::ByteBufferReader(const char* bytes) { + Construct(reinterpret_cast<const uint8_t*>(bytes), strlen(bytes)); } ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf) { - Construct(buf.Data(), buf.Length()); + Construct(reinterpret_cast<const uint8_t*>(buf.Data()), buf.Length()); } -void ByteBufferReader::Construct(const char* bytes, size_t len) { +void ByteBufferReader::Construct(const uint8_t* bytes, size_t len) { bytes_ = bytes; size_ = len; start_ = 0; @@ -134,7 +134,7 @@ bool ByteBufferReader::ReadString(std::string* val, size_t len) { if (len > Length()) { return false; } else { - val->append(bytes_ + start_, len); + val->append(reinterpret_cast<const char*>(bytes_ + start_), len); start_ += len; return true; } diff --git a/rtc_base/byte_buffer.h b/rtc_base/byte_buffer.h index 9bcbb838aa..fe17da20c8 100644 --- a/rtc_base/byte_buffer.h +++ b/rtc_base/byte_buffer.h @@ -16,7 +16,9 @@ #include <string> +#include "absl/base/attributes.h" #include "absl/strings/string_view.h" +#include "api/array_view.h" #include "rtc_base/buffer.h" #include "rtc_base/byte_order.h" @@ -124,20 +126,28 @@ class ByteBufferReader { public: ByteBufferReader(const char* bytes, size_t len); + explicit ByteBufferReader( + rtc::ArrayView<const uint8_t> bytes ABSL_ATTRIBUTE_LIFETIME_BOUND); + // Initializes buffer from a zero-terminated string. explicit ByteBufferReader(const char* bytes); - explicit ByteBufferReader(const Buffer& buf); - explicit ByteBufferReader(const ByteBufferWriter& buf); ByteBufferReader(const ByteBufferReader&) = delete; ByteBufferReader& operator=(const ByteBufferReader&) = delete; // Returns start of unprocessed data. - const char* Data() const { return bytes_ + start_; } + // TODO(bugs.webrtc.org/15661): Deprecate and remove. + const char* Data() const { + return reinterpret_cast<const char*>(bytes_ + start_); + } // Returns number of unprocessed bytes. size_t Length() const { return end_ - start_; } + // Returns a view of the unprocessed data. + rtc::ArrayView<const uint8_t> DataView() { + return rtc::ArrayView<const uint8_t>(bytes_ + start_, end_ - start_); + } // Read a next value from the buffer. Return false if there isn't // enough data left for the specified type. @@ -160,9 +170,9 @@ class ByteBufferReader { bool Consume(size_t size); protected: - void Construct(const char* bytes, size_t size); + void Construct(const uint8_t* bytes, size_t size); - const char* bytes_; + const uint8_t* bytes_; size_t size_; size_t start_; size_t end_; diff --git a/rtc_base/byte_buffer_unittest.cc b/rtc_base/byte_buffer_unittest.cc index 4f8043c98f..615237c1e6 100644 --- a/rtc_base/byte_buffer_unittest.cc +++ b/rtc_base/byte_buffer_unittest.cc @@ -12,6 +12,8 @@ #include <string.h> +#include <cstdint> + #include "rtc_base/arraysize.h" #include "rtc_base/byte_order.h" #include "test/gtest.h" @@ -247,4 +249,19 @@ TEST(ByteBufferTest, TestReadWriteUVarint) { EXPECT_EQ(size, read_buffer.Length()); } +TEST(ByteBufferTest, ReadFromArrayView) { + const uint8_t buf[] = {'a', 'b', 'c'}; + ArrayView<const uint8_t> view(buf, 3); + + ByteBufferReader read_buffer(view); + uint8_t val; + EXPECT_TRUE(read_buffer.ReadUInt8(&val)); + EXPECT_EQ(val, 'a'); + EXPECT_TRUE(read_buffer.ReadUInt8(&val)); + EXPECT_EQ(val, 'b'); + EXPECT_TRUE(read_buffer.ReadUInt8(&val)); + EXPECT_EQ(val, 'c'); + EXPECT_FALSE(read_buffer.ReadUInt8(&val)); +} + } // namespace rtc diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn index ac542cc301..185d5931f7 100644 --- a/rtc_base/experiments/BUILD.gn +++ b/rtc_base/experiments/BUILD.gn @@ -75,8 +75,6 @@ rtc_library("quality_scaler_settings") { ":field_trial_parser", "..:logging", "../../api:field_trials_view", - "../../api/transport:field_trial_based_config", - "../../system_wrappers:field_trial", ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } @@ -103,10 +101,14 @@ rtc_library("quality_scaling_experiment") { ] deps = [ "..:logging", + "../../api:field_trials_view", + "../../api/transport:field_trial_based_config", "../../api/video_codecs:video_codecs_api", - "../../system_wrappers:field_trial", ] - absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + absl_deps = [ + "//third_party/abseil-cpp/absl/strings:strings", + "//third_party/abseil-cpp/absl/types:optional", + ] } rtc_library("normalize_simulcast_size_experiment") { diff --git a/rtc_base/experiments/quality_scaler_settings.cc b/rtc_base/experiments/quality_scaler_settings.cc index 85c99255ab..24da211d89 100644 --- a/rtc_base/experiments/quality_scaler_settings.cc +++ b/rtc_base/experiments/quality_scaler_settings.cc @@ -10,7 +10,7 @@ #include "rtc_base/experiments/quality_scaler_settings.h" -#include "api/transport/field_trial_based_config.h" +#include "api/field_trials_view.h" #include "rtc_base/logging.h" namespace webrtc { @@ -20,7 +20,7 @@ const double kMinScaleFactor = 0.01; } // namespace QualityScalerSettings::QualityScalerSettings( - const FieldTrialsView* const key_value_config) + const FieldTrialsView& field_trials) : sampling_period_ms_("sampling_period_ms"), average_qp_window_("average_qp_window"), min_frames_("min_frames"), @@ -28,16 +28,10 @@ QualityScalerSettings::QualityScalerSettings( scale_factor_("scale_factor"), initial_bitrate_interval_ms_("initial_bitrate_interval_ms"), initial_bitrate_factor_("initial_bitrate_factor") { - ParseFieldTrial( - {&sampling_period_ms_, &average_qp_window_, &min_frames_, - &initial_scale_factor_, &scale_factor_, &initial_bitrate_interval_ms_, - &initial_bitrate_factor_}, - key_value_config->Lookup("WebRTC-Video-QualityScalerSettings")); -} - -QualityScalerSettings QualityScalerSettings::ParseFromFieldTrials() { - FieldTrialBasedConfig field_trial_config; - return QualityScalerSettings(&field_trial_config); + ParseFieldTrial({&sampling_period_ms_, &average_qp_window_, &min_frames_, + &initial_scale_factor_, &scale_factor_, + &initial_bitrate_interval_ms_, &initial_bitrate_factor_}, + field_trials.Lookup("WebRTC-Video-QualityScalerSettings")); } absl::optional<int> QualityScalerSettings::SamplingPeriodMs() const { diff --git a/rtc_base/experiments/quality_scaler_settings.h b/rtc_base/experiments/quality_scaler_settings.h index 99827aac6b..1085816697 100644 --- a/rtc_base/experiments/quality_scaler_settings.h +++ b/rtc_base/experiments/quality_scaler_settings.h @@ -19,7 +19,7 @@ namespace webrtc { class QualityScalerSettings final { public: - static QualityScalerSettings ParseFromFieldTrials(); + explicit QualityScalerSettings(const FieldTrialsView& field_trials); absl::optional<int> SamplingPeriodMs() const; absl::optional<int> AverageQpWindow() const; @@ -30,8 +30,6 @@ class QualityScalerSettings final { absl::optional<double> InitialBitrateFactor() const; private: - explicit QualityScalerSettings(const FieldTrialsView* const key_value_config); - FieldTrialOptional<int> sampling_period_ms_; FieldTrialOptional<int> average_qp_window_; FieldTrialOptional<int> min_frames_; diff --git a/rtc_base/experiments/quality_scaler_settings_unittest.cc b/rtc_base/experiments/quality_scaler_settings_unittest.cc index 9da770c1b5..578fe97b03 100644 --- a/rtc_base/experiments/quality_scaler_settings_unittest.cc +++ b/rtc_base/experiments/quality_scaler_settings_unittest.cc @@ -10,14 +10,15 @@ #include "rtc_base/experiments/quality_scaler_settings.h" -#include "test/field_trial.h" #include "test/gtest.h" +#include "test/scoped_key_value_config.h" namespace webrtc { namespace { TEST(QualityScalerSettingsTest, ValuesNotSetByDefault) { - const auto settings = QualityScalerSettings::ParseFromFieldTrials(); + webrtc::test::ScopedKeyValueConfig field_trials(""); + const auto settings = QualityScalerSettings(field_trials); EXPECT_FALSE(settings.MinFrames()); EXPECT_FALSE(settings.InitialScaleFactor()); EXPECT_FALSE(settings.ScaleFactor()); @@ -26,46 +27,42 @@ TEST(QualityScalerSettingsTest, ValuesNotSetByDefault) { } TEST(QualityScalerSettingsTest, ParseMinFrames) { - test::ScopedFieldTrials field_trials( + test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScalerSettings/min_frames:100/"); - EXPECT_EQ(100, QualityScalerSettings::ParseFromFieldTrials().MinFrames()); + EXPECT_EQ(100, QualityScalerSettings(field_trials).MinFrames()); } TEST(QualityScalerSettingsTest, ParseInitialScaleFactor) { - test::ScopedFieldTrials field_trials( + test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScalerSettings/initial_scale_factor:1.5/"); - EXPECT_EQ(1.5, - QualityScalerSettings::ParseFromFieldTrials().InitialScaleFactor()); + EXPECT_EQ(1.5, QualityScalerSettings(field_trials).InitialScaleFactor()); } TEST(QualityScalerSettingsTest, ParseScaleFactor) { - test::ScopedFieldTrials field_trials( + test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScalerSettings/scale_factor:1.1/"); - EXPECT_EQ(1.1, QualityScalerSettings::ParseFromFieldTrials().ScaleFactor()); + EXPECT_EQ(1.1, QualityScalerSettings(field_trials).ScaleFactor()); } TEST(QualityScalerSettingsTest, ParseInitialBitrateInterval) { - test::ScopedFieldTrials field_trials( + test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScalerSettings/initial_bitrate_interval_ms:1000/"); - EXPECT_EQ( - 1000, - QualityScalerSettings::ParseFromFieldTrials().InitialBitrateIntervalMs()); + EXPECT_EQ(1000, + QualityScalerSettings(field_trials).InitialBitrateIntervalMs()); } TEST(QualityScalerSettingsTest, ParseInitialBitrateFactor) { - test::ScopedFieldTrials field_trials( + test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScalerSettings/initial_bitrate_factor:0.75/"); - EXPECT_EQ( - 0.75, - QualityScalerSettings::ParseFromFieldTrials().InitialBitrateFactor()); + EXPECT_EQ(0.75, QualityScalerSettings(field_trials).InitialBitrateFactor()); } TEST(QualityScalerSettingsTest, ParseAll) { - test::ScopedFieldTrials field_trials( + test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScalerSettings/" "min_frames:100,initial_scale_factor:1.5,scale_factor:0.9," "initial_bitrate_interval_ms:5500,initial_bitrate_factor:0.7/"); - const auto settings = QualityScalerSettings::ParseFromFieldTrials(); + const auto settings = QualityScalerSettings(field_trials); EXPECT_EQ(100, settings.MinFrames()); EXPECT_EQ(1.5, settings.InitialScaleFactor()); EXPECT_EQ(0.9, settings.ScaleFactor()); @@ -74,11 +71,11 @@ TEST(QualityScalerSettingsTest, ParseAll) { } TEST(QualityScalerSettingsTest, DoesNotParseIncorrectValue) { - test::ScopedFieldTrials field_trials( + test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScalerSettings/" "min_frames:a,initial_scale_factor:b,scale_factor:c," "initial_bitrate_interval_ms:d,initial_bitrate_factor:e/"); - const auto settings = QualityScalerSettings::ParseFromFieldTrials(); + const auto settings = QualityScalerSettings(field_trials); EXPECT_FALSE(settings.MinFrames()); EXPECT_FALSE(settings.InitialScaleFactor()); EXPECT_FALSE(settings.ScaleFactor()); @@ -87,11 +84,11 @@ TEST(QualityScalerSettingsTest, DoesNotParseIncorrectValue) { } TEST(QualityScalerSettingsTest, DoesNotReturnTooSmallValue) { - test::ScopedFieldTrials field_trials( + test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScalerSettings/" "min_frames:0,initial_scale_factor:0.0,scale_factor:0.0," "initial_bitrate_interval_ms:-1,initial_bitrate_factor:0.0/"); - const auto settings = QualityScalerSettings::ParseFromFieldTrials(); + const auto settings = QualityScalerSettings(field_trials); EXPECT_FALSE(settings.MinFrames()); EXPECT_FALSE(settings.InitialScaleFactor()); EXPECT_FALSE(settings.ScaleFactor()); diff --git a/rtc_base/experiments/quality_scaling_experiment.cc b/rtc_base/experiments/quality_scaling_experiment.cc index 0c4ec22d71..ee3d7c0320 100644 --- a/rtc_base/experiments/quality_scaling_experiment.cc +++ b/rtc_base/experiments/quality_scaling_experiment.cc @@ -13,8 +13,10 @@ #include <string> +#include "absl/strings/match.h" +#include "api/field_trials_view.h" +#include "api/transport/field_trial_based_config.h" #include "rtc_base/logging.h" -#include "system_wrappers/include/field_trial.h" namespace webrtc { namespace { @@ -42,17 +44,17 @@ absl::optional<VideoEncoder::QpThresholds> GetThresholds(int low, } } // namespace -bool QualityScalingExperiment::Enabled() { +bool QualityScalingExperiment::Enabled(const FieldTrialsView& field_trials) { #if defined(WEBRTC_IOS) - return webrtc::field_trial::IsEnabled(kFieldTrial); + return absl::StartsWith(field_trials.Lookup(kFieldTrial), "Enabled"); #else - return !webrtc::field_trial::IsDisabled(kFieldTrial); + return !absl::StartsWith(field_trials.Lookup(kFieldTrial), "Disabled"); #endif } absl::optional<QualityScalingExperiment::Settings> -QualityScalingExperiment::ParseSettings() { - std::string group = webrtc::field_trial::FindFullName(kFieldTrial); +QualityScalingExperiment::ParseSettings(const FieldTrialsView& field_trials) { + std::string group = field_trials.Lookup(kFieldTrial); // TODO(http://crbug.com/webrtc/12401): Completely remove the experiment code // after few releases. #if !defined(WEBRTC_IOS) @@ -71,8 +73,9 @@ QualityScalingExperiment::ParseSettings() { } absl::optional<VideoEncoder::QpThresholds> -QualityScalingExperiment::GetQpThresholds(VideoCodecType codec_type) { - const auto settings = ParseSettings(); +QualityScalingExperiment::GetQpThresholds(VideoCodecType codec_type, + const FieldTrialsView& field_trials) { + const auto settings = ParseSettings(field_trials); if (!settings) return absl::nullopt; @@ -93,8 +96,9 @@ QualityScalingExperiment::GetQpThresholds(VideoCodecType codec_type) { } } -QualityScalingExperiment::Config QualityScalingExperiment::GetConfig() { - const auto settings = ParseSettings(); +QualityScalingExperiment::Config QualityScalingExperiment::GetConfig( + const FieldTrialsView& field_trials) { + const auto settings = ParseSettings(field_trials); if (!settings) return Config(); diff --git a/rtc_base/experiments/quality_scaling_experiment.h b/rtc_base/experiments/quality_scaling_experiment.h index 31d8292b5c..bd24c06e55 100644 --- a/rtc_base/experiments/quality_scaling_experiment.h +++ b/rtc_base/experiments/quality_scaling_experiment.h @@ -11,6 +11,7 @@ #define RTC_BASE_EXPERIMENTS_QUALITY_SCALING_EXPERIMENT_H_ #include "absl/types/optional.h" +#include "api/field_trials_view.h" #include "api/video_codecs/video_encoder.h" namespace webrtc { @@ -40,17 +41,19 @@ class QualityScalingExperiment { }; // Returns true if the experiment is enabled. - static bool Enabled(); + static bool Enabled(const FieldTrialsView& field_trials); // Returns settings from field trial. - static absl::optional<Settings> ParseSettings(); + static absl::optional<Settings> ParseSettings( + const FieldTrialsView& field_trials); // Returns QpThresholds for the `codec_type`. static absl::optional<VideoEncoder::QpThresholds> GetQpThresholds( - VideoCodecType codec_type); + VideoCodecType codec_type, + const FieldTrialsView& field_trials); // Returns parsed values. If the parsing fails, default values are returned. - static Config GetConfig(); + static Config GetConfig(const FieldTrialsView& field_trials); }; } // namespace webrtc diff --git a/rtc_base/experiments/quality_scaling_experiment_unittest.cc b/rtc_base/experiments/quality_scaling_experiment_unittest.cc index 4507f1514f..0c1450557a 100644 --- a/rtc_base/experiments/quality_scaling_experiment_unittest.cc +++ b/rtc_base/experiments/quality_scaling_experiment_unittest.cc @@ -10,8 +10,8 @@ #include "rtc_base/experiments/quality_scaling_experiment.h" -#include "test/field_trial.h" #include "test/gtest.h" +#include "test/scoped_key_value_config.h" namespace webrtc { namespace { @@ -41,28 +41,28 @@ void ExpectEqualConfig(QualityScalingExperiment::Config a, #if !defined(WEBRTC_IOS) // TODO(bugs.webrtc.org/12401): investigate why QualityScaler kicks in on iOS. TEST(QualityScalingExperimentTest, DefaultEnabledWithoutFieldTrial) { - webrtc::test::ScopedFieldTrials field_trials(""); - EXPECT_TRUE(QualityScalingExperiment::Enabled()); + webrtc::test::ScopedKeyValueConfig field_trials(""); + EXPECT_TRUE(QualityScalingExperiment::Enabled(field_trials)); } #else TEST(QualityScalingExperimentTest, DefaultDisabledWithoutFieldTrialIOS) { - webrtc::test::ScopedFieldTrials field_trials(""); - EXPECT_FALSE(QualityScalingExperiment::Enabled()); + webrtc::test::ScopedKeyValueConfig field_trials(""); + EXPECT_FALSE(QualityScalingExperiment::Enabled(field_trials)); } #endif TEST(QualityScalingExperimentTest, EnabledWithFieldTrial) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled/"); - EXPECT_TRUE(QualityScalingExperiment::Enabled()); + EXPECT_TRUE(QualityScalingExperiment::Enabled(field_trials)); } TEST(QualityScalingExperimentTest, ParseSettings) { const QualityScalingExperiment::Settings kExpected = {1, 2, 3, 4, 5, 6, 7, 8, 0.9f, 0.99f, 1}; - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,7,8,0.9,0.99,1/"); - const auto settings = QualityScalingExperiment::ParseSettings(); + const auto settings = QualityScalingExperiment::ParseSettings(field_trials); EXPECT_TRUE(settings); ExpectEqualSettings(kExpected, *settings); } @@ -70,117 +70,117 @@ TEST(QualityScalingExperimentTest, ParseSettings) { #if !defined(WEBRTC_IOS) // TODO(bugs.webrtc.org/12401): investigate why QualityScaler kicks in on iOS. TEST(QualityScalingExperimentTest, ParseSettingsUsesDefaultsWithoutFieldTrial) { - webrtc::test::ScopedFieldTrials field_trials(""); + webrtc::test::ScopedKeyValueConfig field_trials(""); // Uses some default hard coded values. - EXPECT_TRUE(QualityScalingExperiment::ParseSettings()); + EXPECT_TRUE(QualityScalingExperiment::ParseSettings(field_trials)); } #else TEST(QualityScalingExperimentTest, ParseSettingsFailsWithoutFieldTrial) { - webrtc::test::ScopedFieldTrials field_trials(""); - EXPECT_FALSE(QualityScalingExperiment::ParseSettings()); + webrtc::test::ScopedKeyValueConfig field_trials(""); + EXPECT_FALSE(QualityScalingExperiment::ParseSettings(field_trials)); } #endif TEST(QualityScalingExperimentTest, ParseSettingsFailsWithInvalidFieldTrial) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-invalid/"); - EXPECT_FALSE(QualityScalingExperiment::ParseSettings()); + EXPECT_FALSE(QualityScalingExperiment::ParseSettings(field_trials)); } TEST(QualityScalingExperimentTest, GetConfig) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,7,8,0.9,0.99,0/"); - const auto config = QualityScalingExperiment::GetConfig(); + const auto config = QualityScalingExperiment::GetConfig(field_trials); EXPECT_EQ(0.9f, config.alpha_high); EXPECT_EQ(0.99f, config.alpha_low); EXPECT_FALSE(config.use_all_drop_reasons); } TEST(QualityScalingExperimentTest, GetsDefaultConfigForInvalidFieldTrial) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-invalid/"); - const auto config = QualityScalingExperiment::GetConfig(); + const auto config = QualityScalingExperiment::GetConfig(field_trials); ExpectEqualConfig(config, QualityScalingExperiment::Config()); } TEST(QualityScalingExperimentTest, GetsDefaultAlphaForInvalidValue) { QualityScalingExperiment::Config expected_config; expected_config.use_all_drop_reasons = true; - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,7,8,0.99,0.9,1/"); - const auto config = QualityScalingExperiment::GetConfig(); + const auto config = QualityScalingExperiment::GetConfig(field_trials); ExpectEqualConfig(config, expected_config); } TEST(QualityScalingExperimentTest, GetVp8Thresholds) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,0,0,0.9,0.99,1/"); const auto thresholds = - QualityScalingExperiment::GetQpThresholds(kVideoCodecVP8); + QualityScalingExperiment::GetQpThresholds(kVideoCodecVP8, field_trials); EXPECT_TRUE(thresholds); EXPECT_EQ(1, thresholds->low); EXPECT_EQ(2, thresholds->high); } TEST(QualityScalingExperimentTest, GetThresholdsFailsForInvalidVp8Value) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-0,0,3,4,5,6,7,8,0.9,0.99,1/"); const auto thresholds = - QualityScalingExperiment::GetQpThresholds(kVideoCodecVP8); + QualityScalingExperiment::GetQpThresholds(kVideoCodecVP8, field_trials); EXPECT_FALSE(thresholds); } TEST(QualityScalingExperimentTest, GetVp9Thresholds) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,0,0,0.9,0.99,1/"); const auto thresholds = - QualityScalingExperiment::GetQpThresholds(kVideoCodecVP9); + QualityScalingExperiment::GetQpThresholds(kVideoCodecVP9, field_trials); EXPECT_TRUE(thresholds); EXPECT_EQ(3, thresholds->low); EXPECT_EQ(4, thresholds->high); } TEST(QualityScalingExperimentTest, GetThresholdsFailsForInvalidVp9Value) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,0,0,5,6,7,8,0.9,0.99,1/"); const auto thresholds = - QualityScalingExperiment::GetQpThresholds(kVideoCodecVP9); + QualityScalingExperiment::GetQpThresholds(kVideoCodecVP9, field_trials); EXPECT_FALSE(thresholds); } TEST(QualityScalingExperimentTest, GetH264Thresholds) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,0,0,0.9,0.99,1/"); const auto thresholds = - QualityScalingExperiment::GetQpThresholds(kVideoCodecH264); + QualityScalingExperiment::GetQpThresholds(kVideoCodecH264, field_trials); EXPECT_TRUE(thresholds); EXPECT_EQ(5, thresholds->low); EXPECT_EQ(6, thresholds->high); } TEST(QualityScalingExperimentTest, GetThresholdsFailsForInvalidH264Value) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,0,0,7,8,0.9,0.99,1/"); const auto thresholds = - QualityScalingExperiment::GetQpThresholds(kVideoCodecH264); + QualityScalingExperiment::GetQpThresholds(kVideoCodecH264, field_trials); EXPECT_FALSE(thresholds); } TEST(QualityScalingExperimentTest, GetGenericThresholds) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,0,0,7,8,0.9,0.99,1/"); - const auto thresholds = - QualityScalingExperiment::GetQpThresholds(kVideoCodecGeneric); + const auto thresholds = QualityScalingExperiment::GetQpThresholds( + kVideoCodecGeneric, field_trials); EXPECT_TRUE(thresholds); EXPECT_EQ(7, thresholds->low); EXPECT_EQ(8, thresholds->high); } TEST(QualityScalingExperimentTest, GetThresholdsFailsForInvalidGenericValue) { - webrtc::test::ScopedFieldTrials field_trials( + webrtc::test::ScopedKeyValueConfig field_trials( "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,0,0,0.9,0.99,1/"); - const auto thresholds = - QualityScalingExperiment::GetQpThresholds(kVideoCodecGeneric); + const auto thresholds = QualityScalingExperiment::GetQpThresholds( + kVideoCodecGeneric, field_trials); EXPECT_FALSE(thresholds); } } // namespace webrtc diff --git a/rtc_base/ip_address_unittest.cc b/rtc_base/ip_address_unittest.cc index 9ca05c95fe..aee9b93dd9 100644 --- a/rtc_base/ip_address_unittest.cc +++ b/rtc_base/ip_address_unittest.cc @@ -61,10 +61,6 @@ static const std::string kIPv6PublicAddrAnonymizedString = "2401:fa00:4:x:x:x:x:x"; static const std::string kIPv6PublicAddr2AnonymizedString = "2401:0:0:x:x:x:x:x"; -static const std::string kIPv4MappedAnyAddrString = "::ffff:0:0"; -static const std::string kIPv4MappedRFC1918AddrString = "::ffff:c0a8:701"; -static const std::string kIPv4MappedLoopbackAddrString = "::ffff:7f00:1"; -static const std::string kIPv4MappedPublicAddrString = "::ffff:102:0304"; static const std::string kIPv4MappedV4StyleAddrString = "::ffff:192.168.7.1"; static const std::string kIPv4BrokenString1 = "192.168.7."; diff --git a/rtc_base/nat_unittest.cc b/rtc_base/nat_unittest.cc index 19e53543ba..432985d283 100644 --- a/rtc_base/nat_unittest.cc +++ b/rtc_base/nat_unittest.cc @@ -11,14 +11,17 @@ #include <string.h> #include <algorithm> +#include <cstddef> #include <memory> #include <string> #include <vector> #include "absl/memory/memory.h" +#include "api/units/time_delta.h" #include "rtc_base/async_packet_socket.h" #include "rtc_base/async_tcp_socket.h" #include "rtc_base/async_udp_socket.h" +#include "rtc_base/event.h" #include "rtc_base/gunit.h" #include "rtc_base/ip_address.h" #include "rtc_base/logging.h" @@ -80,29 +83,36 @@ void TestSend(SocketServer* internal, NATSocketFactory* natsf = new NATSocketFactory( internal, nat->internal_udp_address(), nat->internal_tcp_address()); - TestClient* in = CreateTestClient(natsf, internal_addr); - TestClient* out[4]; - for (int i = 0; i < 4; i++) - out[i] = CreateTestClient(external, external_addrs[i]); - th_int.Start(); th_ext.Start(); + TestClient* in; + th_int.BlockingCall([&] { in = CreateTestClient(natsf, internal_addr); }); + + TestClient* out[4]; + th_ext.BlockingCall([&] { + for (int i = 0; i < 4; i++) + out[i] = CreateTestClient(external, external_addrs[i]); + }); + const char* buf = "filter_test"; size_t len = strlen(buf); - in->SendTo(buf, len, out[0]->address()); + th_int.BlockingCall([&] { in->SendTo(buf, len, out[0]->address()); }); SocketAddress trans_addr; - EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); + th_ext.BlockingCall( + [&] { EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); }); for (int i = 1; i < 4; i++) { - in->SendTo(buf, len, out[i]->address()); + th_int.BlockingCall([&] { in->SendTo(buf, len, out[i]->address()); }); SocketAddress trans_addr2; - EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2)); - bool are_same = (trans_addr == trans_addr2); - ASSERT_EQ(are_same, exp_same) << "same translated address"; - ASSERT_NE(AF_UNSPEC, trans_addr.family()); - ASSERT_NE(AF_UNSPEC, trans_addr2.family()); + th_ext.BlockingCall([&] { + EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2)); + bool are_same = (trans_addr == trans_addr2); + ASSERT_EQ(are_same, exp_same) << "same translated address"; + ASSERT_NE(AF_UNSPEC, trans_addr.family()); + ASSERT_NE(AF_UNSPEC, trans_addr2.family()); + }); } th_int.Stop(); @@ -134,29 +144,39 @@ void TestRecv(SocketServer* internal, NATSocketFactory* natsf = new NATSocketFactory( internal, nat->internal_udp_address(), nat->internal_tcp_address()); - TestClient* in = CreateTestClient(natsf, internal_addr); - TestClient* out[4]; - for (int i = 0; i < 4; i++) - out[i] = CreateTestClient(external, external_addrs[i]); - th_int.Start(); th_ext.Start(); + TestClient* in = nullptr; + th_int.BlockingCall([&] { in = CreateTestClient(natsf, internal_addr); }); + + TestClient* out[4]; + th_ext.BlockingCall([&] { + for (int i = 0; i < 4; i++) + out[i] = CreateTestClient(external, external_addrs[i]); + }); + const char* buf = "filter_test"; size_t len = strlen(buf); - in->SendTo(buf, len, out[0]->address()); + th_int.BlockingCall([&] { in->SendTo(buf, len, out[0]->address()); }); SocketAddress trans_addr; - EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); + th_ext.BlockingCall( + [&] { EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); }); + + th_ext.BlockingCall([&] { out[1]->SendTo(buf, len, trans_addr); }); + th_int.BlockingCall( + [&] { EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len)); }); + th_ext.BlockingCall([&] { out[2]->SendTo(buf, len, trans_addr); }); - out[1]->SendTo(buf, len, trans_addr); - EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len)); + th_int.BlockingCall( + [&] { EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len)); }); - out[2]->SendTo(buf, len, trans_addr); - EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len)); + th_ext.BlockingCall([&] { out[3]->SendTo(buf, len, trans_addr); }); - out[3]->SendTo(buf, len, trans_addr); - EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len)); + th_int.BlockingCall([&] { + EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len)); + }); th_int.Stop(); th_ext.Stop(); diff --git a/rtc_base/network/BUILD.gn b/rtc_base/network/BUILD.gn index 35ae3d45f7..263bfcc282 100644 --- a/rtc_base/network/BUILD.gn +++ b/rtc_base/network/BUILD.gn @@ -16,3 +16,19 @@ rtc_library("sent_packet") { deps = [ "../system:rtc_export" ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } + +rtc_library("received_packet") { + sources = [ + "received_packet.cc", + "received_packet.h", + ] + deps = [ + "..:socket_address", + "../../api:array_view", + "../../api/units:timestamp", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/functional:any_invocable", + "//third_party/abseil-cpp/absl/types:optional", + ] +} diff --git a/rtc_base/network/received_packet.cc b/rtc_base/network/received_packet.cc new file mode 100644 index 0000000000..40d6e1142c --- /dev/null +++ b/rtc_base/network/received_packet.cc @@ -0,0 +1,42 @@ +/* + * Copyright 2023 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 "rtc_base/network/received_packet.h" + +#include <utility> + +#include "absl/types/optional.h" + +namespace rtc { + +ReceivedPacket::ReceivedPacket(rtc::ArrayView<const uint8_t> payload, + const SocketAddress& source_address, + absl::optional<webrtc::Timestamp> arrival_time) + : payload_(payload), + arrival_time_(std::move(arrival_time)), + source_address_(source_address) {} + +// static +ReceivedPacket ReceivedPacket::CreateFromLegacy( + const char* data, + size_t size, + int64_t packet_time_us, + const rtc::SocketAddress& source_address) { + RTC_DCHECK(packet_time_us == -1 || packet_time_us >= 0); + return ReceivedPacket(rtc::reinterpret_array_view<const uint8_t>( + rtc::MakeArrayView(data, size)), + source_address, + (packet_time_us >= 0) + ? absl::optional<webrtc::Timestamp>( + webrtc::Timestamp::Micros(packet_time_us)) + : absl::nullopt); +} + +} // namespace rtc diff --git a/rtc_base/network/received_packet.h b/rtc_base/network/received_packet.h new file mode 100644 index 0000000000..9b10099e9d --- /dev/null +++ b/rtc_base/network/received_packet.h @@ -0,0 +1,58 @@ +/* + * Copyright 2023 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. + */ +#ifndef RTC_BASE_NETWORK_RECEIVED_PACKET_H_ +#define RTC_BASE_NETWORK_RECEIVED_PACKET_H_ + +#include <cstdint> + +#include "absl/types/optional.h" +#include "api/array_view.h" +#include "api/units/timestamp.h" +#include "rtc_base/socket_address.h" + +namespace rtc { + +// ReceivedPacket repressent a received IP packet. +// It contains a payload and metadata. +// ReceivedPacket itself does not put constraints on what payload contains. For +// example it may contains STUN, SCTP, SRTP, RTP, RTCP.... etc. +class ReceivedPacket { + public: + // Caller must keep memory pointed to by payload and address valid for the + // lifetime of this ReceivedPacket. + ReceivedPacket( + rtc::ArrayView<const uint8_t> payload, + const SocketAddress& source_address, + absl::optional<webrtc::Timestamp> arrival_time = absl::nullopt); + + // Address/port of the packet sender. + const SocketAddress& source_address() const { return source_address_; } + rtc::ArrayView<const uint8_t> payload() const { return payload_; } + + // Timestamp when this packet was received. Not available on all socket + // implementations. + absl::optional<webrtc::Timestamp> arrival_time() const { + return arrival_time_; + } + + static ReceivedPacket CreateFromLegacy( + const char* data, + size_t size, + int64_t packet_time_us, + const rtc::SocketAddress& = rtc::SocketAddress()); + + private: + rtc::ArrayView<const uint8_t> payload_; + absl::optional<webrtc::Timestamp> arrival_time_; + const SocketAddress& source_address_; +}; + +} // namespace rtc +#endif // RTC_BASE_NETWORK_RECEIVED_PACKET_H_ diff --git a/rtc_base/numerics/sample_counter.cc b/rtc_base/numerics/sample_counter.cc index 16a8e25098..78e35fdb5b 100644 --- a/rtc_base/numerics/sample_counter.cc +++ b/rtc_base/numerics/sample_counter.cc @@ -31,6 +31,9 @@ void SampleCounter::Add(int sample) { if (!max_ || sample > *max_) { max_ = sample; } + if (!min_ || sample < *min_) { + min_ = sample; + } } void SampleCounter::Add(const SampleCounter& other) { @@ -45,6 +48,8 @@ void SampleCounter::Add(const SampleCounter& other) { num_samples_ += other.num_samples_; if (other.max_ && (!max_ || *max_ < *other.max_)) max_ = other.max_; + if (other.min_ && (!min_ || *min_ > *other.min_)) + min_ = other.min_; } absl::optional<int> SampleCounter::Avg(int64_t min_required_samples) const { @@ -58,6 +63,10 @@ absl::optional<int> SampleCounter::Max() const { return max_; } +absl::optional<int> SampleCounter::Min() const { + return min_; +} + absl::optional<int64_t> SampleCounter::Sum(int64_t min_required_samples) const { RTC_DCHECK_GT(min_required_samples, 0); if (num_samples_ < min_required_samples) diff --git a/rtc_base/numerics/sample_counter.h b/rtc_base/numerics/sample_counter.h index 717a1afbcf..2b41f95fc0 100644 --- a/rtc_base/numerics/sample_counter.h +++ b/rtc_base/numerics/sample_counter.h @@ -26,6 +26,7 @@ class SampleCounter { void Add(int sample); absl::optional<int> Avg(int64_t min_required_samples) const; absl::optional<int> Max() const; + absl::optional<int> Min() const; absl::optional<int64_t> Sum(int64_t min_required_samples) const; int64_t NumSamples() const; void Reset(); @@ -37,6 +38,7 @@ class SampleCounter { int64_t sum_ = 0; int64_t num_samples_ = 0; absl::optional<int> max_; + absl::optional<int> min_; }; class SampleCounterWithVariance : public SampleCounter { diff --git a/rtc_base/numerics/sample_counter_unittest.cc b/rtc_base/numerics/sample_counter_unittest.cc index 14b0573de9..ffc8b89f6f 100644 --- a/rtc_base/numerics/sample_counter_unittest.cc +++ b/rtc_base/numerics/sample_counter_unittest.cc @@ -24,6 +24,7 @@ TEST(SampleCounterTest, ProcessesNoSamples) { SampleCounter counter; EXPECT_THAT(counter.Avg(kMinSamples), Eq(absl::nullopt)); EXPECT_THAT(counter.Max(), Eq(absl::nullopt)); + EXPECT_THAT(counter.Min(), Eq(absl::nullopt)); } TEST(SampleCounterTest, NotEnoughSamples) { @@ -35,6 +36,7 @@ TEST(SampleCounterTest, NotEnoughSamples) { EXPECT_THAT(counter.Avg(kMinSamples), Eq(absl::nullopt)); EXPECT_THAT(counter.Sum(kMinSamples), Eq(absl::nullopt)); EXPECT_THAT(counter.Max(), Eq(5)); + EXPECT_THAT(counter.Min(), Eq(1)); } TEST(SampleCounterTest, EnoughSamples) { @@ -46,6 +48,7 @@ TEST(SampleCounterTest, EnoughSamples) { EXPECT_THAT(counter.Avg(kMinSamples), Eq(3)); EXPECT_THAT(counter.Sum(kMinSamples), Eq(15)); EXPECT_THAT(counter.Max(), Eq(5)); + EXPECT_THAT(counter.Min(), Eq(1)); } TEST(SampleCounterTest, ComputesVariance) { @@ -74,6 +77,7 @@ TEST(SampleCounterTest, AggregatesTwoCounters) { counter1.Add(counter2); EXPECT_THAT(counter1.Avg(kMinSamples), Eq(3)); EXPECT_THAT(counter1.Max(), Eq(5)); + EXPECT_THAT(counter1.Min(), Eq(1)); EXPECT_THAT(counter1.Variance(kMinSamples), Eq(2)); } diff --git a/rtc_base/openssl_adapter.cc b/rtc_base/openssl_adapter.cc index c68eb22f5c..e48cdf43bd 100644 --- a/rtc_base/openssl_adapter.cc +++ b/rtc_base/openssl_adapter.cc @@ -44,6 +44,7 @@ #include "rtc_base/openssl_identity.h" #endif #include "rtc_base/openssl_utility.h" +#include "rtc_base/strings/str_join.h" #include "rtc_base/strings/string_builder.h" #include "rtc_base/thread.h" @@ -168,23 +169,6 @@ namespace rtc { using ::webrtc::TimeDelta; -namespace webrtc_openssl_adapter_internal { - -// Simple O(n^2) implementation is sufficient for current use case. -std::string StrJoin(const std::vector<std::string>& list, char delimiter) { - RTC_CHECK(!list.empty()); - StringBuilder sb; - sb << list[0]; - for (size_t i = 1; i < list.size(); i++) { - sb.AppendFormat("%c", delimiter); - sb << list[i]; - } - return sb.Release(); -} -} // namespace webrtc_openssl_adapter_internal - -using webrtc_openssl_adapter_internal::StrJoin; - bool OpenSSLAdapter::InitializeSSL() { if (!SSL_library_init()) return false; @@ -373,7 +357,7 @@ int OpenSSLAdapter::BeginSSL() { } if (!elliptic_curves_.empty()) { - SSL_set1_curves_list(ssl_, StrJoin(elliptic_curves_, ':').c_str()); + SSL_set1_curves_list(ssl_, webrtc::StrJoin(elliptic_curves_, ":").c_str()); } // Now that the initial config is done, transfer ownership of `bio` to the diff --git a/rtc_base/openssl_adapter.h b/rtc_base/openssl_adapter.h index 558a04077a..4c05471b2b 100644 --- a/rtc_base/openssl_adapter.h +++ b/rtc_base/openssl_adapter.h @@ -37,14 +37,6 @@ namespace rtc { -namespace webrtc_openssl_adapter_internal { - -// Local definition, since absl::StrJoin is not allow-listed. Declared in header -// file only for unittests. -std::string StrJoin(const std::vector<std::string>& list, char delimiter); - -} // namespace webrtc_openssl_adapter_internal - class OpenSSLAdapter final : public SSLAdapter { public: static bool InitializeSSL(); diff --git a/rtc_base/openssl_adapter_unittest.cc b/rtc_base/openssl_adapter_unittest.cc index ce351dc98e..5b59a8019e 100644 --- a/rtc_base/openssl_adapter_unittest.cc +++ b/rtc_base/openssl_adapter_unittest.cc @@ -116,19 +116,4 @@ TEST(OpenSSLAdapterFactoryTest, CreateWorksWithCustomVerifier) { EXPECT_NE(simple_adapter, nullptr); } -TEST(StrJoinTest, SingleElement) { - EXPECT_EQ(webrtc_openssl_adapter_internal::StrJoin({"a"}, ','), "a"); -} - -TEST(StrJoinTest, TwoElements) { - EXPECT_EQ(webrtc_openssl_adapter_internal::StrJoin({"first", "second"}, ':'), - "first:second"); -} - -TEST(StrJoinTest, WithEmptyElement) { - EXPECT_EQ( - webrtc_openssl_adapter_internal::StrJoin({"first", "", "second"}, ':'), - "first::second"); -} - } // namespace rtc diff --git a/rtc_base/openssl_stream_adapter.cc b/rtc_base/openssl_stream_adapter.cc index cbbb8e96ab..9642674d45 100644 --- a/rtc_base/openssl_stream_adapter.cc +++ b/rtc_base/openssl_stream_adapter.cc @@ -278,21 +278,6 @@ static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) { // OpenSSLStreamAdapter ///////////////////////////////////////////////////////////////////////////// -static std::atomic<bool> g_use_legacy_tls_protocols_override(false); -static std::atomic<bool> g_allow_legacy_tls_protocols(false); - -void SetAllowLegacyTLSProtocols(const absl::optional<bool>& allow) { - g_use_legacy_tls_protocols_override.store(allow.has_value()); - if (allow.has_value()) - g_allow_legacy_tls_protocols.store(allow.value()); -} - -bool ShouldAllowLegacyTLSProtocols() { - return g_use_legacy_tls_protocols_override.load() - ? g_allow_legacy_tls_protocols.load() - : webrtc::field_trial::IsEnabled("WebRTC-LegacyTlsProtocols"); -} - OpenSSLStreamAdapter::OpenSSLStreamAdapter( std::unique_ptr<StreamInterface> stream, absl::AnyInvocable<void(SSLHandshakeError)> handshake_error) @@ -306,10 +291,7 @@ OpenSSLStreamAdapter::OpenSSLStreamAdapter( ssl_(nullptr), ssl_ctx_(nullptr), ssl_mode_(SSL_MODE_TLS), - ssl_max_version_(SSL_PROTOCOL_TLS_12), - // Default is to support legacy TLS protocols. - // This will be changed to default non-support in M82 or M83. - support_legacy_tls_protocols_flag_(ShouldAllowLegacyTLSProtocols()) { + ssl_max_version_(SSL_PROTOCOL_TLS_12) { stream_->SignalEvent.connect(this, &OpenSSLStreamAdapter::OnEvent); } @@ -469,6 +451,17 @@ bool OpenSSLStreamAdapter::ExportKeyingMaterial(absl::string_view label, return true; } +uint16_t OpenSSLStreamAdapter::GetPeerSignatureAlgorithm() const { + if (state_ != SSL_CONNECTED) { + return 0; + } +#ifdef OPENSSL_IS_BORINGSSL + return SSL_get_peer_signature_algorithm(ssl_); +#else + return kSslSignatureAlgorithmUnknown; +#endif +} + bool OpenSSLStreamAdapter::SetDtlsSrtpCryptoSuites( const std::vector<int>& ciphers) { if (state_ != SSL_NONE) { @@ -1020,33 +1013,10 @@ SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() { return nullptr; } - if (support_legacy_tls_protocols_flag_) { - // TODO(https://bugs.webrtc.org/10261): Completely remove this branch in - // M84. - SSL_CTX_set_min_proto_version( - ctx, ssl_mode_ == SSL_MODE_DTLS ? DTLS1_VERSION : TLS1_VERSION); - switch (ssl_max_version_) { - case SSL_PROTOCOL_TLS_10: - SSL_CTX_set_max_proto_version( - ctx, ssl_mode_ == SSL_MODE_DTLS ? DTLS1_VERSION : TLS1_VERSION); - break; - case SSL_PROTOCOL_TLS_11: - SSL_CTX_set_max_proto_version( - ctx, ssl_mode_ == SSL_MODE_DTLS ? DTLS1_VERSION : TLS1_1_VERSION); - break; - case SSL_PROTOCOL_TLS_12: - default: - SSL_CTX_set_max_proto_version( - ctx, ssl_mode_ == SSL_MODE_DTLS ? DTLS1_2_VERSION : TLS1_2_VERSION); - break; - } - } else { - // TODO(https://bugs.webrtc.org/10261): Make this the default in M84. - SSL_CTX_set_min_proto_version( - ctx, ssl_mode_ == SSL_MODE_DTLS ? DTLS1_2_VERSION : TLS1_2_VERSION); - SSL_CTX_set_max_proto_version( - ctx, ssl_mode_ == SSL_MODE_DTLS ? DTLS1_2_VERSION : TLS1_2_VERSION); - } + SSL_CTX_set_min_proto_version( + ctx, ssl_mode_ == SSL_MODE_DTLS ? DTLS1_2_VERSION : TLS1_2_VERSION); + SSL_CTX_set_max_proto_version( + ctx, ssl_mode_ == SSL_MODE_DTLS ? DTLS1_2_VERSION : TLS1_2_VERSION); #ifdef OPENSSL_IS_BORINGSSL // SSL_CTX_set_current_time_cb is only supported in BoringSSL. diff --git a/rtc_base/openssl_stream_adapter.h b/rtc_base/openssl_stream_adapter.h index 579ca2a1f8..34cadeb06c 100644 --- a/rtc_base/openssl_stream_adapter.h +++ b/rtc_base/openssl_stream_adapter.h @@ -66,12 +66,6 @@ class SSLCertChain; /////////////////////////////////////////////////////////////////////////////// -// If `allow` has a value, its value determines if legacy TLS protocols are -// allowed, overriding the default configuration. -// If `allow` has no value, any previous override is removed and the default -// configuration is restored. -RTC_EXPORT void SetAllowLegacyTLSProtocols(const absl::optional<bool>& allow); - class OpenSSLStreamAdapter final : public SSLStreamAdapter, public sigslot::has_slots<> { public: @@ -124,6 +118,8 @@ class OpenSSLStreamAdapter final : public SSLStreamAdapter, uint8_t* result, size_t result_len) override; + uint16_t GetPeerSignatureAlgorithm() const override; + // DTLS-SRTP interface bool SetDtlsSrtpCryptoSuites(const std::vector<int>& crypto_suites) override; bool GetDtlsSrtpCryptoSuite(int* crypto_suite) override; @@ -250,9 +246,6 @@ class OpenSSLStreamAdapter final : public SSLStreamAdapter, // A 50-ms initial timeout ensures rapid setup on fast connections, but may // be too aggressive for low bandwidth links. int dtls_handshake_timeout_ms_ = 50; - - // TODO(https://bugs.webrtc.org/10261): Completely remove this option in M84. - const bool support_legacy_tls_protocols_flag_; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/rtc_base/physical_socket_server.cc b/rtc_base/physical_socket_server.cc index d42168249a..b0af1c20ce 100644 --- a/rtc_base/physical_socket_server.cc +++ b/rtc_base/physical_socket_server.cc @@ -10,6 +10,7 @@ #include "rtc_base/physical_socket_server.h" #include <cstdint> +#include <utility> #if defined(_MSC_VER) && _MSC_VER < 1300 #pragma warning(disable : 4786) @@ -21,7 +22,6 @@ #if defined(WEBRTC_POSIX) #include <fcntl.h> -#include <string.h> #if defined(WEBRTC_USE_EPOLL) // "poll" will be used to wait for the signal dispatcher. #include <poll.h> @@ -30,7 +30,6 @@ #endif #include <sys/ioctl.h> #include <sys/select.h> -#include <sys/time.h> #include <unistd.h> #endif @@ -38,20 +37,18 @@ #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> + #undef SetPort #endif #include <errno.h> -#include <algorithm> -#include <map> - -#include "rtc_base/arraysize.h" -#include "rtc_base/byte_order.h" +#include "rtc_base/async_dns_resolver.h" #include "rtc_base/checks.h" +#include "rtc_base/event.h" +#include "rtc_base/ip_address.h" #include "rtc_base/logging.h" #include "rtc_base/network_monitor.h" -#include "rtc_base/null_socket_server.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/time_utils.h" #include "system_wrappers/include/field_trial.h" @@ -70,6 +67,7 @@ #if defined(WEBRTC_POSIX) #include <netinet/tcp.h> // for TCP_NODELAY + #define IP_MTU 14 // Until this is integrated from linux/in.h to netinet/in.h typedef void* SockOptArg; @@ -252,9 +250,8 @@ int PhysicalSocket::Connect(const SocketAddress& addr) { } if (addr.IsUnresolvedIP()) { RTC_LOG(LS_VERBOSE) << "Resolving addr in PhysicalSocket::Connect"; - resolver_ = new AsyncResolver(); - resolver_->SignalDone.connect(this, &PhysicalSocket::OnResolveResult); - resolver_->Start(addr); + resolver_ = std::make_unique<webrtc::AsyncDnsResolver>(); + resolver_->Start(addr, [this] { OnResolveResult(resolver_->result()); }); state_ = CS_CONNECTING; return 0; } @@ -564,8 +561,7 @@ int PhysicalSocket::Close() { state_ = CS_CLOSED; SetEnabledEvents(0); if (resolver_) { - resolver_->Destroy(false); - resolver_ = nullptr; + resolver_.reset(); } return err; } @@ -589,14 +585,16 @@ int PhysicalSocket::DoSendTo(SOCKET socket, return ::sendto(socket, buf, len, flags, dest_addr, addrlen); } -void PhysicalSocket::OnResolveResult(AsyncResolverInterface* resolver) { - if (resolver != resolver_) { - return; - } - - int error = resolver_->GetError(); +void PhysicalSocket::OnResolveResult( + const webrtc::AsyncDnsResolverResult& result) { + int error = result.GetError(); if (error == 0) { - error = DoConnect(resolver_->address()); + SocketAddress address; + if (result.GetResolvedAddress(AF_INET, &address)) { + error = DoConnect(address); + } else { + Close(); + } } else { Close(); } diff --git a/rtc_base/physical_socket_server.h b/rtc_base/physical_socket_server.h index 650db80931..ea449ff121 100644 --- a/rtc_base/physical_socket_server.h +++ b/rtc_base/physical_socket_server.h @@ -11,17 +11,23 @@ #ifndef RTC_BASE_PHYSICAL_SOCKET_SERVER_H_ #define RTC_BASE_PHYSICAL_SOCKET_SERVER_H_ +#include "api/async_dns_resolver.h" #include "api/units/time_delta.h" +#include "rtc_base/socket.h" +#include "rtc_base/socket_address.h" +#include "rtc_base/third_party/sigslot/sigslot.h" #if defined(WEBRTC_POSIX) #if defined(WEBRTC_LINUX) // On Linux, use epoll. #include <sys/epoll.h> + #define WEBRTC_USE_EPOLL 1 #elif defined(WEBRTC_FUCHSIA) // Fuchsia implements select and poll but not epoll, and testing shows that poll // is faster than select. #include <poll.h> + #define WEBRTC_USE_POLL 1 #else // On other POSIX systems, use select by default. @@ -29,7 +35,9 @@ #endif // WEBRTC_POSIX #include <array> +#include <cstdint> #include <memory> +#include <string> #include <unordered_map> #include <vector> @@ -218,7 +226,7 @@ class PhysicalSocket : public Socket, public sigslot::has_slots<> { SocketAddress* out_addr, int64_t* timestamp); - void OnResolveResult(AsyncResolverInterface* resolver); + void OnResolveResult(const webrtc::AsyncDnsResolverResult& resolver); void UpdateLastError(); void MaybeRemapSendError(); @@ -237,7 +245,7 @@ class PhysicalSocket : public Socket, public sigslot::has_slots<> { mutable webrtc::Mutex mutex_; int error_ RTC_GUARDED_BY(mutex_); ConnState state_; - AsyncResolver* resolver_; + std::unique_ptr<webrtc::AsyncDnsResolverInterface> resolver_; #if !defined(NDEBUG) std::string dbg_addr_; diff --git a/rtc_base/rate_limiter.cc b/rtc_base/rate_limiter.cc index 4740b26f81..0f3f343aed 100644 --- a/rtc_base/rate_limiter.cc +++ b/rtc_base/rate_limiter.cc @@ -14,7 +14,6 @@ #include "absl/types/optional.h" #include "system_wrappers/include/clock.h" -#include "system_wrappers/include/field_trial.h" namespace webrtc { @@ -35,8 +34,7 @@ bool RateLimiter::TryUseRate(size_t packet_size_bytes) { MutexLock lock(&lock_); int64_t now_ms = clock_->TimeInMilliseconds(); absl::optional<uint32_t> current_rate = current_rate_.Rate(now_ms); - if (!webrtc::field_trial::IsEnabled("WebRTC-DisableRtxRateLimiter") && - current_rate) { + if (current_rate) { // If there is a current rate, check if adding bytes would cause maximum // bitrate target to be exceeded. If there is NOT a valid current rate, // allow allocating rate even if target is exceeded. This prevents diff --git a/rtc_base/rate_limiter_unittest.cc b/rtc_base/rate_limiter_unittest.cc index a830446d60..07dda5609e 100644 --- a/rtc_base/rate_limiter_unittest.cc +++ b/rtc_base/rate_limiter_unittest.cc @@ -15,7 +15,6 @@ #include "rtc_base/event.h" #include "rtc_base/platform_thread.h" #include "system_wrappers/include/clock.h" -#include "test/field_trial.h" #include "test/gtest.h" namespace webrtc { @@ -107,19 +106,6 @@ TEST_F(RateLimitTest, WindowSizeLimits) { EXPECT_FALSE(rate_limiter->SetWindowSize(kWindowSizeMs + 1)); } -TEST_F(RateLimitTest, DiablesRtxRateLimiterByFieldTrial) { - webrtc::test::ScopedFieldTrials trial( - "WebRTC-DisableRtxRateLimiter/Enabled/"); - - // Fill rate, extend window to full size. - EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2)); - clock_.AdvanceTimeMilliseconds(kWindowSizeMs - 1); - EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2)); - - // Does not limit rate even when all rate consumed. - EXPECT_TRUE(rate_limiter->TryUseRate(1)); -} - static constexpr TimeDelta kMaxTimeout = TimeDelta::Seconds(30); class ThreadTask { diff --git a/rtc_base/ref_count.h b/rtc_base/ref_count.h index d8d652abd8..60a11fa5c7 100644 --- a/rtc_base/ref_count.h +++ b/rtc_base/ref_count.h @@ -10,57 +10,16 @@ #ifndef RTC_BASE_REF_COUNT_H_ #define RTC_BASE_REF_COUNT_H_ -namespace rtc { - -// Refcounted objects should implement the following informal interface: -// -// void AddRef() const ; -// RefCountReleaseStatus Release() const; -// -// You may access members of a reference-counted object, including the AddRef() -// and Release() methods, only if you already own a reference to it, or if -// you're borrowing someone else's reference. (A newly created object is a -// special case: the reference count is zero on construction, and the code that -// creates the object should immediately call AddRef(), bringing the reference -// count from zero to one, e.g., by constructing an rtc::scoped_refptr). -// -// AddRef() creates a new reference to the object. -// -// Release() releases a reference to the object; the caller now has one less -// reference than before the call. Returns kDroppedLastRef if the number of -// references dropped to zero because of this (in which case the object destroys -// itself). Otherwise, returns kOtherRefsRemained, to signal that at the precise -// time the caller's reference was dropped, other references still remained (but -// if other threads own references, this may of course have changed by the time -// Release() returns). -// -// The caller of Release() must treat it in the same way as a delete operation: -// Regardless of the return value from Release(), the caller mustn't access the -// object. The object might still be alive, due to references held by other -// users of the object, but the object can go away at any time, e.g., as the -// result of another thread calling Release(). -// -// Calling AddRef() and Release() manually is discouraged. It's recommended to -// use rtc::scoped_refptr to manage all pointers to reference counted objects. -// Note that rtc::scoped_refptr depends on compile-time duck-typing; formally -// implementing the below RefCountInterface is not required. +// Transition file for backwards compatibility with source code +// that includes the non-API file. -enum class RefCountReleaseStatus { kDroppedLastRef, kOtherRefsRemained }; +#include "api/ref_count.h" -// Interfaces where refcounting is part of the public api should -// inherit this abstract interface. The implementation of these -// methods is usually provided by the RefCountedObject template class, -// applied as a leaf in the inheritance tree. -class RefCountInterface { - public: - virtual void AddRef() const = 0; - virtual RefCountReleaseStatus Release() const = 0; +namespace rtc { - // Non-public destructor, because Release() has exclusive responsibility for - // destroying the object. - protected: - virtual ~RefCountInterface() {} -}; +// TODO(bugs.webrtc.org/15622): Deprecate and remove these aliases. +using webrtc::RefCountInterface; +using webrtc::RefCountReleaseStatus; } // namespace rtc diff --git a/rtc_base/socket_unittest.cc b/rtc_base/socket_unittest.cc index 0a41a776ac..f5ef2a33fc 100644 --- a/rtc_base/socket_unittest.cc +++ b/rtc_base/socket_unittest.cc @@ -1132,13 +1132,13 @@ void SocketTest::UdpSocketRecvTimestampUseRtcEpoch(const IPAddress& loopback) { client2->SendTo("foo", 3, address); std::unique_ptr<TestClient::Packet> packet_1 = client1->NextPacket(10000); ASSERT_TRUE(packet_1 != nullptr); - EXPECT_NEAR(packet_1->packet_time_us, rtc::TimeMicros(), 1000'000); + EXPECT_NEAR(packet_1->packet_time->us(), rtc::TimeMicros(), 1000'000); Thread::SleepMs(100); client2->SendTo("bar", 3, address); std::unique_ptr<TestClient::Packet> packet_2 = client1->NextPacket(10000); ASSERT_TRUE(packet_2 != nullptr); - EXPECT_GT(packet_2->packet_time_us, packet_1->packet_time_us); - EXPECT_NEAR(packet_2->packet_time_us, rtc::TimeMicros(), 1000'000); + EXPECT_GT(packet_2->packet_time->us(), packet_1->packet_time->us()); + EXPECT_NEAR(packet_2->packet_time->us(), rtc::TimeMicros(), 1000'000); } } // namespace rtc diff --git a/rtc_base/ssl_stream_adapter.h b/rtc_base/ssl_stream_adapter.h index d8b66f11e8..701cc4437b 100644 --- a/rtc_base/ssl_stream_adapter.h +++ b/rtc_base/ssl_stream_adapter.h @@ -39,6 +39,10 @@ constexpr int kSrtpAeadAes128Gcm = 0x0007; constexpr int kSrtpAeadAes256Gcm = 0x0008; constexpr int kSrtpCryptoSuiteMaxValue = 0xFFFF; +// Constants for SSL signature algorithms. +constexpr int kSslSignatureAlgorithmUnknown = 0; +constexpr int kSslSignatureAlgorithmMaxValue = 0xFFFF; + // Names of SRTP profiles listed above. // 128-bit AES with 80-bit SHA-1 HMAC. extern const char kCsAesCm128HmacSha1_80[]; @@ -218,6 +222,9 @@ class SSLStreamAdapter : public StreamInterface { uint8_t* result, size_t result_len); + // Returns the signature algorithm or 0 if not applicable. + virtual uint16_t GetPeerSignatureAlgorithm() const = 0; + // DTLS-SRTP interface virtual bool SetDtlsSrtpCryptoSuites(const std::vector<int>& crypto_suites); virtual bool GetDtlsSrtpCryptoSuite(int* crypto_suite); diff --git a/rtc_base/ssl_stream_adapter_unittest.cc b/rtc_base/ssl_stream_adapter_unittest.cc index 0a99d9b1f0..def4c47c0d 100644 --- a/rtc_base/ssl_stream_adapter_unittest.cc +++ b/rtc_base/ssl_stream_adapter_unittest.cc @@ -31,8 +31,11 @@ #include "rtc_base/ssl_identity.h" #include "rtc_base/stream.h" #include "test/field_trial.h" +#include "test/gmock.h" +#include "test/gtest.h" using ::testing::Combine; +using ::testing::NotNull; using ::testing::tuple; using ::testing::Values; using ::testing::WithParamInterface; @@ -593,9 +596,12 @@ class SSLStreamAdapterTestBase : public ::testing::Test, size_t client_digest_len; bool rv; + ASSERT_THAT(server_identity(), NotNull()); rv = server_identity()->certificate().ComputeDigest( rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len); ASSERT_TRUE(rv); + + ASSERT_THAT(client_identity(), NotNull()); rv = client_identity()->certificate().ComputeDigest( rtc::DIGEST_SHA_1, client_digest, 20, &client_digest_len); ASSERT_TRUE(rv); @@ -1607,11 +1613,14 @@ INSTANTIATE_TEST_SUITE_P( rtc::KeyParams::RSA(1152, 65537), rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)))); -// Tests for enabling / disabling legacy TLS protocols in DTLS. -class SSLStreamAdapterTestDTLSLegacyProtocols +// Tests for enabling the (D)TLS extension permutation which randomizes the +// order of extensions in the client hello. +// These tests are a no-op under OpenSSL. +#ifdef OPENSSL_IS_BORINGSSL +class SSLStreamAdapterTestDTLSExtensionPermutation : public SSLStreamAdapterTestDTLSBase { public: - SSLStreamAdapterTestDTLSLegacyProtocols() + SSLStreamAdapterTestDTLSExtensionPermutation() : SSLStreamAdapterTestDTLSBase(rtc::KeyParams::ECDSA(rtc::EC_NIST_P256), rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)) { } @@ -1650,179 +1659,6 @@ class SSLStreamAdapterTestDTLSLegacyProtocols } }; -// Test getting the used DTLS ciphers. -// DTLS 1.2 enabled for neither client nor server -> DTLS 1.0 will be used. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, TestGetSslCipherSuite) { - ConfigureClient("WebRTC-LegacyTlsProtocols/Enabled/"); - ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/"); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); - TestHandshake(); - - int client_cipher; - ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher)); - int server_cipher; - ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher)); - - ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true)); - ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false)); - - ASSERT_EQ(client_cipher, server_cipher); -} - -// Test getting the used DTLS 1.2 ciphers. -// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslCipherSuiteDtls12Both) { - ConfigureClient(""); - ConfigureServer(""); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12); - TestHandshake(); - - int client_cipher; - ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher)); - int server_cipher; - ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher)); - - ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(true)); - ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(false)); - - ASSERT_EQ(client_cipher, server_cipher); -} - -// DTLS 1.2 enabled for client only -> DTLS 1.0 will be used. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslCipherSuiteDtls12Client) { - ConfigureClient("WebRTC-LegacyTlsProtocols/Enabled/"); - ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/"); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12); - TestHandshake(); - - int client_cipher; - ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher)); - int server_cipher; - ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher)); - - ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true)); - ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false)); - - ASSERT_EQ(client_cipher, server_cipher); -} - -// DTLS 1.2 enabled for server only -> DTLS 1.0 will be used. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslCipherSuiteDtls12Server) { - ConfigureClient("WebRTC-LegacyTlsProtocols/Enabled/"); - ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/"); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_10); - TestHandshake(); - - int client_cipher; - ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher)); - int server_cipher; - ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher)); - - ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true)); - ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false)); - - ASSERT_EQ(client_cipher, server_cipher); -} - -// Client has legacy TLS versions disabled, server has DTLS 1.0 only. -// This is meant to cause a failure. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslVersionLegacyDisabledServer10) { - ConfigureClient(""); - ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/"); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12); - // Handshake should fail. - TestHandshake(false); -} - -// Both client and server have legacy TLS versions disabled and support -// DTLS 1.2. This should work. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslVersionLegacyDisabledServer12) { - ConfigureClient(""); - ConfigureServer(""); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12); - TestHandshake(); -} - -// Both client and server have legacy TLS versions enabled and support DTLS 1.0. -// This should work. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslVersionLegacyEnabledClient10Server10) { - ConfigureClient("WebRTC-LegacyTlsProtocols/Enabled/"); - ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/"); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); - TestHandshake(); -} - -// Legacy protocols are disabled in the client, max TLS version is 1.0 -// This should be a configuration error, and handshake should fail. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslVersionLegacyDisabledClient10Server10) { - ConfigureClient(""); - ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/"); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); - TestHandshake(false); -} - -// Both client and server have legacy TLS versions enabled and support DTLS 1.0. -// This should work. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslVersionLegacyOverrideEnabledClient10Server10) { - rtc::SetAllowLegacyTLSProtocols(true); - ConfigureClient(""); - ConfigureServer(""); - // Remove override. - rtc::SetAllowLegacyTLSProtocols(absl::nullopt); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); - TestHandshake(); -} - -// Client has legacy TLS disabled and server has legacy TLS enabled via -// override. Handshake for DTLS 1.0 should fail. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslVersionLegacyOverrideDisabledClient10EnabledServer10) { - rtc::SetAllowLegacyTLSProtocols(false); - ConfigureClient(""); - rtc::SetAllowLegacyTLSProtocols(true); - ConfigureServer(""); - // Remove override. - rtc::SetAllowLegacyTLSProtocols(absl::nullopt); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); - TestHandshake(false); -} - -// Client has legacy TLS enabled and server has legacy TLS disabled via -// override. Handshake for DTLS 1.0 should fail. -TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, - TestGetSslVersionLegacyOverrideEnabledClient10DisabledServer10) { - rtc::SetAllowLegacyTLSProtocols(true); - ConfigureClient(""); - rtc::SetAllowLegacyTLSProtocols(false); - ConfigureServer(""); - // Remove override. - rtc::SetAllowLegacyTLSProtocols(absl::nullopt); - SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); - TestHandshake(false); -} - -// These tests are a no-op under OpenSSL. -#ifdef OPENSSL_IS_BORINGSSL -// TODO(https://bugs.webrtc.org/10261): when removing -// SSLStreamAdapterTestDTLSLegacyProtocols that this class -// inherits from move the code to this class. -class SSLStreamAdapterTestDTLSExtensionPermutation - : public SSLStreamAdapterTestDTLSLegacyProtocols { - public: - SSLStreamAdapterTestDTLSExtensionPermutation() - : SSLStreamAdapterTestDTLSLegacyProtocols() {} -}; - -// Tests for enabling the (D)TLS extension permutation which randomizes the -// order of extensions in the client hello. TEST_F(SSLStreamAdapterTestDTLSExtensionPermutation, ClientDefaultServerDefault) { ConfigureClient(""); diff --git a/rtc_base/strings/str_join.h b/rtc_base/strings/str_join.h new file mode 100644 index 0000000000..762e63ae2a --- /dev/null +++ b/rtc_base/strings/str_join.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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. + */ +#ifndef RTC_BASE_STRINGS_STR_JOIN_H_ +#define RTC_BASE_STRINGS_STR_JOIN_H_ + +#include <string> + +#include "absl/strings/string_view.h" +#include "rtc_base/strings/string_builder.h" + +namespace webrtc { + +template <typename Range> +std::string StrJoin(const Range& seq, absl::string_view delimiter) { + rtc::StringBuilder sb; + int idx = 0; + + for (const typename Range::value_type& elem : seq) { + if (idx > 0) { + sb << delimiter; + } + sb << elem; + + ++idx; + } + return sb.Release(); +} + +template <typename Range, typename Functor> +std::string StrJoin(const Range& seq, + absl::string_view delimiter, + const Functor& fn) { + rtc::StringBuilder sb; + int idx = 0; + + for (const typename Range::value_type& elem : seq) { + if (idx > 0) { + sb << delimiter; + } + fn(sb, elem); + + ++idx; + } + return sb.Release(); +} + +} // namespace webrtc + +#endif // RTC_BASE_STRINGS_STR_JOIN_H_ diff --git a/rtc_base/strings/str_join_unittest.cc b/rtc_base/strings/str_join_unittest.cc new file mode 100644 index 0000000000..a4ac02125f --- /dev/null +++ b/rtc_base/strings/str_join_unittest.cc @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 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 "rtc_base/strings/str_join.h" + +#include <string> +#include <utility> +#include <vector> + +#include "test/gtest.h" + +namespace webrtc { +namespace { + +TEST(StrJoinTest, CanJoinStringsFromVector) { + std::vector<std::string> strings = {"Hello", "World"}; + std::string s = StrJoin(strings, " "); + EXPECT_EQ(s, "Hello World"); +} + +TEST(StrJoinTest, CanJoinNumbersFromArray) { + std::array<int, 3> numbers = {1, 2, 3}; + std::string s = StrJoin(numbers, ","); + EXPECT_EQ(s, "1,2,3"); +} + +TEST(StrJoinTest, CanFormatElementsWhileJoining) { + std::vector<std::pair<std::string, std::string>> pairs = { + {"hello", "world"}, {"foo", "bar"}, {"fum", "gazonk"}}; + std::string s = StrJoin(pairs, ",", + [&](rtc::StringBuilder& sb, + const std::pair<std::string, std::string>& p) { + sb << p.first << "=" << p.second; + }); + EXPECT_EQ(s, "hello=world,foo=bar,fum=gazonk"); +} + +} // namespace +} // namespace webrtc diff --git a/rtc_base/synchronization/sequence_checker_internal.cc b/rtc_base/synchronization/sequence_checker_internal.cc index 3e205b91d5..4b9583deb2 100644 --- a/rtc_base/synchronization/sequence_checker_internal.cc +++ b/rtc_base/synchronization/sequence_checker_internal.cc @@ -22,6 +22,11 @@ SequenceCheckerImpl::SequenceCheckerImpl(bool attach_to_current_thread) valid_thread_(rtc::CurrentThreadRef()), valid_queue_(TaskQueueBase::Current()) {} +SequenceCheckerImpl::SequenceCheckerImpl(TaskQueueBase* attached_queue) + : attached_(attached_queue != nullptr), + valid_thread_(rtc::PlatformThreadRef()), + valid_queue_(attached_queue) {} + bool SequenceCheckerImpl::IsCurrent() const { const TaskQueueBase* const current_queue = TaskQueueBase::Current(); const rtc::PlatformThreadRef current_thread = rtc::CurrentThreadRef(); diff --git a/rtc_base/synchronization/sequence_checker_internal.h b/rtc_base/synchronization/sequence_checker_internal.h index 22503027a5..a23ac08885 100644 --- a/rtc_base/synchronization/sequence_checker_internal.h +++ b/rtc_base/synchronization/sequence_checker_internal.h @@ -31,6 +31,7 @@ namespace webrtc_sequence_checker_internal { class RTC_EXPORT SequenceCheckerImpl { public: explicit SequenceCheckerImpl(bool attach_to_current_thread); + explicit SequenceCheckerImpl(TaskQueueBase* attached_queue); ~SequenceCheckerImpl() = default; bool IsCurrent() const; @@ -59,6 +60,7 @@ class RTC_EXPORT SequenceCheckerImpl { class SequenceCheckerDoNothing { public: explicit SequenceCheckerDoNothing(bool attach_to_current_thread) {} + explicit SequenceCheckerDoNothing(TaskQueueBase* attached_queue) {} bool IsCurrent() const { return true; } void Detach() {} }; diff --git a/rtc_base/system/file_wrapper.cc b/rtc_base/system/file_wrapper.cc index f7befc6dc5..af34d0e411 100644 --- a/rtc_base/system/file_wrapper.cc +++ b/rtc_base/system/file_wrapper.cc @@ -10,15 +10,19 @@ #include "rtc_base/system/file_wrapper.h" +#include <stddef.h> + #include <cerrno> +#include <cstdint> +#include <string> #include "absl/strings/string_view.h" +#include "rtc_base/checks.h" #include "rtc_base/numerics/safe_conversions.h" #ifdef _WIN32 #include <Windows.h> #else -#include <string.h> #endif #include <utility> diff --git a/rtc_base/system/file_wrapper.h b/rtc_base/system/file_wrapper.h index 5e1e3d6a16..92a552cfd9 100644 --- a/rtc_base/system/file_wrapper.h +++ b/rtc_base/system/file_wrapper.h @@ -12,6 +12,7 @@ #define RTC_BASE_SYSTEM_FILE_WRAPPER_H_ #include <stddef.h> +#include <stdint.h> #include <stdio.h> #include <string> diff --git a/rtc_base/test_client.cc b/rtc_base/test_client.cc index f23ac2aec0..87c946529e 100644 --- a/rtc_base/test_client.cc +++ b/rtc_base/test_client.cc @@ -15,7 +15,9 @@ #include <memory> #include <utility> +#include "api/units/timestamp.h" #include "rtc_base/gunit.h" +#include "rtc_base/network/received_packet.h" #include "rtc_base/thread.h" #include "rtc_base/time_utils.h" @@ -30,10 +32,11 @@ TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket) TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket, ThreadProcessingFakeClock* fake_clock) - : fake_clock_(fake_clock), - socket_(std::move(socket)), - prev_packet_timestamp_(-1) { - socket_->SignalReadPacket.connect(this, &TestClient::OnPacket); + : fake_clock_(fake_clock), socket_(std::move(socket)) { + socket_->RegisterReceivedPacketCallback( + [&](rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) { + OnPacket(socket, packet); + }); socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend); } @@ -100,20 +103,22 @@ bool TestClient::CheckNextPacket(const char* buf, bool res = false; std::unique_ptr<Packet> packet = NextPacket(kTimeoutMs); if (packet) { - res = (packet->size == size && memcmp(packet->buf, buf, size) == 0 && - CheckTimestamp(packet->packet_time_us)); + res = (packet->buf.size() == size && + memcmp(packet->buf.data(), buf, size) == 0 && + CheckTimestamp(packet->packet_time)); if (addr) *addr = packet->addr; } return res; } -bool TestClient::CheckTimestamp(int64_t packet_timestamp) { +bool TestClient::CheckTimestamp( + absl::optional<webrtc::Timestamp> packet_timestamp) { bool res = true; - if (packet_timestamp == -1) { + if (!packet_timestamp) { res = false; } - if (prev_packet_timestamp_ != -1) { + if (prev_packet_timestamp_) { if (packet_timestamp < prev_packet_timestamp_) { res = false; } @@ -145,36 +150,24 @@ int TestClient::SetOption(Socket::Option opt, int value) { } void TestClient::OnPacket(AsyncPacketSocket* socket, - const char* buf, - size_t size, - const SocketAddress& remote_addr, - const int64_t& packet_time_us) { + const rtc::ReceivedPacket& received_packet) { webrtc::MutexLock lock(&mutex_); - packets_.push_back( - std::make_unique<Packet>(remote_addr, buf, size, packet_time_us)); + packets_.push_back(std::make_unique<Packet>(received_packet)); } void TestClient::OnReadyToSend(AsyncPacketSocket* socket) { ++ready_to_send_count_; } -TestClient::Packet::Packet(const SocketAddress& a, - const char* b, - size_t s, - int64_t packet_time_us) - : addr(a), buf(0), size(s), packet_time_us(packet_time_us) { - buf = new char[size]; - memcpy(buf, b, size); -} +TestClient::Packet::Packet(const rtc::ReceivedPacket& received_packet) + : addr(received_packet.source_address()), + // Copy received_packet payload to a buffer owned by Packet. + buf(received_packet.payload().data(), received_packet.payload().size()), + packet_time(received_packet.arrival_time()) {} TestClient::Packet::Packet(const Packet& p) - : addr(p.addr), buf(0), size(p.size), packet_time_us(p.packet_time_us) { - buf = new char[size]; - memcpy(buf, p.buf, size); -} - -TestClient::Packet::~Packet() { - delete[] buf; -} + : addr(p.addr), + buf(p.buf.data(), p.buf.size()), + packet_time(p.packet_time) {} } // namespace rtc diff --git a/rtc_base/test_client.h b/rtc_base/test_client.h index dd91d37ab9..6fe6fd5b83 100644 --- a/rtc_base/test_client.h +++ b/rtc_base/test_client.h @@ -14,8 +14,11 @@ #include <memory> #include <vector> +#include "api/units/timestamp.h" #include "rtc_base/async_udp_socket.h" +#include "rtc_base/buffer.h" #include "rtc_base/fake_clock.h" +#include "rtc_base/network/received_packet.h" #include "rtc_base/synchronization/mutex.h" namespace rtc { @@ -26,17 +29,12 @@ class TestClient : public sigslot::has_slots<> { public: // Records the contents of a packet that was received. struct Packet { - Packet(const SocketAddress& a, - const char* b, - size_t s, - int64_t packet_time_us); + Packet(const rtc::ReceivedPacket& received_packet); Packet(const Packet& p); - virtual ~Packet(); SocketAddress addr; - char* buf; - size_t size; - int64_t packet_time_us; + Buffer buf; + absl::optional<webrtc::Timestamp> packet_time; }; // Default timeout for NextPacket reads. @@ -96,14 +94,11 @@ class TestClient : public sigslot::has_slots<> { static const int kNoPacketTimeoutMs = 1000; // Workaround for the fact that AsyncPacketSocket::GetConnState doesn't exist. Socket::ConnState GetState(); - // Slot for packets read on the socket. + void OnPacket(AsyncPacketSocket* socket, - const char* buf, - size_t len, - const SocketAddress& remote_addr, - const int64_t& packet_time_us); + const rtc::ReceivedPacket& received_packet); void OnReadyToSend(AsyncPacketSocket* socket); - bool CheckTimestamp(int64_t packet_timestamp); + bool CheckTimestamp(absl::optional<webrtc::Timestamp> packet_timestamp); void AdvanceTime(int ms); ThreadProcessingFakeClock* fake_clock_ = nullptr; @@ -111,7 +106,7 @@ class TestClient : public sigslot::has_slots<> { std::unique_ptr<AsyncPacketSocket> socket_; std::vector<std::unique_ptr<Packet>> packets_; int ready_to_send_count_ = 0; - int64_t prev_packet_timestamp_; + absl::optional<webrtc::Timestamp> prev_packet_timestamp_; }; } // namespace rtc |