Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into xds_failover_plumb_api
Browse files Browse the repository at this point in the history
Signed-off-by: Adi Suissa-Peleg <[email protected]>
  • Loading branch information
adisuissa committed Jun 27, 2024
2 parents 5de301a + dd3bdac commit be6e38f
Show file tree
Hide file tree
Showing 44 changed files with 1,575 additions and 206 deletions.
10 changes: 10 additions & 0 deletions api/envoy/extensions/filters/http/composite/v3/composite.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";

package envoy.extensions.filters.http.composite.v3;

import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/config_source.proto";
import "envoy/config/core/v3/extension.proto";

Expand Down Expand Up @@ -57,4 +58,13 @@ message ExecuteFilterAction {
// Only one of ``typed_config`` or ``dynamic_config`` can be set.
DynamicConfig dynamic_config = 2
[(udpa.annotations.field_migrate).oneof_promotion = "config_type"];

// Probability of the action execution. If not specified, this is 100%.
// This allows sampling behavior for the configured actions.
// For example, if
// :ref:`default_value <envoy_v3_api_field_config.core.v3.RuntimeFractionalPercent.default_value>`
// under the ``sample_percent`` is configured with 30%, a dice roll with that
// probability is done. The underline action will only be executed if the
// dice roll returns positive. Otherwise, the action is skipped.
config.core.v3.RuntimeFractionalPercent sample_percent = 3;
}
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ message RemoteJwks {
// cluster: jwt.www.googleapis.com|443
// timeout: 1s
//
config.core.v3.HttpUri http_uri = 1;
config.core.v3.HttpUri http_uri = 1 [(validate.rules).message = {required: true}];

// Duration after which the cached JWKS should be expired. If not specified, default cache
// duration is 10 minutes.
Expand Down
19 changes: 19 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,20 @@ behavior_changes:
:ref:`TlvsMetadata type <envoy_v3_api_msg_data.core.v3.TlvsMetadata>`.
This change can be temporarily disabled by setting the runtime flag
``envoy.reloadable_features.use_typed_metadata_in_proxy_protocol_listener`` to ``false``.
- area: composite_filter
change: |
Adding support for
:ref:`sample_percent <envoy_v3_api_field_extensions.filters.http.composite.v3.ExecuteFilterAction.sample_percent>`.
It specifies the probability of the action execution. If not specified, it is 100%.
- area: golang
change: |
Move ``Continue``, ``SendLocalReply`` and ``RecoverPanic` from ``FilterCallbackHandler`` to ``DecoderFilterCallbacks`` and
``EncoderFilterCallbacks``, to support full-duplex processing.
- area: ext_proc
change: |
Added support for observability mode. If enabled, each part of the HTTP request or response specified by ProcessingMode
is sent without waiting for the response from the ext_proc service. It is "Send and Go" mode that can be used by external
processor to observe Envoy data and status.
minor_behavior_changes:
# *Changes that may cause incompatibilities for some users, but should not for most*
Expand Down Expand Up @@ -108,6 +118,11 @@ minor_behavior_changes:
- area: filters
change: |
Set ``WWW-Authenticate`` header for 401 responses from the Basic Auth filter.
- area: jwt_authn
change: |
jwt_authn now validates provider URIs. If the validation is too strict it can temporarily be
disabled by setting the runtime guard ``envoy.reloadable_features.jwt_authn_validate_uri`` to
false.
- area: http
change: |
Removed runtime guard ``envoy.reloadable_features.refresh_rtt_after_request`` and legacy code path.
Expand Down Expand Up @@ -203,6 +218,10 @@ bug_fixes:
change: |
Fixed missing :ref:`additional addresses <envoy_v3_api_msg_config.endpoint.v3.Endpoint.AdditionalAddress>`
for :ref:`LbEndpoint <envoy_v3_api_field_config.endpoint.v3.LbEndpoint.endpoint>` in config dump.
- area: http
change: |
Fixed a bug where additional :ref:`cookie attributes <envoy_v3_api_msg_config.route.v3.RouteAction.HashPolicy.cookie>`
are not sent properly to clients.
removed_config_or_runtime:
# *Normally occurs at the end of the* :ref:`deprecation period <deprecated>`
Expand Down
19 changes: 19 additions & 0 deletions envoy/upstream/upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,25 @@ class Host : virtual public HostDescription {
* Set true to disable active health check for the host.
*/
virtual void setDisableActiveHealthCheck(bool disable_active_health_check) PURE;

/**
* Base interface for attaching LbPolicy-specific data to individual hosts.
*/
class HostLbPolicyData {
public:
virtual ~HostLbPolicyData() = default;
};
using HostLbPolicyDataPtr = std::shared_ptr<HostLbPolicyData>;

/* Takes ownership of lb_policy_data and attaches it to the host.
* Must be called before the host is used across threads.
*/
virtual void setLbPolicyData(HostLbPolicyDataPtr lb_policy_data) PURE;

/*
* @return a reference to the LbPolicyData attached to the host.
*/
virtual const HostLbPolicyDataPtr& lbPolicyData() const PURE;
};

using HostConstSharedPtr = std::shared_ptr<const Host>;
Expand Down
14 changes: 9 additions & 5 deletions source/common/common/random_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
namespace Envoy {
namespace Random {

const size_t RandomGeneratorImpl::UUID_LENGTH = 36;
constexpr size_t CONSTEXPR_UUID_LENGTH = 36;
const size_t RandomGeneratorImpl::UUID_LENGTH = CONSTEXPR_UUID_LENGTH;

uint64_t RandomGeneratorImpl::random() {
uint64_t RandomUtility::random() {
// Prefetch 256 * sizeof(uint64_t) bytes of randomness. buffered_idx is initialized to 256,
// i.e. out-of-range value, so the buffer will be filled with randomness on the first call
// to this function.
Expand Down Expand Up @@ -46,7 +47,7 @@ uint64_t RandomGeneratorImpl::random() {
return buffered[buffered_idx++];
}

std::string RandomGeneratorImpl::uuid() {
std::string RandomUtility::uuid() {
// Prefetch 2048 bytes of randomness. buffered_idx is initialized to sizeof(buffered),
// i.e. out-of-range value, so the buffer will be filled with randomness on the first
// call to this function.
Expand Down Expand Up @@ -88,7 +89,7 @@ std::string RandomGeneratorImpl::uuid() {

// Convert UUID to a string representation, e.g. a121e9e1-feae-4136-9e0e-6fac343d56c9.
static const char* const hex = "0123456789abcdef";
char uuid[UUID_LENGTH];
char uuid[CONSTEXPR_UUID_LENGTH];

for (uint8_t i = 0; i < 4; i++) {
const uint8_t d = rand[i];
Expand Down Expand Up @@ -128,8 +129,11 @@ std::string RandomGeneratorImpl::uuid() {
uuid[2 * i + 5] = hex[d & 0x0f];
}

return {uuid, UUID_LENGTH};
return {uuid, CONSTEXPR_UUID_LENGTH};
}

uint64_t RandomGeneratorImpl::random() { return RandomUtility::random(); }
std::string RandomGeneratorImpl::uuid() { return RandomUtility::uuid(); }

} // namespace Random
} // namespace Envoy
12 changes: 12 additions & 0 deletions source/common/common/random_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

namespace Envoy {
namespace Random {

/**
* Utility class for generating random numbers and UUIDs. These methods in class are thread-safe.
* NOTE: The RandomGenerator from FactoryContext should be used as priority. Only use this class
* when RandomGenerator is not available and unit test mocking is not needed.
*/
class RandomUtility {
public:
static uint64_t random();
static std::string uuid();
};

/**
* Implementation of RandomGenerator that uses per-thread RANLUX generators seeded with current
* time.
Expand Down
14 changes: 11 additions & 3 deletions source/common/http/hash_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ class CookieHashMethod : public HashMethodImplBase {
CookieHashMethod(const std::string& key, const std::string& path,
const absl::optional<std::chrono::seconds>& ttl, bool terminal,
const CookieAttributeRefVector attributes)
: HashMethodImplBase(terminal), key_(key), path_(path), ttl_(ttl), attributes_(attributes) {}
: HashMethodImplBase(terminal), key_(key), path_(path), ttl_(ttl) {
for (const auto& attribute : attributes) {
attributes_.push_back(attribute);
}
}

absl::optional<uint64_t> evaluate(const Network::Address::Instance*,
const RequestHeaderMap& headers,
Expand All @@ -91,7 +95,11 @@ class CookieHashMethod : public HashMethodImplBase {
absl::optional<uint64_t> hash;
std::string value = Utility::parseCookieValue(headers, key_);
if (value.empty() && ttl_.has_value()) {
value = add_cookie(key_, path_, ttl_.value(), attributes_);
CookieAttributeRefVector attributes;
for (const auto& attribute : attributes_) {
attributes.push_back(attribute);
}
value = add_cookie(key_, path_, ttl_.value(), attributes);
hash = HashUtil::xxHash64(value);

} else if (!value.empty()) {
Expand All @@ -104,7 +112,7 @@ class CookieHashMethod : public HashMethodImplBase {
const std::string key_;
const std::string path_;
const absl::optional<std::chrono::seconds> ttl_;
const CookieAttributeRefVector attributes_;
std::vector<CookieAttribute> attributes_;
};

class IpHashMethod : public HashMethodImplBase {
Expand Down
1 change: 1 addition & 0 deletions source/common/http/http1/balsa_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ BalsaParser::BalsaParser(MessageType type, ParserCallbacks* connection, size_t m
http_validation_policy.require_content_length_if_body_required = false;
http_validation_policy.disallow_invalid_header_characters_in_response = true;
http_validation_policy.disallow_lone_cr_in_request_headers = true;
http_validation_policy.disallow_lone_cr_in_chunk_extension = true;
framer_.set_http_validation_policy(http_validation_policy);

framer_.set_balsa_headers(&headers_);
Expand Down
1 change: 1 addition & 0 deletions source/common/runtime/runtime_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ RUNTIME_GUARD(envoy_reloadable_features_http_filter_avoid_reentrant_local_reply)
RUNTIME_GUARD(envoy_reloadable_features_http_reject_path_with_fragment);
RUNTIME_GUARD(envoy_reloadable_features_http_route_connect_proxy_by_default);
RUNTIME_GUARD(envoy_reloadable_features_immediate_response_use_filter_mutation_rule);
RUNTIME_GUARD(envoy_reloadable_features_jwt_authn_validate_uri);
RUNTIME_GUARD(envoy_reloadable_features_no_downgrade_to_canonical_name);
RUNTIME_GUARD(envoy_reloadable_features_no_extension_lookup_by_name);
RUNTIME_GUARD(envoy_reloadable_features_normalize_host_for_preresolve_dfp_dns);
Expand Down
3 changes: 2 additions & 1 deletion source/common/tls/client_ssl_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ class ClientSslSocketFactory : public Network::CommonUpstreamTransportSocketFact

Envoy::Ssl::ClientContextSharedPtr sslCtx() override;

private:
protected:
ClientSslSocketFactory(Envoy::Ssl::ClientContextConfigPtr config,
Envoy::Ssl::ContextManager& manager, Stats::Scope& stats_scope,
absl::Status& creation_status);

private:
Envoy::Ssl::ContextManager& manager_;
Stats::Scope& stats_scope_;
SslSocketFactoryStats stats_;
Expand Down
6 changes: 5 additions & 1 deletion source/common/tls/ssl_socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ void SslSocket::drainErrorQueue() {
absl::NullSafeStringView(ERR_reason_error_string(err)));
}

if (!saw_error) {
return;
}

if (!failure_reason_.empty()) {
if (new_ssl_failure_format) {
absl::StrAppend(&failure_reason_, ":TLS_error_end");
Expand All @@ -247,7 +251,7 @@ void SslSocket::drainErrorQueue() {
failure_reason_);
}

if (saw_error && !saw_counted_error) {
if (!saw_counted_error) {
ctx_->stats().connection_error_.inc();
}
}
Expand Down
6 changes: 6 additions & 0 deletions source/common/upstream/upstream_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,11 @@ class HostImplBase : public Host,
return std::make_unique<HostHandleImpl>(shared_from_this());
}

void setLbPolicyData(HostLbPolicyDataPtr lb_policy_data) override {
lb_policy_data_ = std::move(lb_policy_data);
}
const HostLbPolicyDataPtr& lbPolicyData() const override { return lb_policy_data_; }

protected:
static CreateConnectionData
createConnection(Event::Dispatcher& dispatcher, const ClusterInfo& cluster,
Expand All @@ -437,6 +442,7 @@ class HostImplBase : public Host,
// flag access? May be we could refactor HealthFlag to contain all these statuses and flags in the
// future.
std::atomic<Host::HealthStatus> eds_health_status_{};
HostLbPolicyDataPtr lb_policy_data_;

struct HostHandleImpl : HostHandle {
HostHandleImpl(const std::shared_ptr<const HostImplBase>& parent) : parent_(parent) {
Expand Down
51 changes: 35 additions & 16 deletions source/extensions/filters/http/composite/action.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ void ExecuteFilterAction::createFilters(Http::FilterChainFactoryCallbacks& callb
cb_(callbacks);
}

bool ExecuteFilterActionFactory::isSampled(
const envoy::extensions::filters::http::composite::v3::ExecuteFilterAction& composite_action,
Envoy::Runtime::Loader& runtime) {
if (composite_action.has_sample_percent() &&
!runtime.snapshot().featureEnabled(composite_action.sample_percent().runtime_key(),
composite_action.sample_percent().default_value())) {
return false;
}
return true;
}

Matcher::ActionFactoryCb ExecuteFilterActionFactory::createActionFactoryCb(
const Protobuf::Message& config, Http::Matching::HttpFilterActionContext& context,
ProtobufMessage::ValidationVisitor& validation_visitor) {
Expand Down Expand Up @@ -66,6 +77,28 @@ Matcher::ActionFactoryCb ExecuteFilterActionFactory::createDynamicActionFactoryC
provider_manager);
}

Matcher::ActionFactoryCb ExecuteFilterActionFactory::createActionFactoryCbCommon(
const envoy::extensions::filters::http::composite::v3::ExecuteFilterAction& composite_action,
Http::Matching::HttpFilterActionContext& context, Envoy::Http::FilterFactoryCb& callback,
bool is_downstream) {
const std::string stream_str = is_downstream ? "downstream" : "upstream";

if (callback == nullptr) {
throw EnvoyException(
fmt::format("Failed to get {} filter factory creation function", stream_str));
}
std::string name = composite_action.typed_config().name();
ASSERT(context.server_factory_context_ != absl::nullopt);
Envoy::Runtime::Loader& runtime = context.server_factory_context_->runtime();
return [cb = std::move(callback), n = std::move(name),
composite_action = std::move(composite_action), &runtime, this]() -> Matcher::ActionPtr {
if (!isSampled(composite_action, runtime)) {
return nullptr;
}
return std::make_unique<ExecuteFilterAction>(cb, n);
};
}

Matcher::ActionFactoryCb ExecuteFilterActionFactory::createStaticActionFactoryCbDownstream(
const envoy::extensions::filters::http::composite::v3::ExecuteFilterAction& composite_action,
Http::Matching::HttpFilterActionContext& context,
Expand Down Expand Up @@ -93,14 +126,7 @@ Matcher::ActionFactoryCb ExecuteFilterActionFactory::createStaticActionFactoryCb
*message, context.stat_prefix_, context.server_factory_context_.value());
}

if (callback == nullptr) {
throw EnvoyException("Failed to get downstream filter factory creation function");
}
std::string name = composite_action.typed_config().name();

return [cb = std::move(callback), n = std::move(name)]() -> Matcher::ActionPtr {
return std::make_unique<ExecuteFilterAction>(cb, n);
};
return createActionFactoryCbCommon(composite_action, context, callback, true);
}

Matcher::ActionFactoryCb ExecuteFilterActionFactory::createStaticActionFactoryCbUpstream(
Expand All @@ -124,14 +150,7 @@ Matcher::ActionFactoryCb ExecuteFilterActionFactory::createStaticActionFactoryCb
callback = callback_or_status.value();
}

if (callback == nullptr) {
throw EnvoyException("Failed to get upstream filter factory creation function");
}
std::string name = composite_action.typed_config().name();

return [cb = std::move(callback), n = std::move(name)]() -> Matcher::ActionPtr {
return std::make_unique<ExecuteFilterAction>(cb, n);
};
return createActionFactoryCbCommon(composite_action, context, callback, false);
}

REGISTER_FACTORY(ExecuteFilterActionFactory,
Expand Down
Loading

0 comments on commit be6e38f

Please sign in to comment.