1 // 2 // Copyright 2018 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef GRPC_SRC_CORE_XDS_GRPC_XDS_LISTENER_H 18 #define GRPC_SRC_CORE_XDS_GRPC_XDS_LISTENER_H 19 20 #include <stdint.h> 21 #include <string.h> 22 23 #include <algorithm> 24 #include <array> 25 #include <map> 26 #include <memory> 27 #include <string> 28 #include <vector> 29 30 #include "absl/types/optional.h" 31 #include "absl/types/variant.h" 32 #include "src/core/lib/iomgr/resolved_address.h" 33 #include "src/core/util/time.h" 34 #include "src/core/xds/grpc/xds_common_types.h" 35 #include "src/core/xds/grpc/xds_http_filter.h" 36 #include "src/core/xds/grpc/xds_route_config.h" 37 #include "src/core/xds/xds_client/xds_resource_type.h" 38 #include "src/core/xds/xds_client/xds_resource_type_impl.h" 39 40 namespace grpc_core { 41 42 struct XdsListenerResource : public XdsResourceType::ResourceData { 43 struct HttpConnectionManager { 44 // The RDS resource name or inline RouteConfiguration. 45 absl::variant<std::string, std::shared_ptr<const XdsRouteConfigResource>> 46 route_config; 47 48 // Storing the Http Connection Manager Common Http Protocol Option 49 // max_stream_duration 50 Duration http_max_stream_duration; 51 52 struct HttpFilter { 53 std::string name; 54 XdsHttpFilterImpl::FilterConfig config; 55 56 bool operator==(const HttpFilter& other) const { 57 return name == other.name && config == other.config; 58 } 59 60 std::string ToString() const; 61 }; 62 std::vector<HttpFilter> http_filters; 63 64 bool operator==(const HttpConnectionManager& other) const { 65 if (absl::holds_alternative<std::string>(route_config)) { 66 if (route_config != other.route_config) return false; 67 } else { 68 auto& rc1 = absl::get<std::shared_ptr<const XdsRouteConfigResource>>( 69 route_config); 70 auto* rc2 = absl::get_if<std::shared_ptr<const XdsRouteConfigResource>>( 71 &other.route_config); 72 if (rc2 == nullptr) return false; 73 if (!(*rc1 == **rc2)) return false; 74 } 75 return http_max_stream_duration == other.http_max_stream_duration && 76 http_filters == other.http_filters; 77 } 78 79 std::string ToString() const; 80 }; 81 82 struct DownstreamTlsContext { DownstreamTlsContextXdsListenerResource::DownstreamTlsContext83 DownstreamTlsContext() {} 84 85 CommonTlsContext common_tls_context; 86 bool require_client_certificate = false; 87 88 bool operator==(const DownstreamTlsContext& other) const { 89 return common_tls_context == other.common_tls_context && 90 require_client_certificate == other.require_client_certificate; 91 } 92 93 std::string ToString() const; 94 bool Empty() const; 95 }; 96 97 struct FilterChainData { 98 DownstreamTlsContext downstream_tls_context; 99 // This is in principle the filter list. 100 // We currently require exactly one filter, which is the HCM. 101 HttpConnectionManager http_connection_manager; 102 103 bool operator==(const FilterChainData& other) const { 104 return downstream_tls_context == other.downstream_tls_context && 105 http_connection_manager == other.http_connection_manager; 106 } 107 108 std::string ToString() const; 109 }; 110 111 // A multi-level map used to determine which filter chain to use for a given 112 // incoming connection. Determining the right filter chain for a given 113 // connection checks the following properties, in order: 114 // - destination port (never matched, so not present in map) 115 // - destination IP address 116 // - server name (never matched, so not present in map) 117 // - transport protocol (allows only "raw_buffer" or unset, prefers the 118 // former, so only one of those two types is present in map) 119 // - application protocol (never matched, so not present in map) 120 // - connection source type (any, local or external) 121 // - source IP address 122 // - source port 123 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener_components.proto#config-listener-v3-filterchainmatch 124 // for more details 125 struct FilterChainMap { 126 struct FilterChainDataSharedPtr { 127 std::shared_ptr<FilterChainData> data; 128 bool operator==(const FilterChainDataSharedPtr& other) const { 129 return *data == *other.data; 130 } 131 }; 132 struct CidrRange { 133 grpc_resolved_address address; 134 uint32_t prefix_len; 135 136 bool operator==(const CidrRange& other) const { 137 return memcmp(&address, &other.address, sizeof(address)) == 0 && 138 prefix_len == other.prefix_len; 139 } 140 141 std::string ToString() const; 142 }; 143 using SourcePortsMap = std::map<uint16_t, FilterChainDataSharedPtr>; 144 struct SourceIp { 145 absl::optional<CidrRange> prefix_range; 146 SourcePortsMap ports_map; 147 148 bool operator==(const SourceIp& other) const { 149 return prefix_range == other.prefix_range && 150 ports_map == other.ports_map; 151 } 152 }; 153 using SourceIpVector = std::vector<SourceIp>; 154 enum class ConnectionSourceType { kAny = 0, kSameIpOrLoopback, kExternal }; 155 using ConnectionSourceTypesArray = std::array<SourceIpVector, 3>; 156 struct DestinationIp { 157 absl::optional<CidrRange> prefix_range; 158 // We always fail match on server name, so those filter chains are not 159 // included here. 160 ConnectionSourceTypesArray source_types_array; 161 162 bool operator==(const DestinationIp& other) const { 163 return prefix_range == other.prefix_range && 164 source_types_array == other.source_types_array; 165 } 166 }; 167 // We always fail match on destination ports map 168 using DestinationIpVector = std::vector<DestinationIp>; 169 DestinationIpVector destination_ip_vector; 170 171 bool operator==(const FilterChainMap& other) const { 172 return destination_ip_vector == other.destination_ip_vector; 173 } 174 175 std::string ToString() const; 176 }; 177 178 struct TcpListener { 179 std::string address; // host:port listening address 180 FilterChainMap filter_chain_map; 181 absl::optional<FilterChainData> default_filter_chain; 182 183 bool operator==(const TcpListener& other) const { 184 return address == other.address && 185 filter_chain_map == other.filter_chain_map && 186 default_filter_chain == other.default_filter_chain; 187 } 188 189 std::string ToString() const; 190 }; 191 192 absl::variant<HttpConnectionManager, TcpListener> listener; 193 194 bool operator==(const XdsListenerResource& other) const { 195 return listener == other.listener; 196 } 197 198 std::string ToString() const; 199 }; 200 201 } // namespace grpc_core 202 203 #endif // GRPC_SRC_CORE_XDS_GRPC_XDS_LISTENER_H 204