Merge pull request #24285 from yashykt/cdsresponseupdate

Update Cds response parsing for tls
pull/24304/head
Yash Tibrewal 4 years ago committed by GitHub
commit 73d7ee5d51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 158
      src/core/ext/xds/xds_api.cc
  2. 52
      src/core/ext/xds/xds_api.h

@ -56,6 +56,8 @@
#include "envoy/config/route/v3/route.upb.h"
#include "envoy/config/route/v3/route_components.upb.h"
#include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h"
#include "envoy/extensions/transport_sockets/tls/v3/common.upb.h"
#include "envoy/extensions/transport_sockets/tls/v3/tls.upb.h"
#include "envoy/service/cluster/v3/cds.upb.h"
#include "envoy/service/discovery/v3/discovery.upb.h"
#include "envoy/service/endpoint/v3/eds.upb.h"
@ -63,6 +65,7 @@
#include "envoy/service/load_stats/v3/lrs.upb.h"
#include "envoy/service/route/v3/rds.upb.h"
#include "envoy/type/matcher/v3/regex.upb.h"
#include "envoy/type/matcher/v3/string.upb.h"
#include "envoy/type/v3/percent.upb.h"
#include "envoy/type/v3/range.upb.h"
#include "google/protobuf/any.upb.h"
@ -375,6 +378,44 @@ XdsApi::RdsUpdate::VirtualHost* XdsApi::RdsUpdate::FindVirtualHostForDomain(
return target_vhost;
}
//
// XdsApi::StringMatcher
//
XdsApi::StringMatcher::StringMatcher(const StringMatcher& other)
: type(other.type) {
switch (type) {
case StringMatcherType::SAFE_REGEX:
regex_match = absl::make_unique<RE2>(other.regex_match->pattern());
break;
default:
string_matcher = other.string_matcher;
}
}
XdsApi::StringMatcher& XdsApi::StringMatcher::operator=(
const StringMatcher& other) {
type = other.type;
switch (type) {
case StringMatcherType::SAFE_REGEX:
regex_match = absl::make_unique<RE2>(other.regex_match->pattern());
break;
default:
string_matcher = other.string_matcher;
}
return *this;
}
bool XdsApi::StringMatcher::operator==(const StringMatcher& other) const {
if (type != other.type) return false;
switch (type) {
case StringMatcherType::SAFE_REGEX:
return regex_match->pattern() != other.regex_match->pattern();
default:
return string_matcher != other.string_matcher;
}
}
//
// XdsApi::EdsUpdate
//
@ -1758,6 +1799,92 @@ grpc_error* RdsResponseParse(
return GRPC_ERROR_NONE;
}
grpc_error* CommonTlsContextParse(
const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*
common_tls_context_proto,
XdsApi::CommonTlsContext* common_tls_context) GRPC_MUST_USE_RESULT;
grpc_error* CommonTlsContextParse(
const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*
common_tls_context_proto,
XdsApi::CommonTlsContext* common_tls_context) {
auto* combined_validation_context =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_combined_validation_context(
common_tls_context_proto);
if (combined_validation_context != nullptr) {
auto* default_validation_context =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(
combined_validation_context);
if (default_validation_context != nullptr) {
size_t len = 0;
auto* subject_alt_names_matchers =
envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_match_subject_alt_names(
default_validation_context, &len);
for (size_t i = 0; i < len; ++i) {
XdsApi::StringMatcher matcher;
if (envoy_type_matcher_v3_StringMatcher_has_exact(
subject_alt_names_matchers[i])) {
matcher.type = XdsApi::StringMatcher::StringMatcherType::EXACT;
matcher.string_matcher =
UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_exact(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_prefix(
subject_alt_names_matchers[i])) {
matcher.type = XdsApi::StringMatcher::StringMatcherType::PREFIX;
matcher.string_matcher =
UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_prefix(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_suffix(
subject_alt_names_matchers[i])) {
matcher.type = XdsApi::StringMatcher::StringMatcherType::SUFFIX;
matcher.string_matcher =
UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_suffix(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_safe_regex(
subject_alt_names_matchers[i])) {
matcher.type = XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX;
auto* regex_matcher = envoy_type_matcher_v3_StringMatcher_safe_regex(
subject_alt_names_matchers[i]);
std::unique_ptr<RE2> regex =
absl::make_unique<RE2>(UpbStringToStdString(
envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher)));
if (!regex->ok()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid regex string specified in string matcher.");
}
matcher.regex_match = std::move(regex);
} else {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid StringMatcher specified");
}
matcher.ignore_case = envoy_type_matcher_v3_StringMatcher_ignore_case(
subject_alt_names_matchers[i]);
common_tls_context->combined_validation_context
.default_validation_context.match_subject_alt_names.emplace_back(
matcher);
}
}
auto* validation_context_certificate_provider_instance =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_certificate_provider_instance(
combined_validation_context);
if (validation_context_certificate_provider_instance != nullptr) {
common_tls_context->combined_validation_context
.validation_context_certificate_provider_instance = UpbStringToStdString(
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_instance_name(
validation_context_certificate_provider_instance));
}
}
auto* tls_certificate_certificate_provider_instance =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider_instance(
common_tls_context_proto);
if (tls_certificate_certificate_provider_instance != nullptr) {
common_tls_context
->tls_certificate_certificate_provider_instance = UpbStringToStdString(
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_instance_name(
tls_certificate_certificate_provider_instance));
}
return GRPC_ERROR_NONE;
}
grpc_error* CdsResponseParse(
XdsClient* client, TraceFlag* tracer,
const envoy_service_discovery_v3_DiscoveryResponse* response,
@ -1829,6 +1956,37 @@ grpc_error* CdsResponseParse(
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"LB policy is not ROUND_ROBIN.");
}
// Record Upstream tls context
auto* transport_socket =
envoy_config_cluster_v3_Cluster_transport_socket(cluster);
if (transport_socket != nullptr) {
absl::string_view name = UpbStringToAbsl(
envoy_config_core_v3_TransportSocket_name(transport_socket));
if (name == "tls") {
auto* typed_config =
envoy_config_core_v3_TransportSocket_typed_config(transport_socket);
if (typed_config != nullptr) {
const upb_strview encoded_upstream_tls_context =
google_protobuf_Any_value(typed_config);
auto* upstream_tls_context =
envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_parse(
encoded_upstream_tls_context.data,
encoded_upstream_tls_context.size, arena);
if (upstream_tls_context == nullptr) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Can't decode upstream tls context.");
}
auto* common_tls_context =
envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_common_tls_context(
upstream_tls_context);
if (common_tls_context != nullptr) {
grpc_error* error = CommonTlsContextParse(
common_tls_context, &cds_update.common_tls_context);
if (error != GRPC_ERROR_NONE) return error;
}
}
}
}
// Record LRS server name (if any).
const envoy_config_core_v3_ConfigSource* lrs_server =
envoy_config_cluster_v3_Cluster_lrs_server(cluster);

@ -150,6 +150,55 @@ class XdsApi {
VirtualHost* FindVirtualHostForDomain(const std::string& domain);
};
struct StringMatcher {
enum class StringMatcherType {
EXACT, // value stored in string_matcher_field
PREFIX, // value stored in string_matcher_field
SUFFIX, // value stored in string_matcher_field
SAFE_REGEX, // use regex_match field
CONTAINS, // value stored in string_matcher_field
};
StringMatcherType type;
std::string string_matcher;
std::unique_ptr<RE2> regex_match;
bool ignore_case;
StringMatcher() = default;
StringMatcher(const StringMatcher& other);
StringMatcher& operator=(const StringMatcher& other);
bool operator==(const StringMatcher& other) const;
};
struct CommonTlsContext {
struct CertificateValidationContext {
std::vector<StringMatcher> match_subject_alt_names;
bool operator==(const CertificateValidationContext& other) const {
return match_subject_alt_names == other.match_subject_alt_names;
}
};
struct CombinedCertificateValidationContext {
CertificateValidationContext default_validation_context;
std::string validation_context_certificate_provider_instance;
bool operator==(const CombinedCertificateValidationContext& other) const {
return default_validation_context == other.default_validation_context &&
validation_context_certificate_provider_instance ==
other.validation_context_certificate_provider_instance;
}
};
std::string tls_certificate_certificate_provider_instance;
CombinedCertificateValidationContext combined_validation_context;
bool operator==(const CommonTlsContext& other) const {
return tls_certificate_certificate_provider_instance ==
other.tls_certificate_certificate_provider_instance &&
combined_validation_context == other.combined_validation_context;
}
};
// TODO(roth): When we can use absl::variant<>, consider using that
// here, to enforce the fact that only one of the two fields can be set.
struct LdsUpdate {
@ -173,6 +222,8 @@ class XdsApi {
// The name to use in the EDS request.
// If empty, the cluster name will be used.
std::string eds_service_name;
// Tls Context used by clients
CommonTlsContext common_tls_context;
// The LRS server to use for load reporting.
// If not set, load reporting will be disabled.
// If set to the empty string, will use the same server we obtained the CDS
@ -184,6 +235,7 @@ class XdsApi {
bool operator==(const CdsUpdate& other) const {
return eds_service_name == other.eds_service_name &&
common_tls_context == other.common_tls_context &&
lrs_load_reporting_server_name ==
other.lrs_load_reporting_server_name &&
max_concurrent_requests == other.max_concurrent_requests;

Loading…
Cancel
Save