Line data Source code
1 : #pragma once
2 :
3 : #include <chrono>
4 : #include <cstdint>
5 :
6 : #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h"
7 : #include "envoy/http/codes.h"
8 : #include "envoy/stream_info/stream_info.h"
9 :
10 : namespace Envoy {
11 : namespace StreamInfo {
12 :
13 : /**
14 : * Util class for ResponseFlags.
15 : */
16 : class ResponseFlagUtils {
17 : public:
18 : static const std::string toString(const StreamInfo& stream_info);
19 : static const std::string toShortString(const StreamInfo& stream_info);
20 : static absl::optional<ResponseFlag> toResponseFlag(absl::string_view response_flag);
21 :
22 : struct FlagStrings {
23 : const absl::string_view short_string_;
24 : const absl::string_view long_string_; // PascalCase string
25 : };
26 :
27 : using FlagStringsAndEnum = std::pair<const FlagStrings, ResponseFlag>;
28 :
29 : // When adding a new flag, it's required to update the access log docs and the string
30 : // mapping below - ``ALL_RESPONSE_STRINGS_FLAGS``.
31 : constexpr static absl::string_view NONE = "-";
32 : constexpr static absl::string_view DOWNSTREAM_CONNECTION_TERMINATION = "DC";
33 : constexpr static absl::string_view FAILED_LOCAL_HEALTH_CHECK = "LH";
34 : constexpr static absl::string_view NO_HEALTHY_UPSTREAM = "UH";
35 : constexpr static absl::string_view UPSTREAM_REQUEST_TIMEOUT = "UT";
36 : constexpr static absl::string_view LOCAL_RESET = "LR";
37 : constexpr static absl::string_view UPSTREAM_REMOTE_RESET = "UR";
38 : constexpr static absl::string_view UPSTREAM_CONNECTION_FAILURE = "UF";
39 : constexpr static absl::string_view UPSTREAM_CONNECTION_TERMINATION = "UC";
40 : constexpr static absl::string_view UPSTREAM_OVERFLOW = "UO";
41 : constexpr static absl::string_view UPSTREAM_RETRY_LIMIT_EXCEEDED = "URX";
42 : constexpr static absl::string_view NO_ROUTE_FOUND = "NR";
43 : constexpr static absl::string_view DELAY_INJECTED = "DI";
44 : constexpr static absl::string_view FAULT_INJECTED = "FI";
45 : constexpr static absl::string_view RATE_LIMITED = "RL";
46 : constexpr static absl::string_view UNAUTHORIZED_EXTERNAL_SERVICE = "UAEX";
47 : constexpr static absl::string_view RATELIMIT_SERVICE_ERROR = "RLSE";
48 : constexpr static absl::string_view STREAM_IDLE_TIMEOUT = "SI";
49 : constexpr static absl::string_view INVALID_ENVOY_REQUEST_HEADERS = "IH";
50 : constexpr static absl::string_view DOWNSTREAM_PROTOCOL_ERROR = "DPE";
51 : constexpr static absl::string_view UPSTREAM_MAX_STREAM_DURATION_REACHED = "UMSDR";
52 : constexpr static absl::string_view RESPONSE_FROM_CACHE_FILTER = "RFCF";
53 : constexpr static absl::string_view NO_FILTER_CONFIG_FOUND = "NFCF";
54 : constexpr static absl::string_view DURATION_TIMEOUT = "DT";
55 : constexpr static absl::string_view UPSTREAM_PROTOCOL_ERROR = "UPE";
56 : constexpr static absl::string_view NO_CLUSTER_FOUND = "NC";
57 : constexpr static absl::string_view OVERLOAD_MANAGER = "OM";
58 : constexpr static absl::string_view DNS_FAIL = "DF";
59 : constexpr static absl::string_view DROP_OVERLOAD = "DO";
60 :
61 : constexpr static absl::string_view DOWNSTREAM_CONNECTION_TERMINATION_LONG =
62 : "DownstreamConnectionTermination";
63 : constexpr static absl::string_view FAILED_LOCAL_HEALTH_CHECK_LONG = "FailedLocalHealthCheck";
64 : constexpr static absl::string_view NO_HEALTHY_UPSTREAM_LONG = "NoHealthyUpstream";
65 : constexpr static absl::string_view UPSTREAM_REQUEST_TIMEOUT_LONG = "UpstreamRequestTimeout";
66 : constexpr static absl::string_view LOCAL_RESET_LONG = "LocalReset";
67 : constexpr static absl::string_view UPSTREAM_REMOTE_RESET_LONG = "UpstreamRemoteReset";
68 : constexpr static absl::string_view UPSTREAM_CONNECTION_FAILURE_LONG = "UpstreamConnectionFailure";
69 : constexpr static absl::string_view UPSTREAM_CONNECTION_TERMINATION_LONG =
70 : "UpstreamConnectionTermination";
71 : constexpr static absl::string_view UPSTREAM_OVERFLOW_LONG = "UpstreamOverflow";
72 : constexpr static absl::string_view UPSTREAM_RETRY_LIMIT_EXCEEDED_LONG =
73 : "UpstreamRetryLimitExceeded";
74 : constexpr static absl::string_view NO_ROUTE_FOUND_LONG = "NoRouteFound";
75 : constexpr static absl::string_view DELAY_INJECTED_LONG = "DelayInjected";
76 : constexpr static absl::string_view FAULT_INJECTED_LONG = "FaultInjected";
77 : constexpr static absl::string_view RATE_LIMITED_LONG = "RateLimited";
78 : constexpr static absl::string_view UNAUTHORIZED_EXTERNAL_SERVICE_LONG =
79 : "UnauthorizedExternalService";
80 : constexpr static absl::string_view RATELIMIT_SERVICE_ERROR_LONG = "RateLimitServiceError";
81 : constexpr static absl::string_view STREAM_IDLE_TIMEOUT_LONG = "StreamIdleTimeout";
82 : constexpr static absl::string_view INVALID_ENVOY_REQUEST_HEADERS_LONG =
83 : "InvalidEnvoyRequestHeaders";
84 : constexpr static absl::string_view DOWNSTREAM_PROTOCOL_ERROR_LONG = "DownstreamProtocolError";
85 : constexpr static absl::string_view UPSTREAM_MAX_STREAM_DURATION_REACHED_LONG =
86 : "UpstreamMaxStreamDurationReached";
87 : constexpr static absl::string_view RESPONSE_FROM_CACHE_FILTER_LONG = "ResponseFromCacheFilter";
88 : constexpr static absl::string_view NO_FILTER_CONFIG_FOUND_LONG = "NoFilterConfigFound";
89 : constexpr static absl::string_view DURATION_TIMEOUT_LONG = "DurationTimeout";
90 : constexpr static absl::string_view UPSTREAM_PROTOCOL_ERROR_LONG = "UpstreamProtocolError";
91 : constexpr static absl::string_view NO_CLUSTER_FOUND_LONG = "NoClusterFound";
92 : constexpr static absl::string_view OVERLOAD_MANAGER_LONG = "OverloadManagerTerminated";
93 : constexpr static absl::string_view DNS_FAIL_LONG = "DnsResolutionFailed";
94 : constexpr static absl::string_view DROP_OVERLOAD_LONG = "DropOverload";
95 :
96 : static constexpr std::array ALL_RESPONSE_STRINGS_FLAGS{
97 : FlagStringsAndEnum{{FAILED_LOCAL_HEALTH_CHECK, FAILED_LOCAL_HEALTH_CHECK_LONG},
98 : ResponseFlag::FailedLocalHealthCheck},
99 : FlagStringsAndEnum{{NO_HEALTHY_UPSTREAM, NO_HEALTHY_UPSTREAM_LONG},
100 : ResponseFlag::NoHealthyUpstream},
101 : FlagStringsAndEnum{{UPSTREAM_REQUEST_TIMEOUT, UPSTREAM_REQUEST_TIMEOUT_LONG},
102 : ResponseFlag::UpstreamRequestTimeout},
103 : FlagStringsAndEnum{{LOCAL_RESET, LOCAL_RESET_LONG}, ResponseFlag::LocalReset},
104 : FlagStringsAndEnum{{UPSTREAM_REMOTE_RESET, UPSTREAM_REMOTE_RESET_LONG},
105 : ResponseFlag::UpstreamRemoteReset},
106 : FlagStringsAndEnum{{UPSTREAM_CONNECTION_FAILURE, UPSTREAM_CONNECTION_FAILURE_LONG},
107 : ResponseFlag::UpstreamConnectionFailure},
108 : FlagStringsAndEnum{{UPSTREAM_CONNECTION_TERMINATION, UPSTREAM_CONNECTION_TERMINATION_LONG},
109 : ResponseFlag::UpstreamConnectionTermination},
110 : FlagStringsAndEnum{{UPSTREAM_OVERFLOW, UPSTREAM_OVERFLOW_LONG},
111 : ResponseFlag::UpstreamOverflow},
112 : FlagStringsAndEnum{{NO_ROUTE_FOUND, NO_ROUTE_FOUND_LONG}, ResponseFlag::NoRouteFound},
113 : FlagStringsAndEnum{{DELAY_INJECTED, DELAY_INJECTED_LONG}, ResponseFlag::DelayInjected},
114 : FlagStringsAndEnum{{FAULT_INJECTED, FAULT_INJECTED_LONG}, ResponseFlag::FaultInjected},
115 : FlagStringsAndEnum{{RATE_LIMITED, RATE_LIMITED_LONG}, ResponseFlag::RateLimited},
116 : FlagStringsAndEnum{{UNAUTHORIZED_EXTERNAL_SERVICE, UNAUTHORIZED_EXTERNAL_SERVICE_LONG},
117 : ResponseFlag::UnauthorizedExternalService},
118 : FlagStringsAndEnum{{RATELIMIT_SERVICE_ERROR, RATELIMIT_SERVICE_ERROR_LONG},
119 : ResponseFlag::RateLimitServiceError},
120 : FlagStringsAndEnum{
121 : {DOWNSTREAM_CONNECTION_TERMINATION, DOWNSTREAM_CONNECTION_TERMINATION_LONG},
122 : ResponseFlag::DownstreamConnectionTermination},
123 : FlagStringsAndEnum{{UPSTREAM_RETRY_LIMIT_EXCEEDED, UPSTREAM_RETRY_LIMIT_EXCEEDED_LONG},
124 : ResponseFlag::UpstreamRetryLimitExceeded},
125 : FlagStringsAndEnum{{STREAM_IDLE_TIMEOUT, STREAM_IDLE_TIMEOUT_LONG},
126 : ResponseFlag::StreamIdleTimeout},
127 : FlagStringsAndEnum{{INVALID_ENVOY_REQUEST_HEADERS, INVALID_ENVOY_REQUEST_HEADERS_LONG},
128 : ResponseFlag::InvalidEnvoyRequestHeaders},
129 : FlagStringsAndEnum{{DOWNSTREAM_PROTOCOL_ERROR, DOWNSTREAM_PROTOCOL_ERROR_LONG},
130 : ResponseFlag::DownstreamProtocolError},
131 : FlagStringsAndEnum{
132 : {UPSTREAM_MAX_STREAM_DURATION_REACHED, UPSTREAM_MAX_STREAM_DURATION_REACHED_LONG},
133 : ResponseFlag::UpstreamMaxStreamDurationReached},
134 : FlagStringsAndEnum{{RESPONSE_FROM_CACHE_FILTER, RESPONSE_FROM_CACHE_FILTER_LONG},
135 : ResponseFlag::ResponseFromCacheFilter},
136 : FlagStringsAndEnum{{NO_FILTER_CONFIG_FOUND, NO_FILTER_CONFIG_FOUND_LONG},
137 : ResponseFlag::NoFilterConfigFound},
138 : FlagStringsAndEnum{{DURATION_TIMEOUT, DURATION_TIMEOUT_LONG}, ResponseFlag::DurationTimeout},
139 : FlagStringsAndEnum{{UPSTREAM_PROTOCOL_ERROR, UPSTREAM_PROTOCOL_ERROR_LONG},
140 : ResponseFlag::UpstreamProtocolError},
141 : FlagStringsAndEnum{{NO_CLUSTER_FOUND, NO_CLUSTER_FOUND_LONG}, ResponseFlag::NoClusterFound},
142 : FlagStringsAndEnum{{OVERLOAD_MANAGER, OVERLOAD_MANAGER_LONG}, ResponseFlag::OverloadManager},
143 : FlagStringsAndEnum{{DNS_FAIL, DNS_FAIL_LONG}, ResponseFlag::DnsResolutionFailed},
144 : FlagStringsAndEnum{{DROP_OVERLOAD, DROP_OVERLOAD_LONG}, ResponseFlag::DropOverLoad},
145 : };
146 :
147 : private:
148 : ResponseFlagUtils();
149 : static const std::string toString(const StreamInfo& stream_info, bool use_long_name);
150 : static absl::flat_hash_map<std::string, ResponseFlag> getFlagMap();
151 : };
152 :
153 : class TimingUtility {
154 : public:
155 3 : TimingUtility(const StreamInfo& info) : stream_info_(info) {}
156 :
157 : absl::optional<std::chrono::nanoseconds> firstUpstreamTxByteSent();
158 : absl::optional<std::chrono::nanoseconds> lastUpstreamTxByteSent();
159 : absl::optional<std::chrono::nanoseconds> firstUpstreamRxByteReceived();
160 : absl::optional<std::chrono::nanoseconds> lastUpstreamRxByteReceived();
161 : absl::optional<std::chrono::nanoseconds> upstreamHandshakeComplete();
162 : absl::optional<std::chrono::nanoseconds> firstDownstreamTxByteSent();
163 : absl::optional<std::chrono::nanoseconds> lastDownstreamTxByteSent();
164 : absl::optional<std::chrono::nanoseconds> lastDownstreamRxByteReceived();
165 : absl::optional<std::chrono::nanoseconds> downstreamHandshakeComplete();
166 : absl::optional<std::chrono::nanoseconds> lastDownstreamAckReceived();
167 :
168 : private:
169 : const StreamInfo& stream_info_;
170 : };
171 :
172 : /**
173 : * Utility class for StreamInfo.
174 : */
175 : class Utility {
176 : public:
177 : /**
178 : * @param address supplies the downstream address.
179 : * @return a properly formatted address for logs, header expansion, etc.
180 : */
181 : static const std::string&
182 : formatDownstreamAddressNoPort(const Network::Address::Instance& address);
183 :
184 : /**
185 : * @param address supplies the downstream address.
186 : * @return a port, extracted from the provided downstream address for logs, header expansion, etc.
187 : */
188 : static const std::string
189 : formatDownstreamAddressJustPort(const Network::Address::Instance& address);
190 :
191 : /**
192 : * @param address supplies the downstream address.
193 : * @return a port, extracted from the provided downstream address for logs, header expansion, etc.
194 : */
195 : static absl::optional<uint32_t>
196 : extractDownstreamAddressJustPort(const Network::Address::Instance& address);
197 : };
198 :
199 : // Static utils for creating, consuming, and producing strings from the
200 : // Proxy-Status HTTP response header.
201 : class ProxyStatusUtils {
202 : public:
203 : // Returns a Proxy-Status proxy name string, configured according to |proxy_status_config|.
204 : // If |proxy_status_config| has not been set, defaults to |server_name|.
205 : static const std::string
206 : makeProxyName(absl::string_view node_id, absl::string_view server_name,
207 : const envoy::extensions::filters::network::http_connection_manager::v3::
208 : HttpConnectionManager::ProxyStatusConfig* proxy_status_config);
209 :
210 : // Returns a Proxy-Status request header string, of the form:
211 : //
212 : // <server_name>; error=<error_type>; details=<details>
213 : //
214 : // where:
215 : // - node_id is either the method argument, or the name of the proxy
216 : // in |node_id|,
217 : // - error is the error in |error|,
218 : // - details is |stream_info.responseCodeDetails()|, but the field is
219 : // present only if configured in |proxy_status_config|.
220 : static const std::string
221 : makeProxyStatusHeader(const StreamInfo& stream_info, ProxyStatusError error,
222 : absl::string_view proxy_name,
223 : const envoy::extensions::filters::network::http_connection_manager::v3::
224 : HttpConnectionManager::ProxyStatusConfig& proxy_status_config);
225 :
226 : // Returns a view into the string representation of a given ProxyStatusError
227 : // enum.
228 : static const absl::string_view proxyStatusErrorToString(ProxyStatusError proxy_status);
229 :
230 : // Reads |stream_info.responseFlag| and returns an applicable ProxyStatusError, or nullopt
231 : // if no ProxyStatusError is applicable.
232 : static const absl::optional<ProxyStatusError> fromStreamInfo(const StreamInfo& stream_info);
233 :
234 : // Returns the recommended HTTP status code for a ProxyStatusError, or nullopt
235 : // if no HTTP status code is applicable.
236 : //
237 : // See
238 : // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-proxy-status-05#section-2.1.1 :
239 : //
240 : // > Each Proxy Error Type has a Recommended HTTP Status Code. When
241 : // > generating a HTTP response containing "error", its HTTP status code
242 : // > SHOULD be set to the Recommended HTTP Status Code.
243 : static const absl::optional<Http::Code>
244 : recommendedHttpStatusCode(const ProxyStatusError proxy_status);
245 :
246 : constexpr static absl::string_view DNS_TIMEOUT = "dns_timeout";
247 : constexpr static absl::string_view DNS_ERROR = "dns_error";
248 : constexpr static absl::string_view DESTINATION_NOT_FOUND = "destination_not_found";
249 : constexpr static absl::string_view DESTINATION_UNAVAILABLE = "destination_unavailable";
250 : constexpr static absl::string_view DESTINATION_IP_PROHIBITED = "destination_ip_prohibited";
251 : constexpr static absl::string_view DESTINATION_IP_UNROUTABLE = "destination_ip_unroutable";
252 : constexpr static absl::string_view CONNECTION_REFUSED = "connection_refused";
253 : constexpr static absl::string_view CONNECTION_TERMINATED = "connection_terminated";
254 : constexpr static absl::string_view CONNECTION_TIMEOUT = "connection_timeout";
255 : constexpr static absl::string_view CONNECTION_READ_TIMEOUT = "connection_read_timeout";
256 : constexpr static absl::string_view CONNECTION_WRITE_TIMEOUT = "connection_write_timeout";
257 : constexpr static absl::string_view CONNECTION_LIMIT_REACHED = "connection_limit_reached";
258 : constexpr static absl::string_view TLS_PROTOCOL_ERROR = "tls_protocol_error";
259 : constexpr static absl::string_view TLS_CERTIFICATE_ERROR = "tls_certificate_error";
260 : constexpr static absl::string_view TLS_ALERT_RECEIVED = "tls_alert_received";
261 : constexpr static absl::string_view HTTP_REQUEST_ERROR = "http_request_error";
262 : constexpr static absl::string_view HTTP_REQUEST_DENIED = "http_request_denied";
263 : constexpr static absl::string_view HTTP_RESPONSE_INCOMPLETE = "http_response_incomplete";
264 : constexpr static absl::string_view HTTP_RESPONSE_HEADER_SECTION_SIZE =
265 : "http_response_header_section_size";
266 : constexpr static absl::string_view HTTP_RESPONSE_HEADER_SIZE = "http_response_header_size";
267 : constexpr static absl::string_view HTTP_RESPONSE_BODY_SIZE = "http_response_body_size";
268 : constexpr static absl::string_view HTTP_RESPONSE_TRAILER_SECTION_SIZE =
269 : "http_response_trailer_section_size";
270 : constexpr static absl::string_view HTTP_RESPONSE_TRAILER_SIZE = "http_response_trailer_size";
271 : constexpr static absl::string_view HTTP_RESPONSE_TRANSFER_CODING =
272 : "http_response_transfer_coding";
273 : constexpr static absl::string_view HTTP_RESPONSE_CONTENT_CODING = "http_response_content_coding";
274 : constexpr static absl::string_view HTTP_RESPONSE_TIMEOUT = "http_response_timeout";
275 : constexpr static absl::string_view HTTP_UPGRADE_FAILED = "http_upgrade_failed";
276 : constexpr static absl::string_view HTTP_PROTOCOL_ERROR = "http_protocol_error";
277 : constexpr static absl::string_view PROXY_INTERNAL_RESPONSE = "proxy_internal_response";
278 : constexpr static absl::string_view PROXY_INTERNAL_ERROR = "proxy_internal_error";
279 : constexpr static absl::string_view PROXY_CONFIGURATION_ERROR = "proxy_configuration_error";
280 : constexpr static absl::string_view PROXY_LOOP_DETECTED = "proxy_loop_detected";
281 : };
282 :
283 : } // namespace StreamInfo
284 : } // namespace Envoy
|