Coverage Report

Created: 2023-11-12 09:30

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