From 3ab0caf5c2775d9f24463bbaf993f2e4f83eb71a Mon Sep 17 00:00:00 2001 From: Ali Beyad Date: Sun, 3 Mar 2024 15:25:04 +0000 Subject: [PATCH] tests Signed-off-by: Ali Beyad --- source/common/network/utility.cc | 1 - source/common/quic/BUILD | 2 + source/common/quic/envoy_quic_utils.cc | 6 +++ test/common/quic/BUILD | 2 + .../quic/envoy_quic_client_session_test.cc | 45 +++++++++++++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/source/common/network/utility.cc b/source/common/network/utility.cc index 6e9f3188d244..53539577239d 100644 --- a/source/common/network/utility.cc +++ b/source/common/network/utility.cc @@ -602,7 +602,6 @@ Api::IoCallUint64Result Utility::readFromSocket(IoHandle& handle, UdpPacketProcessor& udp_packet_processor, MonotonicTime receive_time, bool use_gro, uint32_t* packets_dropped) { - if (use_gro) { Buffer::InstancePtr buffer = std::make_unique(); IoHandle::RecvMsgOutput output(1, packets_dropped); diff --git a/source/common/quic/BUILD b/source/common/quic/BUILD index 6f0315c59fea..50346c554fa6 100644 --- a/source/common/quic/BUILD +++ b/source/common/quic/BUILD @@ -362,6 +362,7 @@ envoy_cc_library( "//envoy/event:dispatcher_interface", "//source/common/network:socket_option_factory_lib", "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/runtime:runtime_lib", "@com_github_google_quiche//:quic_core_connection_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], @@ -435,6 +436,7 @@ envoy_cc_library( "//source/common/network:socket_option_factory_lib", "//source/common/protobuf:utility_lib", "//source/common/quic:quic_io_handle_wrapper_lib", + "//source/common/runtime:runtime_lib", "@com_github_google_quiche//:quic_core_config_lib", "@com_github_google_quiche//:quic_core_http_header_list_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", diff --git a/source/common/quic/envoy_quic_utils.cc b/source/common/quic/envoy_quic_utils.cc index 1d4b0bc68aa6..456041452541 100644 --- a/source/common/quic/envoy_quic_utils.cc +++ b/source/common/quic/envoy_quic_utils.cc @@ -5,10 +5,12 @@ #include "envoy/common/platform.h" #include "envoy/config/core/v3/base.pb.h" +#include "source/common/api/os_sys_calls_impl.h" #include "source/common/http/utility.h" #include "source/common/network/socket_option_factory.h" #include "source/common/network/utility.h" #include "source/common/protobuf/utility.h" +#include "source/common/runtime/runtime_features.h" namespace Envoy { namespace Quic { @@ -149,6 +151,10 @@ createConnectionSocket(const Network::Address::InstanceConstSharedPtr& peer_addr } connection_socket->addOptions(Network::SocketOptionFactory::buildIpPacketInfoOptions()); connection_socket->addOptions(Network::SocketOptionFactory::buildRxQueueOverFlowOptions()); + if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.prefer_udp_gro") && + Api::OsSysCallsSingleton::get().supportsUdpGro()) { + connection_socket->addOptions(Network::SocketOptionFactory::buildUdpGroOptions()); + } if (options != nullptr) { connection_socket->addOptions(options); } diff --git a/test/common/quic/BUILD b/test/common/quic/BUILD index 0d9444d28b12..d41f1d7ebed2 100644 --- a/test/common/quic/BUILD +++ b/test/common/quic/BUILD @@ -191,6 +191,7 @@ envoy_cc_test( deps = [ ":test_utils_lib", "//envoy/stats:stats_macros", + "//source/common/api:os_sys_calls_lib", "//source/common/quic:client_codec_lib", "//source/common/quic:envoy_quic_alarm_factory_lib", "//source/common/quic:envoy_quic_client_connection_lib", @@ -203,6 +204,7 @@ envoy_cc_test( "//test/mocks/stats:stats_mocks", "//test/test_common:logging_lib", "//test/test_common:simulated_time_system_lib", + "//test/test_common:threadsafe_singleton_injector_lib", "@com_github_google_quiche//:quic_test_tools_session_peer_lib", ], ) diff --git a/test/common/quic/envoy_quic_client_session_test.cc b/test/common/quic/envoy_quic_client_session_test.cc index 23a105888b10..950134f8401b 100644 --- a/test/common/quic/envoy_quic_client_session_test.cc +++ b/test/common/quic/envoy_quic_client_session_test.cc @@ -1,5 +1,6 @@ #include "envoy/stats/stats_macros.h" +#include "source/common/api/os_sys_calls_impl.h" #include "source/common/network/transport_socket_options_impl.h" #include "source/common/quic/client_codec_impl.h" #include "source/common/quic/envoy_quic_alarm_factory.h" @@ -18,6 +19,7 @@ #include "test/test_common/logging.h" #include "test/test_common/network_utility.h" #include "test/test_common/simulated_time_system.h" +#include "test/test_common/threadsafe_singleton_injector.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -472,5 +474,48 @@ TEST_P(EnvoyQuicClientSessionTest, StatelessResetOnProbingSocket) { EXPECT_EQ(self_addr_->asString(), quic_connection_->self_address().ToString()); } +class MockOsSysCallsImpl : public Api::OsSysCallsImpl { +public: + MOCK_METHOD(Api::SysCallSizeResult, recvmsg, (os_fd_t socket, msghdr* msg, int flags), + (override)); + MOCK_METHOD(Api::SysCallIntResult, recvmmsg, + (os_fd_t socket, struct mmsghdr* msgvec, unsigned int vlen, int flags, + struct timespec* timeout), + (override)); +}; + +// Ensures that the Network::Utility::readFromSocket function uses GRO instead of `recvmmsg`. +// Only Linux platforms support GRO. +#if defined(__linux__) +TEST_P(EnvoyQuicClientSessionTest, UsesUdpGro) { + MockOsSysCallsImpl os_sys_calls_; + TestThreadsafeSingletonInjector singleton_injector_{&os_sys_calls_}; + + // Have to connect the QUIC session, so that the socket is set up so we can do I/O on it. + envoy_quic_session_.connect(); + + std::string write_data = "abc"; + Buffer::RawSlice slice; + slice.mem_ = write_data.data(); + slice.len_ = write_data.length(); + + // GRO uses `recvmsg`, not `recvmmsg`. + EXPECT_CALL(os_sys_calls_, recvmmsg(_, _, _, _, _)).Times(0); + EXPECT_CALL(os_sys_calls_, recvmsg(_, _, _)) + .WillOnce( + Invoke([&](os_fd_t /*socket*/, msghdr* /*msg*/, int /*flags*/) -> Api::SysCallSizeResult { + dispatcher_->exit(); + // Return an error so IoSocketHandleImpl::recvmsg() exits early, instead of trying to + // use the msghdr that would normally have been populated by recvmsg but is not + // populated by this mock. + return {-1, SOCKET_ERROR_AGAIN}; + })); + + peer_socket_->ioHandle().sendmsg(&slice, 1, 0, peer_addr_->ip(), *self_addr_); + + dispatcher_->run(Event::Dispatcher::RunType::RunUntilExit); +} +#endif + } // namespace Quic } // namespace Envoy