24 #include <type_traits>
27 #include "absl/memory/memory.h"
28 #include "absl/status/status.h"
29 #include "absl/strings/str_cat.h"
30 #include "absl/strings/str_format.h"
31 #include "absl/strings/str_join.h"
71 return absl::StrFormat(
"common_tls_context=%s, require_client_certificate=%s",
77 return common_tls_context.Empty();
87 "route_config_name=%s",
88 !route_config_name.empty() ? route_config_name.c_str() :
"<inlined>"));
90 http_max_stream_duration.ToString()));
95 if (!http_filters.empty()) {
96 std::vector<std::string> filter_strings;
97 for (
const auto& http_filter : http_filters) {
98 filter_strings.push_back(http_filter.ToString());
121 "{downstream_tls_context=", downstream_tls_context.ToString(),
133 addr_str.ok() ? addr_str.value() : addr_str.status().ToString(),
134 ", prefix_len=", prefix_len,
"}");
147 std::vector<XdsListenerResource::FilterChainMap::CidrRange>
155 } filter_chain_match;
162 if (destination_port != 0) {
165 if (!prefix_ranges.empty()) {
166 std::vector<std::string> prefix_ranges_content;
167 for (
const auto&
range : prefix_ranges) {
168 prefix_ranges_content.push_back(
range.ToString());
171 "prefix_ranges={",
absl::StrJoin(prefix_ranges_content,
", "),
"}"));
175 contents.push_back(
"source_type=SAME_IP_OR_LOOPBACK");
177 ConnectionSourceType::kExternal) {
178 contents.push_back(
"source_type=EXTERNAL");
180 if (!source_prefix_ranges.empty()) {
181 std::vector<std::string> source_prefix_ranges_content;
182 for (
const auto&
range : source_prefix_ranges) {
183 source_prefix_ranges_content.push_back(
range.ToString());
189 if (!source_ports.empty()) {
193 if (!server_names.empty()) {
197 if (!transport_protocol.empty()) {
200 if (!application_protocols.empty()) {
214 for (
const auto& destination_ip : destination_ip_vector) {
215 for (
int source_type = 0; source_type < 3; ++source_type) {
216 for (
const auto& source_ip :
217 destination_ip.source_types_array[source_type]) {
218 for (
const auto& source_port_pair : source_ip.ports_map) {
220 if (destination_ip.prefix_range.has_value()) {
222 *destination_ip.prefix_range);
227 if (source_ip.prefix_range.has_value()) {
229 *source_ip.prefix_range);
231 if (source_port_pair.first != 0) {
232 filter_chain_match.
source_ports.push_back(source_port_pair.first);
235 "{filter_chain_match=", filter_chain_match.
ToString(),
236 ", filter_chain=", source_port_pair.second.data->ToString(),
272 void MaybeLogHttpConnectionManager(
275 http_connection_manager_config) {
290 bool is_client,
const XdsEncodingContext&
context,
292 http_connection_manager_proto,
295 MaybeLogHttpConnectionManager(
context, http_connection_manager_proto);
300 http_connection_manager_proto) != 0) {
302 "'xff_num_trusted_hops' must be zero");
305 http_connection_manager_proto)) {
307 "'original_ip_detection_extensions' must be empty");
312 http_connection_manager_proto);
316 if (duration !=
nullptr) {
323 size_t num_filters = 0;
324 const auto* http_filters =
326 http_connection_manager_proto, &num_filters);
327 std::set<absl::string_view> names_seen;
328 for (
size_t i = 0;
i < num_filters; ++
i) {
329 const auto* http_filter = http_filters[
i];
337 if (names_seen.find(
name) != names_seen.end()) {
341 names_seen.insert(
name);
342 const bool is_optional =
348 if (any ==
nullptr) {
349 if (is_optional)
continue;
354 if (!filter_type.ok()) {
357 const XdsHttpFilterImpl* filter_impl =
359 if (filter_impl ==
nullptr) {
360 if (is_optional)
continue;
362 "no filter registered for config type ", filter_type->type));
364 if ((is_client && !filter_impl->IsSupportedOnClients()) ||
365 (!is_client && !filter_impl->IsSupportedOnServers())) {
366 if (is_optional)
continue;
368 "Filter %s is not supported on %s", filter_type->type,
369 is_client ?
"clients" :
"servers"));
374 if (!filter_config.
ok()) {
376 "filter config for type ", filter_type->type,
380 XdsListenerResource::HttpConnectionManager::HttpFilter{
385 "Expected at least one HTTP filter");
392 const XdsHttpFilterImpl* filter_impl =
394 http_filter.config.config_proto_type_name);
397 if (filter_impl->IsTerminalFilter()) {
400 http_filter.config.config_proto_type_name,
401 " must be the last filter in the chain"));
405 if (!filter_impl->IsTerminalFilter()) {
408 http_filter.config.config_proto_type_name,
409 " is the last filter in the chain"));
419 XdsListenerResource::HttpConnectionManager::HttpFilter{
428 http_connection_manager_proto)) {
431 http_connection_manager_proto);
442 http_connection_manager_proto);
443 if (rds ==
nullptr) {
445 "HttpConnectionManager neither has inlined route_config nor RDS.");
451 if (config_source ==
nullptr) {
453 "HttpConnectionManager missing config_source for RDS.");
458 "HttpConnectionManager ConfigSource for RDS does not specify ADS "
470 const XdsEncodingContext&
context,
472 XdsListenerResource* lds_update) {
481 "Could not parse HttpConnectionManager config from ApiListener");
483 return HttpConnectionManagerParse(
true ,
context,
485 &lds_update->http_connection_manager);
489 const XdsEncodingContext&
context,
491 XdsListenerResource::DownstreamTlsContext* downstream_tls_context) {
494 if (
name !=
"envoy.transport_sockets.tls") {
500 std::vector<grpc_error_handle>
errors;
501 if (typed_config !=
nullptr) {
504 auto* downstream_tls_context_proto =
506 encoded_downstream_tls_context.
data,
507 encoded_downstream_tls_context.
size,
context.arena);
508 if (downstream_tls_context_proto ==
nullptr) {
510 "Can't decode downstream tls context.");
512 auto* common_tls_context =
514 downstream_tls_context_proto);
515 if (common_tls_context !=
nullptr) {
518 &downstream_tls_context->common_tls_context);
521 auto* require_client_certificate =
523 downstream_tls_context_proto);
524 if (require_client_certificate !=
nullptr) {
525 downstream_tls_context->require_client_certificate =
530 downstream_tls_context_proto);
531 if (require_sni !=
nullptr &&
537 downstream_tls_context_proto) !=
540 "ocsp_staple_policy: Only LENIENT_STAPLING supported"));
543 if (downstream_tls_context->common_tls_context
544 .tls_certificate_provider_instance.instance_name.empty()) {
546 "TLS configuration provided but no "
547 "tls_certificate_provider_instance found."));
549 if (downstream_tls_context->require_client_certificate &&
550 downstream_tls_context->common_tls_context.certificate_validation_context
551 .ca_certificate_provider_instance.instance_name.empty()) {
553 "TLS configuration requires client certificates but no certificate "
554 "provider instance specified for validation."));
556 if (!downstream_tls_context->common_tls_context.certificate_validation_context
557 .match_subject_alt_names.empty()) {
559 "match_subject_alt_names not supported on servers"));
567 XdsListenerResource::FilterChainMap::CidrRange* cidr_range) {
573 cidr_range->prefix_len = 0;
574 auto* prefix_len_proto =
576 if (prefix_len_proto !=
nullptr) {
579 (
reinterpret_cast<const grpc_sockaddr*
>(cidr_range->address.addr))
580 ->sa_family == GRPC_AF_INET
591 FilterChain::FilterChainMatch* filter_chain_match) {
592 auto* destination_port =
594 filter_chain_match_proto);
595 if (destination_port !=
nullptr) {
596 filter_chain_match->destination_port =
601 filter_chain_match_proto, &
size);
602 filter_chain_match->prefix_ranges.reserve(
size);
603 for (
size_t i = 0;
i <
size;
i++) {
604 XdsListenerResource::FilterChainMap::CidrRange cidr_range;
607 filter_chain_match->prefix_ranges.push_back(cidr_range);
609 filter_chain_match->source_type =
612 filter_chain_match_proto));
613 auto* source_prefix_ranges =
615 filter_chain_match_proto, &
size);
616 filter_chain_match->source_prefix_ranges.reserve(
size);
617 for (
size_t i = 0;
i <
size;
i++) {
618 XdsListenerResource::FilterChainMap::CidrRange cidr_range;
620 CidrRangeParse(source_prefix_ranges[i], &cidr_range);
622 filter_chain_match->source_prefix_ranges.push_back(cidr_range);
625 filter_chain_match_proto, &
size);
626 filter_chain_match->source_ports.reserve(
size);
627 for (
size_t i = 0;
i <
size;
i++) {
628 filter_chain_match->source_ports.push_back(source_ports[i]);
631 filter_chain_match_proto, &
size);
632 for (
size_t i = 0;
i <
size;
i++) {
633 filter_chain_match->server_names.push_back(
638 filter_chain_match_proto));
639 auto* application_protocols =
641 filter_chain_match_proto, &
size);
642 for (
size_t i = 0;
i <
size;
i++) {
643 filter_chain_match->application_protocols.push_back(
650 const XdsEncodingContext&
context,
652 FilterChain* filter_chain) {
653 std::vector<grpc_error_handle>
errors;
654 auto* filter_chain_match =
657 if (filter_chain_match !=
nullptr) {
659 filter_chain_match, &filter_chain->filter_chain_match);
662 filter_chain->filter_chain_data =
663 std::make_shared<XdsListenerResource::FilterChainData>();
670 "FilterChain should have exactly one filter: HttpConnectionManager; no "
671 "other filter is supported at the moment"));
675 if (typed_config ==
nullptr) {
677 "No typed_config found in filter."));
682 "type.googleapis.com/"
683 "envoy.extensions.filters.network.http_connection_manager.v3."
684 "HttpConnectionManager") {
692 encoded_http_connection_manager.
data,
693 encoded_http_connection_manager.
size,
context.arena);
696 "Could not parse HttpConnectionManager config from filter "
701 &filter_chain->filter_chain_data->http_connection_manager);
707 auto* transport_socket =
709 if (transport_socket !=
nullptr) {
712 &filter_chain->filter_chain_data->downstream_tls_context);
720 const auto* socket_address =
722 if (socket_address ==
nullptr) {
724 "Address does not have socket_address");
729 "SocketAddress protocol is not TCP");
745 struct InternalFilterChainMap {
747 std::map<std::string, XdsListenerResource::FilterChainMap::SourceIp>;
748 using ConnectionSourceTypesArray = std::array<SourceIpMap, 3>;
749 struct DestinationIp {
754 using DestinationIpMap = std::map<std::string, DestinationIp>;
759 const FilterChain& filter_chain,
762 auto insert_result = ports_map->emplace(
763 port, XdsListenerResource::FilterChainMap::FilterChainDataSharedPtr{
764 filter_chain.filter_chain_data});
765 if (!insert_result.second) {
767 "Duplicate matching rules detected when adding filter chain: ",
768 filter_chain.filter_chain_match.ToString()));
774 const FilterChain& filter_chain,
776 if (filter_chain.filter_chain_match.source_ports.empty()) {
777 return AddFilterChainDataForSourcePort(filter_chain, ports_map, 0);
779 for (
uint32_t port : filter_chain.filter_chain_match.source_ports) {
781 AddFilterChainDataForSourcePort(filter_chain, ports_map,
port);
789 const FilterChain& filter_chain,
790 InternalFilterChainMap::SourceIpMap* source_ip_map) {
791 if (filter_chain.filter_chain_match.source_prefix_ranges.empty()) {
792 auto insert_result = source_ip_map->emplace(
793 "", XdsListenerResource::FilterChainMap::SourceIp());
794 return AddFilterChainDataForSourcePorts(
795 filter_chain, &insert_result.first->second.ports_map);
798 filter_chain.filter_chain_match.source_prefix_ranges) {
800 if (!addr_str.ok()) {
803 auto insert_result = source_ip_map->emplace(
805 XdsListenerResource::FilterChainMap::SourceIp());
806 if (insert_result.second) {
807 insert_result.first->second.prefix_range.emplace(
prefix_range);
810 filter_chain, &insert_result.first->second.ports_map);
818 const FilterChain& filter_chain,
819 InternalFilterChainMap::DestinationIp* destination_ip) {
821 filter_chain.filter_chain_match.source_type) < 3);
822 return AddFilterChainDataForSourceIpRange(
823 filter_chain, &destination_ip->source_types_array[
static_cast<int>(
824 filter_chain.filter_chain_match.source_type)]);
828 const FilterChain& filter_chain,
829 InternalFilterChainMap::DestinationIp* destination_ip) {
831 if (!filter_chain.filter_chain_match.application_protocols.empty()) {
834 return AddFilterChainDataForSourceType(filter_chain, destination_ip);
838 const FilterChain& filter_chain,
839 InternalFilterChainMap::DestinationIp* destination_ip) {
841 filter_chain.filter_chain_match.transport_protocol;
843 if (!transport_protocol.empty() && transport_protocol !=
"raw_buffer") {
849 if (destination_ip->transport_protocol_raw_buffer_provided &&
850 transport_protocol.empty()) {
853 if (!transport_protocol.empty() &&
854 !destination_ip->transport_protocol_raw_buffer_provided) {
855 destination_ip->transport_protocol_raw_buffer_provided =
true;
858 destination_ip->source_types_array =
859 InternalFilterChainMap::ConnectionSourceTypesArray();
861 return AddFilterChainDataForApplicationProtocols(filter_chain,
866 const FilterChain& filter_chain,
867 InternalFilterChainMap::DestinationIp* destination_ip) {
869 if (!filter_chain.filter_chain_match.server_names.empty()) {
872 return AddFilterChainDataForTransportProtocol(filter_chain, destination_ip);
876 const FilterChain& filter_chain,
878 if (filter_chain.filter_chain_match.prefix_ranges.empty()) {
880 "", InternalFilterChainMap::DestinationIp());
881 return AddFilterChainDataForServerNames(filter_chain,
882 &insert_result.first->second);
885 filter_chain.filter_chain_match.prefix_ranges) {
887 if (!addr_str.ok()) {
892 InternalFilterChainMap::DestinationIp());
893 if (insert_result.second) {
894 insert_result.first->second.prefix_range.emplace(
prefix_range);
897 filter_chain, &insert_result.first->second);
904 XdsListenerResource::FilterChainMap BuildFromInternalFilterChainMap(
905 InternalFilterChainMap* internal_filter_chain_map) {
907 for (
auto& destination_ip_pair :
908 internal_filter_chain_map->destination_ip_map) {
909 XdsListenerResource::FilterChainMap::DestinationIp destination_ip;
910 destination_ip.prefix_range = destination_ip_pair.second.prefix_range;
911 for (
int i = 0;
i < 3;
i++) {
912 auto& source_ip_map = destination_ip_pair.second.source_types_array[
i];
913 for (
auto& source_ip_pair : source_ip_map) {
914 destination_ip.source_types_array[
i].push_back(
924 const std::vector<FilterChain>& filter_chains,
926 InternalFilterChainMap internal_filter_chain_map;
927 for (
const auto& filter_chain : filter_chains) {
929 if (filter_chain.filter_chain_match.destination_port != 0)
continue;
931 filter_chain, &internal_filter_chain_map.destination_ip_map);
935 BuildFromInternalFilterChainMap(&internal_filter_chain_map);
940 const XdsEncodingContext&
context,
942 XdsListenerResource* lds_update) {
946 &lds_update->address);
948 const auto* use_original_dst =
950 if (use_original_dst !=
nullptr) {
953 "Field \'use_original_dst\' is not supported.");
957 auto* filter_chains =
959 std::vector<FilterChain> parsed_filter_chains;
960 parsed_filter_chains.reserve(
size);
961 for (
size_t i = 0;
i <
size;
i++) {
962 FilterChain filter_chain;
963 error = FilterChainParse(
context, filter_chains[i], is_v2, &filter_chain);
965 parsed_filter_chains.push_back(
std::move(filter_chain));
968 BuildFilterChainMap(parsed_filter_chains, &lds_update->filter_chain_map);
973 FilterChain filter_chain;
977 if (filter_chain.filter_chain_data !=
nullptr) {
978 lds_update->default_filter_chain =
979 std::move(*filter_chain.filter_chain_data);
989 const XdsEncodingContext&
context,
991 XdsListenerResource* lds_update) {
1003 if (api_listener ==
nullptr &&
address ==
nullptr) {
1005 "Listener has neither address nor ApiListener");
1009 if (api_listener !=
nullptr) {
1010 error = LdsResourceParseClient(
context, api_listener, is_v2, lds_update);
1012 error = LdsResourceParseServer(
context, listener, is_v2, lds_update);
1017 void MaybeLogListener(
const XdsEncodingContext&
context,
1036 serialized_resource.
data(), serialized_resource.
size(),
context.arena);
1037 if (resource ==
nullptr) {
1040 MaybeLogListener(
context, resource);
1045 auto listener_data = absl::make_unique<ResourceDataSubclass>();
1047 LdsResourceParse(
context, resource, is_v2, &listener_data->resource);
1060 listener_data->resource.ToString().c_str());