Skip to content

Commit

Permalink
Merge branch 'main' into update_abseil_less
Browse files Browse the repository at this point in the history
  • Loading branch information
asedeno committed Oct 2, 2024
2 parents 7e1f588 + 520442a commit 9ce666b
Show file tree
Hide file tree
Showing 18 changed files with 102 additions and 321 deletions.
4 changes: 0 additions & 4 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,6 @@ minor_behavior_changes:
change: |
Changes the default value of ``envoy.reloadable_features.http2_use_oghttp2`` to ``false``. This changes the codec used for HTTP/2
requests and responses to address to address stability concerns. This behavior can be reverted by setting the feature to ``true``.
- area: udp
change: |
Set Don't Fragment (DF) flag bit on IP packet header on UDP listener sockets and QUIC upstream connection sockets. This behavior
can be reverted by setting ``envoy.reloadable_features.udp_set_do_not_fragment`` to false.
- area: access_log
change: |
Sanitize SNI for potential log injection. The invalid character will be replaced by ``_`` with an ``invalid:`` marker. If runtime
Expand Down
19 changes: 0 additions & 19 deletions envoy/network/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,25 +175,6 @@ static_assert(IP_RECVDSTADDR == IP_SENDSRCADDR);
#define ENVOY_ATTACH_REUSEPORT_CBPF Network::SocketOptionName()
#endif

#if !defined(ANDROID) && defined(__APPLE__)
// Only include TargetConditionals after testing ANDROID as some Android builds
// on the Mac have this header available and it's not needed unless the target
// is really an Apple platform.
#include <TargetConditionals.h>
#if !defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE
// MAC_OS
#define ENVOY_IP_DONTFRAG ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_DONTFRAG)
#define ENVOY_IPV6_DONTFRAG ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_DONTFRAG)
#endif
#endif

#if !defined(ENVOY_IP_DONTFRAG) && defined(IP_PMTUDISC_DO)
#define ENVOY_IP_MTU_DISCOVER ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_MTU_DISCOVER)
#define ENVOY_IP_MTU_DISCOVER_VALUE IP_PMTUDISC_DO
#define ENVOY_IPV6_MTU_DISCOVER ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_MTU_DISCOVER)
#define ENVOY_IPV6_MTU_DISCOVER_VALUE IPV6_PMTUDISC_DO
#endif

/**
* Interface representing a single filter chain info.
*/
Expand Down
23 changes: 23 additions & 0 deletions source/common/config/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -346,5 +346,28 @@ Utility::buildJitteredExponentialBackOffStrategy(
default_base_interval_ms, default_base_interval_ms * 10, random);
}

absl::Status Utility::validateTerminalFilters(const std::string& name,
const std::string& filter_type,
const std::string& filter_chain_type,
bool is_terminal_filter,
bool last_filter_in_current_config) {
if (is_terminal_filter && !last_filter_in_current_config) {
return absl::InvalidArgumentError(
fmt::format("Error: terminal filter named {} of type {} must be the "
"last filter in a {} filter chain.",
name, filter_type, filter_chain_type));
} else if (!is_terminal_filter && last_filter_in_current_config) {
absl::string_view extra = "";
if (filter_chain_type == "router upstream http") {
extra = " When upstream_http_filters are specified, they must explicitly end with an "
"UpstreamCodec filter.";
}
return absl::InvalidArgumentError(fmt::format("Error: non-terminal filter named {} of type "
"{} is the last filter in a {} filter chain.{}",
name, filter_type, filter_chain_type, extra));
}
return absl::OkStatus();
}

} // namespace Config
} // namespace Envoy
14 changes: 1 addition & 13 deletions source/common/config/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,19 +424,7 @@ class Utility {
const std::string& filter_type,
const std::string& filter_chain_type,
bool is_terminal_filter,
bool last_filter_in_current_config) {
if (is_terminal_filter && !last_filter_in_current_config) {
return absl::InvalidArgumentError(
fmt::format("Error: terminal filter named {} of type {} must be the "
"last filter in a {} filter chain.",
name, filter_type, filter_chain_type));
} else if (!is_terminal_filter && last_filter_in_current_config) {
return absl::InvalidArgumentError(fmt::format(
"Error: non-terminal filter named {} of type {} is the last filter in a {} filter chain.",
name, filter_type, filter_chain_type));
}
return absl::OkStatus();
}
bool last_filter_in_current_config);

/**
* Prepares the DNS failure refresh backoff strategy given the cluster configuration.
Expand Down
7 changes: 0 additions & 7 deletions source/common/listener_manager/listener_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -677,13 +677,6 @@ void ListenerImpl::buildListenSocketOptions(
addListenSocketOptions(listen_socket_options_list_[i],
Network::SocketOptionFactory::buildUdpGroOptions());
}
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.udp_set_do_not_fragment")) {
addListenSocketOptions(
listen_socket_options_list_[i],
Network::SocketOptionFactory::buildDoNotFragmentOptions(
/*mapped_v6*/ addresses_[i]->ip()->version() == Network::Address::IpVersion::v6 &&
!addresses_[i]->ip()->ipv6()->v6only()));
}

// Additional factory specific options.
ASSERT(udp_listener_config_->listener_factory_ != nullptr,
Expand Down
27 changes: 0 additions & 27 deletions source/common/network/socket_option_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,32 +181,5 @@ std::unique_ptr<Socket::Options> SocketOptionFactory::buildIpRecvTosOptions() {
return options;
}

std::unique_ptr<Socket::Options>
SocketOptionFactory::buildDoNotFragmentOptions(bool supports_v4_mapped_v6_addresses) {
auto options = std::make_unique<Socket::Options>();
#ifdef ENVOY_IP_DONTFRAG
options->push_back(std::make_shared<AddrFamilyAwareSocketOptionImpl>(
envoy::config::core::v3::SocketOption::STATE_PREBIND, ENVOY_IP_DONTFRAG, ENVOY_IPV6_DONTFRAG,
1));
// v4 mapped v6 addresses don't support ENVOY_IP_DONTFRAG on MAC OS.
(void)supports_v4_mapped_v6_addresses;
#elif defined(ENVOY_IP_MTU_DISCOVER)
options->push_back(std::make_shared<AddrFamilyAwareSocketOptionImpl>(
envoy::config::core::v3::SocketOption::STATE_PREBIND, ENVOY_IP_MTU_DISCOVER,
ENVOY_IP_MTU_DISCOVER_VALUE, ENVOY_IPV6_MTU_DISCOVER, ENVOY_IPV6_MTU_DISCOVER_VALUE));

if (supports_v4_mapped_v6_addresses) {
ENVOY_LOG_MISC(trace, "Also apply the V4 option to v6 socket to support v4-mapped addresses.");
options->push_back(
std::make_shared<SocketOptionImpl>(envoy::config::core::v3::SocketOption::STATE_PREBIND,
ENVOY_IP_MTU_DISCOVER, ENVOY_IP_MTU_DISCOVER_VALUE));
}
#else
(void)supports_v4_mapped_v6_addresses;
static_assert(false, "Platform supports neither socket option IP_DONTFRAG nor IP_MTU_DISCOVER");
#endif
return options;
}

} // namespace Network
} // namespace Envoy
6 changes: 0 additions & 6 deletions source/common/network/socket_option_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ class SocketOptionFactory : Logger::Loggable<Logger::Id::connection> {
static std::unique_ptr<Socket::Options> buildUdpGroOptions();
static std::unique_ptr<Socket::Options> buildZeroSoLingerOptions();
static std::unique_ptr<Socket::Options> buildIpRecvTosOptions();
/**
* @param supports_v4_mapped_v6_addresses true if this option is to be applied to a v6 socket with
* v4-mapped v6 address(i.e. ::ffff:172.21.0.6) support.
*/
static std::unique_ptr<Socket::Options>
buildDoNotFragmentOptions(bool supports_v4_mapped_v6_addresses);
};
} // namespace Network
} // namespace Envoy
3 changes: 1 addition & 2 deletions source/common/quic/envoy_quic_client_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ class EnvoyQuicClientSession : public QuicFilterManagerConnectionImpl,

// PacketsToReadDelegate
size_t numPacketsExpectedPerEventLoop() const override {
// Do one round of reading per active stream, or to see if there's a new
// active stream.
// Do one round of reading per active stream, or to see if there's a new active stream.
return std::max<size_t>(1, GetNumActiveStreams()) * Network::NUM_DATAGRAMS_PER_RECEIVE;
}

Expand Down
31 changes: 5 additions & 26 deletions source/common/quic/envoy_quic_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ namespace Quic {
namespace {

Network::Address::InstanceConstSharedPtr
getLoopbackAddress(Network::Address::InstanceConstSharedPtr peer_address) {
if (peer_address->ip()->version() == Network::Address::IpVersion::v6) {
return std::make_shared<Network::Address::Ipv6Instance>(
"::1", 0, &peer_address->socketInterface(), peer_address->ip()->ipv6()->v6only());
getLoopbackAddress(const Network::Address::IpVersion version) {
if (version == Network::Address::IpVersion::v6) {
return std::make_shared<Network::Address::Ipv6Instance>("::1");
}
return std::make_shared<Network::Address::Ipv4Instance>("127.0.0.1",
&peer_address->socketInterface());
return std::make_shared<Network::Address::Ipv4Instance>("127.0.0.1");
}

} // namespace
Expand Down Expand Up @@ -202,7 +200,7 @@ createConnectionSocket(const Network::Address::InstanceConstSharedPtr& peer_addr
Network::Socket::Type::Datagram,
// Use the loopback address if `local_addr` is null, to pass in the socket interface used to
// create the IoHandle, without having to make the more expensive `getifaddrs` call.
local_addr ? local_addr : getLoopbackAddress(peer_addr), peer_addr,
local_addr ? local_addr : getLoopbackAddress(peer_addr->ip()->version()), peer_addr,
Network::SocketCreationOptions{false, max_addresses_cache_size});
connection_socket->setDetectedTransportProtocol("quic");
if (!connection_socket->isOpen()) {
Expand All @@ -217,25 +215,6 @@ createConnectionSocket(const Network::Address::InstanceConstSharedPtr& peer_addr
if (prefer_gro && Api::OsSysCallsSingleton::get().supportsUdpGro()) {
connection_socket->addOptions(Network::SocketOptionFactory::buildUdpGroOptions());
}
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.udp_set_do_not_fragment")) {
int v6_only = 0;
if (connection_socket->ipVersion().has_value() &&
connection_socket->ipVersion().value() == Network::Address::IpVersion::v6) {
socklen_t v6_only_len = sizeof(v6_only);
Api::SysCallIntResult result =
connection_socket->getSocketOption(IPPROTO_IPV6, IPV6_V6ONLY, &v6_only, &v6_only_len);
if (result.return_value_ != 0) {
ENVOY_LOG_MISC(
error, "Failed to get IPV6_V6ONLY socket option, getsockopt() returned {}, errno {}",
result.return_value_, result.errno_);
connection_socket->close();
return connection_socket;
}
}
connection_socket->addOptions(Network::SocketOptionFactory::buildDoNotFragmentOptions(
/*mapped_v6*/ connection_socket->ipVersion().value() == Network::Address::IpVersion::v6 &&
v6_only == 0));
}
if (options != nullptr) {
connection_socket->addOptions(options);
}
Expand Down
1 change: 0 additions & 1 deletion source/common/runtime/runtime_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ RUNTIME_GUARD(envoy_reloadable_features_skip_dns_lookup_for_proxied_requests);
RUNTIME_GUARD(envoy_reloadable_features_strict_duration_validation);
RUNTIME_GUARD(envoy_reloadable_features_tcp_tunneling_send_downstream_fin_on_upstream_trailers);
RUNTIME_GUARD(envoy_reloadable_features_test_feature_true);
RUNTIME_GUARD(envoy_reloadable_features_udp_set_do_not_fragment);
RUNTIME_GUARD(envoy_reloadable_features_udp_socket_apply_aggregated_read_limit);
RUNTIME_GUARD(envoy_reloadable_features_uhv_allow_malformed_url_encoding);
RUNTIME_GUARD(envoy_reloadable_features_upstream_remote_address_use_connection);
Expand Down
1 change: 1 addition & 0 deletions test/common/config/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ envoy_cc_test(
"//test/mocks/upstream:thread_local_cluster_mocks",
"//test/test_common:environment_lib",
"//test/test_common:logging_lib",
"//test/test_common:status_utility_lib",
"//test/test_common:test_runtime_lib",
"//test/test_common:utility_lib",
"@com_github_cncf_xds//udpa/type/v1:pkg_cc_proto",
Expand Down
39 changes: 39 additions & 0 deletions test/common/config/utility_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "test/mocks/upstream/thread_local_cluster.h"
#include "test/test_common/environment.h"
#include "test/test_common/logging.h"
#include "test/test_common/status_utility.h"
#include "test/test_common/test_runtime.h"
#include "test/test_common/utility.h"

Expand All @@ -29,6 +30,7 @@
#include "udpa/type/v1/typed_struct.pb.h"
#include "xds/type/v3/typed_struct.pb.h"

using Envoy::StatusHelpers::HasStatusMessage;
using testing::ContainsRegex;
using testing::Eq;
using testing::HasSubstr;
Expand Down Expand Up @@ -894,6 +896,43 @@ TEST(UtilityTest, GetGrpcControlPlane) {
}
}

TEST(UtilityTest, ValidateTerminalFiltersSucceeds) {
EXPECT_OK(Utility::validateTerminalFilters("filter_name", "filter_type", "chain_type",
/*is_terminal_filter=*/true,
/*last_filter_in_current_config=*/true));
EXPECT_OK(Utility::validateTerminalFilters("filter_name", "filter_type", "chain_type",
/*is_terminal_filter=*/false,
/*last_filter_in_current_config=*/false));
}

TEST(UtilityTest, ValidateTerminalFilterFailsWithMisplacedTerminalFilter) {
EXPECT_THAT(
Utility::validateTerminalFilters("filter_name", "filter_type", "chain_type",
/*is_terminal_filter=*/true,
/*last_filter_in_current_config=*/false),
HasStatusMessage("Error: terminal filter named filter_name of type filter_type must be the "
"last filter in a chain_type filter chain."));
}

TEST(UtilityTest, ValidateTerminalFilterFailsWithMissingTerminalFilter) {
EXPECT_THAT(Utility::validateTerminalFilters("filter_name", "filter_type", "chain_type",
/*is_terminal_filter=*/false,
/*last_filter_in_current_config=*/true),
HasStatusMessage("Error: non-terminal filter named filter_name of type "
"filter_type is the last filter in a chain_type filter chain."));
}

TEST(UtilityTest, ValidateTerminalFilterFailsWithMissingUpstreamTerminalFilter) {
EXPECT_THAT(
Utility::validateTerminalFilters("filter_name", "filter_type", "router upstream http",
/*is_terminal_filter=*/false,
/*last_filter_in_current_config=*/true),
HasStatusMessage("Error: non-terminal filter named filter_name of type "
"filter_type is the last filter in a router upstream http filter chain. "
"When upstream_http_filters are specified, they must explicitly end with an "
"UpstreamCodec filter."));
}

} // namespace
} // namespace Config
} // namespace Envoy
Loading

0 comments on commit 9ce666b

Please sign in to comment.