Line data Source code
1 : #pragma once 2 : 3 : #include <chrono> 4 : #include <cstdint> 5 : 6 : #include "envoy/common/time.h" 7 : #include "envoy/config/core/v3/base.pb.h" 8 : #include "envoy/http/header_map.h" 9 : #include "envoy/http/request_id_extension.h" 10 : #include "envoy/network/socket.h" 11 : #include "envoy/router/router.h" 12 : #include "envoy/stream_info/stream_info.h" 13 : #include "envoy/tracing/trace_reason.h" 14 : 15 : #include "source/common/common/assert.h" 16 : #include "source/common/common/dump_state_utils.h" 17 : #include "source/common/common/empty_string.h" 18 : #include "source/common/common/macros.h" 19 : #include "source/common/common/utility.h" 20 : #include "source/common/network/socket_impl.h" 21 : #include "source/common/runtime/runtime_features.h" 22 : #include "source/common/stream_info/filter_state_impl.h" 23 : #include "source/common/stream_info/stream_id_provider_impl.h" 24 : 25 : #include "absl/strings/str_replace.h" 26 : 27 : namespace Envoy { 28 : namespace StreamInfo { 29 : 30 : struct UpstreamInfoImpl : public UpstreamInfo { 31 202 : void setUpstreamConnectionId(uint64_t id) override { upstream_connection_id_ = id; } 32 : 33 0 : absl::optional<uint64_t> upstreamConnectionId() const override { return upstream_connection_id_; } 34 : 35 0 : void setUpstreamInterfaceName(absl::string_view interface_name) override { 36 0 : upstream_connection_interface_name_ = std::string(interface_name); 37 0 : } 38 : 39 0 : absl::optional<absl::string_view> upstreamInterfaceName() const override { 40 0 : return upstream_connection_interface_name_; 41 0 : } 42 : 43 : void 44 202 : setUpstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& ssl_connection_info) override { 45 202 : upstream_ssl_info_ = ssl_connection_info; 46 202 : } 47 : 48 0 : Ssl::ConnectionInfoConstSharedPtr upstreamSslConnection() const override { 49 0 : return upstream_ssl_info_; 50 0 : } 51 4218 : UpstreamTiming& upstreamTiming() override { return upstream_timing_; } 52 0 : const UpstreamTiming& upstreamTiming() const override { return upstream_timing_; } 53 0 : const Network::Address::InstanceConstSharedPtr& upstreamLocalAddress() const override { 54 0 : return upstream_local_address_; 55 0 : } 56 0 : const Network::Address::InstanceConstSharedPtr& upstreamRemoteAddress() const override { 57 0 : return upstream_remote_address_; 58 0 : } 59 : void setUpstreamLocalAddress( 60 368 : const Network::Address::InstanceConstSharedPtr& upstream_local_address) override { 61 368 : upstream_local_address_ = upstream_local_address; 62 368 : } 63 : void setUpstreamRemoteAddress( 64 202 : const Network::Address::InstanceConstSharedPtr& upstream_remote_address) override { 65 202 : upstream_remote_address_ = upstream_remote_address; 66 202 : } 67 6 : void setUpstreamTransportFailureReason(absl::string_view failure_reason) override { 68 6 : upstream_transport_failure_reason_ = std::string(failure_reason); 69 6 : } 70 0 : const std::string& upstreamTransportFailureReason() const override { 71 0 : return upstream_transport_failure_reason_; 72 0 : } 73 439 : void setUpstreamHost(Upstream::HostDescriptionConstSharedPtr host) override { 74 439 : upstream_host_ = host; 75 439 : } 76 0 : const FilterStateSharedPtr& upstreamFilterState() const override { 77 0 : return upstream_filter_state_; 78 0 : } 79 202 : void setUpstreamFilterState(const FilterStateSharedPtr& filter_state) override { 80 202 : upstream_filter_state_ = filter_state; 81 202 : } 82 : 83 404 : Upstream::HostDescriptionConstSharedPtr upstreamHost() const override { return upstream_host_; } 84 : 85 0 : void dumpState(std::ostream& os, int indent_level = 0) const override { 86 0 : const char* spaces = spacesForLevel(indent_level); 87 0 : os << spaces << "UpstreamInfoImpl " << this << DUMP_OPTIONAL_MEMBER(upstream_connection_id_) 88 0 : << "\n"; 89 0 : } 90 542 : void setUpstreamNumStreams(uint64_t num_streams) override { num_streams_ = num_streams; } 91 542 : uint64_t upstreamNumStreams() const override { return num_streams_; } 92 : 93 202 : void setUpstreamProtocol(Http::Protocol protocol) override { upstream_protocol_ = protocol; } 94 0 : absl::optional<Http::Protocol> upstreamProtocol() const override { return upstream_protocol_; } 95 : 96 : Upstream::HostDescriptionConstSharedPtr upstream_host_{}; 97 : Network::Address::InstanceConstSharedPtr upstream_local_address_; 98 : Network::Address::InstanceConstSharedPtr upstream_remote_address_; 99 : UpstreamTiming upstream_timing_; 100 : Ssl::ConnectionInfoConstSharedPtr upstream_ssl_info_; 101 : absl::optional<uint64_t> upstream_connection_id_; 102 : absl::optional<std::string> upstream_connection_interface_name_; 103 : std::string upstream_transport_failure_reason_; 104 : FilterStateSharedPtr upstream_filter_state_; 105 : size_t num_streams_{}; 106 : absl::optional<Http::Protocol> upstream_protocol_; 107 : }; 108 : 109 : struct StreamInfoImpl : public StreamInfo { 110 : StreamInfoImpl( 111 : TimeSource& time_source, 112 : const Network::ConnectionInfoProviderSharedPtr& downstream_connection_info_provider, 113 : FilterState::LifeSpan life_span = FilterState::LifeSpan::FilterChain) 114 : : StreamInfoImpl(absl::nullopt, time_source, downstream_connection_info_provider, 115 3582 : std::make_shared<FilterStateImpl>(life_span)) {} 116 : 117 : StreamInfoImpl( 118 : Http::Protocol protocol, TimeSource& time_source, 119 : const Network::ConnectionInfoProviderSharedPtr& downstream_connection_info_provider) 120 : : StreamInfoImpl(protocol, time_source, downstream_connection_info_provider, 121 128 : std::make_shared<FilterStateImpl>(FilterState::LifeSpan::FilterChain)) {} 122 : 123 : StreamInfoImpl( 124 : Http::Protocol protocol, TimeSource& time_source, 125 : const Network::ConnectionInfoProviderSharedPtr& downstream_connection_info_provider, 126 : FilterStateSharedPtr parent_filter_state, FilterState::LifeSpan life_span) 127 : : StreamInfoImpl( 128 : protocol, time_source, downstream_connection_info_provider, 129 : std::make_shared<FilterStateImpl>( 130 : FilterStateImpl::LazyCreateAncestor(std::move(parent_filter_state), life_span), 131 671 : FilterState::LifeSpan::FilterChain)) {} 132 : 133 612 : SystemTime startTime() const override { return start_time_; } 134 : 135 0 : MonotonicTime startTimeMonotonic() const override { return start_time_monotonic_; } 136 : 137 0 : TimeSource& timeSource() const override { return time_source_; } 138 : 139 1377 : absl::optional<std::chrono::nanoseconds> duration(absl::optional<MonotonicTime> time) const { 140 1377 : if (!time) { 141 0 : return {}; 142 0 : } 143 : 144 1377 : return std::chrono::duration_cast<std::chrono::nanoseconds>(time.value() - 145 1377 : start_time_monotonic_); 146 1377 : } 147 : 148 2375 : void setUpstreamInfo(std::shared_ptr<UpstreamInfo> info) override { upstream_info_ = info; } 149 : 150 6167 : std::shared_ptr<UpstreamInfo> upstreamInfo() override { return upstream_info_; } 151 : 152 1060 : OptRef<const UpstreamInfo> upstreamInfo() const override { 153 1060 : if (!upstream_info_) { 154 429 : return {}; 155 429 : } 156 631 : return *upstream_info_; 157 1060 : } 158 : 159 1377 : absl::optional<std::chrono::nanoseconds> currentDuration() const override { 160 1377 : if (!final_time_) { 161 765 : return duration(time_source_.monotonicTime()); 162 765 : } 163 : 164 612 : return requestComplete(); 165 1377 : } 166 : 167 612 : absl::optional<std::chrono::nanoseconds> requestComplete() const override { 168 612 : return duration(final_time_); 169 612 : } 170 : 171 2237 : void onRequestComplete() override { 172 2237 : ASSERT(!final_time_); 173 2237 : final_time_ = time_source_.monotonicTime(); 174 2237 : } 175 : 176 2002 : DownstreamTiming& downstreamTiming() override { 177 2002 : if (!downstream_timing_.has_value()) { 178 628 : downstream_timing_ = DownstreamTiming(); 179 628 : } 180 2002 : return downstream_timing_.value(); 181 2002 : } 182 5034 : OptRef<const DownstreamTiming> downstreamTiming() const override { 183 5034 : if (!downstream_timing_.has_value()) { 184 628 : return {}; 185 628 : } 186 4406 : return {*downstream_timing_}; 187 5034 : } 188 : 189 2522 : void addBytesReceived(uint64_t bytes_received) override { bytes_received_ += bytes_received; } 190 : 191 612 : uint64_t bytesReceived() const override { return bytes_received_; } 192 : 193 0 : void addBytesRetransmitted(uint64_t bytes_retransmitted) override { 194 0 : bytes_retransmitted_ += bytes_retransmitted; 195 0 : } 196 : 197 0 : uint64_t bytesRetransmitted() const override { return bytes_retransmitted_; } 198 : 199 0 : void addPacketsRetransmitted(uint64_t packets_retransmitted) override { 200 0 : packets_retransmitted_ += packets_retransmitted; 201 0 : } 202 : 203 0 : uint64_t packetsRetransmitted() const override { return packets_retransmitted_; } 204 : 205 2406 : absl::optional<Http::Protocol> protocol() const override { return protocol_; } 206 : 207 1799 : void protocol(Http::Protocol protocol) override { protocol_ = protocol; } 208 : 209 1377 : absl::optional<uint32_t> responseCode() const override { return response_code_; } 210 : 211 565 : const absl::optional<std::string>& responseCodeDetails() const override { 212 565 : return response_code_details_; 213 565 : } 214 : 215 1235 : void setResponseCode(uint32_t code) override { response_code_ = code; } 216 : 217 1207 : void setResponseCodeDetails(absl::string_view rc_details) override { 218 1207 : ASSERT(!StringUtil::hasEmptySpace(rc_details)); 219 1207 : response_code_details_.emplace(rc_details); 220 1207 : } 221 : 222 0 : const absl::optional<std::string>& connectionTerminationDetails() const override { 223 0 : return connection_termination_details_; 224 0 : } 225 : 226 0 : void setConnectionTerminationDetails(absl::string_view connection_termination_details) override { 227 0 : connection_termination_details_.emplace(connection_termination_details); 228 0 : } 229 : 230 8997 : void addBytesSent(uint64_t bytes_sent) override { bytes_sent_ += bytes_sent; } 231 : 232 612 : uint64_t bytesSent() const override { return bytes_sent_; } 233 : 234 651 : void setResponseFlag(ResponseFlag response_flag) override { response_flags_ |= response_flag; } 235 : 236 0 : bool intersectResponseFlags(uint64_t response_flags) const override { 237 0 : return (response_flags_ & response_flags) != 0; 238 0 : } 239 : 240 17362 : bool hasResponseFlag(ResponseFlag flag) const override { return response_flags_ & flag; } 241 : 242 0 : bool hasAnyResponseFlag() const override { return response_flags_ != 0; } 243 : 244 0 : uint64_t responseFlags() const override { return response_flags_; } 245 : 246 0 : const std::string& getRouteName() const override { 247 0 : return route_ != nullptr ? route_->routeName() : EMPTY_STRING; 248 0 : } 249 : 250 0 : void setVirtualClusterName(const absl::optional<std::string>& virtual_cluster_name) override { 251 0 : virtual_cluster_name_ = virtual_cluster_name; 252 0 : } 253 : 254 0 : const absl::optional<std::string>& virtualClusterName() const override { 255 0 : return virtual_cluster_name_; 256 0 : } 257 : 258 1733 : bool healthCheck() const override { return health_check_request_; } 259 : 260 251 : void healthCheck(bool is_health_check) override { health_check_request_ = is_health_check; } 261 : 262 1261 : const Network::ConnectionInfoProvider& downstreamAddressProvider() const override { 263 1261 : return *downstream_connection_info_provider_; 264 1261 : } 265 : 266 2711 : Router::RouteConstSharedPtr route() const override { return route_; } 267 : 268 68 : envoy::config::core::v3::Metadata& dynamicMetadata() override { return metadata_; }; 269 1 : const envoy::config::core::v3::Metadata& dynamicMetadata() const override { return metadata_; }; 270 : 271 0 : void setDynamicMetadata(const std::string& name, const ProtobufWkt::Struct& value) override { 272 0 : (*metadata_.mutable_filter_metadata())[name].MergeFrom(value); 273 0 : }; 274 : 275 3846 : const FilterStateSharedPtr& filterState() override { return filter_state_; } 276 375 : const FilterState& filterState() const override { return *filter_state_; } 277 : 278 960 : void setRequestHeaders(const Http::RequestHeaderMap& headers) override { 279 960 : request_headers_ = &headers; 280 960 : } 281 : 282 1652 : const Http::RequestHeaderMap* getRequestHeaders() const override { return request_headers_; } 283 : 284 671 : void setStreamIdProvider(StreamIdProviderSharedPtr provider) override { 285 671 : stream_id_provider_ = std::move(provider); 286 671 : } 287 0 : OptRef<const StreamIdProvider> getStreamIdProvider() const override { 288 0 : if (stream_id_provider_ == nullptr) { 289 0 : return {}; 290 0 : } 291 0 : return makeOptRef<const StreamIdProvider>(*stream_id_provider_); 292 0 : } 293 : 294 507 : void setTraceReason(Tracing::Reason reason) override { trace_reason_ = reason; } 295 0 : Tracing::Reason traceReason() const override { return trace_reason_; } 296 : 297 0 : void dumpState(std::ostream& os, int indent_level = 0) const override { 298 0 : const char* spaces = spacesForLevel(indent_level); 299 0 : os << spaces << "StreamInfoImpl " << this << DUMP_OPTIONAL_MEMBER(protocol_) 300 0 : << DUMP_OPTIONAL_MEMBER(response_code_) << DUMP_OPTIONAL_MEMBER(response_code_details_) 301 0 : << DUMP_OPTIONAL_MEMBER(attempt_count_) << DUMP_MEMBER(health_check_request_) 302 0 : << DUMP_MEMBER(getRouteName()); 303 0 : DUMP_DETAILS(upstream_info_); 304 0 : } 305 : 306 : void setUpstreamClusterInfo( 307 947 : const Upstream::ClusterInfoConstSharedPtr& upstream_cluster_info) override { 308 947 : upstream_cluster_info_ = upstream_cluster_info; 309 947 : } 310 : 311 291 : absl::optional<Upstream::ClusterInfoConstSharedPtr> upstreamClusterInfo() const override { 312 291 : return upstream_cluster_info_; 313 291 : } 314 : 315 251 : void setAttemptCount(uint32_t attempt_count) override { attempt_count_ = attempt_count; } 316 : 317 0 : absl::optional<uint32_t> attemptCount() const override { return attempt_count_; } 318 : 319 247 : const BytesMeterSharedPtr& getUpstreamBytesMeter() const override { 320 247 : return upstream_bytes_meter_; 321 247 : } 322 : 323 202 : const BytesMeterSharedPtr& getDownstreamBytesMeter() const override { 324 202 : return downstream_bytes_meter_; 325 202 : } 326 : 327 404 : void setUpstreamBytesMeter(const BytesMeterSharedPtr& upstream_bytes_meter) override { 328 404 : upstream_bytes_meter->captureExistingBytesMeter(*upstream_bytes_meter_); 329 404 : upstream_bytes_meter_ = upstream_bytes_meter; 330 404 : } 331 : 332 873 : void setDownstreamBytesMeter(const BytesMeterSharedPtr& downstream_bytes_meter) override { 333 : // Downstream bytes counter don't reset during a retry. 334 873 : if (downstream_bytes_meter_ == nullptr) { 335 873 : downstream_bytes_meter_ = downstream_bytes_meter; 336 873 : } 337 873 : ASSERT(downstream_bytes_meter_.get() == downstream_bytes_meter.get()); 338 873 : } 339 : 340 : // This function is used to persist relevant information from the original 341 : // stream into to the new one, when recreating the stream. Generally this 342 : // includes information about the downstream stream, but not the upstream 343 : // stream. 344 0 : void setFromForRecreateStream(StreamInfo& info) { 345 0 : downstream_timing_ = info.downstreamTiming(); 346 0 : protocol_ = info.protocol(); 347 0 : bytes_received_ = info.bytesReceived(); 348 0 : downstream_bytes_meter_ = info.getDownstreamBytesMeter(); 349 0 : // These two are set in the constructor, but to T(recreate), and should be T(create) 350 0 : start_time_ = info.startTime(); 351 0 : start_time_monotonic_ = info.startTimeMonotonic(); 352 0 : downstream_transport_failure_reason_ = std::string(info.downstreamTransportFailureReason()); 353 0 : bytes_retransmitted_ = info.bytesRetransmitted(); 354 0 : packets_retransmitted_ = info.packetsRetransmitted(); 355 0 : if (Runtime::runtimeFeatureEnabled( 356 0 : "envoy.reloadable_features.http1_connection_close_header_in_redirect")) { 357 0 : should_drain_connection_ = info.shouldDrainConnectionUponCompletion(); 358 0 : } 359 0 : } 360 : 361 : // This function is used to copy over every field exposed in the StreamInfo interface, with a 362 : // couple of exceptions noted below. Note that setFromForRecreateStream is reused here. 363 : // * request_headers_ is a raw pointer; to avoid pointer lifetime issues, a request header pointer 364 : // is required to be passed in here. 365 : // * downstream_connection_info_provider_ is always set in the ctor. 366 0 : void setFrom(StreamInfo& info, const Http::RequestHeaderMap* request_headers) { 367 0 : setFromForRecreateStream(info); 368 0 : virtual_cluster_name_ = info.virtualClusterName(); 369 0 : response_code_ = info.responseCode(); 370 0 : response_code_details_ = info.responseCodeDetails(); 371 0 : connection_termination_details_ = info.connectionTerminationDetails(); 372 0 : upstream_info_ = info.upstreamInfo(); 373 0 : if (info.requestComplete().has_value()) { 374 0 : // derive final time from other info's complete duration and start time. 375 0 : final_time_ = info.startTimeMonotonic() + info.requestComplete().value(); 376 0 : } 377 0 : response_flags_ = info.responseFlags(); 378 0 : health_check_request_ = info.healthCheck(); 379 0 : route_ = info.route(); 380 0 : metadata_ = info.dynamicMetadata(); 381 0 : filter_state_ = info.filterState(); 382 0 : request_headers_ = request_headers; 383 0 : upstream_cluster_info_ = info.upstreamClusterInfo(); 384 0 : auto stream_id_provider = info.getStreamIdProvider(); 385 0 : if (stream_id_provider.has_value() && stream_id_provider->toStringView().has_value()) { 386 0 : std::string id{stream_id_provider->toStringView().value()}; 387 0 : stream_id_provider_ = std::make_shared<StreamIdProviderImpl>(std::move(id)); 388 0 : } 389 0 : trace_reason_ = info.traceReason(); 390 0 : attempt_count_ = info.attemptCount(); 391 0 : upstream_bytes_meter_ = info.getUpstreamBytesMeter(); 392 0 : bytes_sent_ = info.bytesSent(); 393 0 : is_shadow_ = info.isShadow(); 394 0 : } 395 : 396 319 : void setIsShadow(bool is_shadow) { is_shadow_ = is_shadow; } 397 251 : bool isShadow() const override { return is_shadow_; } 398 : 399 1042 : void setDownstreamTransportFailureReason(absl::string_view failure_reason) override { 400 1042 : downstream_transport_failure_reason_ = std::string(failure_reason); 401 1042 : } 402 : 403 0 : absl::string_view downstreamTransportFailureReason() const override { 404 0 : return downstream_transport_failure_reason_; 405 0 : } 406 : 407 1121 : bool shouldDrainConnectionUponCompletion() const override { return should_drain_connection_; } 408 : 409 67 : void setShouldDrainConnectionUponCompletion(bool should_drain) override { 410 67 : should_drain_connection_ = should_drain; 411 67 : } 412 : 413 : TimeSource& time_source_; 414 : SystemTime start_time_; 415 : MonotonicTime start_time_monotonic_; 416 : absl::optional<MonotonicTime> final_time_; 417 : 418 : absl::optional<Http::Protocol> protocol_; 419 : 420 : private: 421 : absl::optional<uint32_t> response_code_; 422 : 423 : public: 424 : absl::optional<std::string> response_code_details_; 425 : absl::optional<std::string> connection_termination_details_; 426 : uint64_t response_flags_{}; 427 : bool health_check_request_{}; 428 : Router::RouteConstSharedPtr route_; 429 : envoy::config::core::v3::Metadata metadata_{}; 430 : FilterStateSharedPtr filter_state_; 431 : absl::optional<uint32_t> attempt_count_; 432 : // TODO(agrawroh): Check if the owner of this storage outlives the StreamInfo. We should only copy 433 : // the string if it could outlive the StreamInfo. 434 : absl::optional<std::string> virtual_cluster_name_; 435 : 436 : private: 437 494 : static Network::ConnectionInfoProviderSharedPtr emptyDownstreamAddressProvider() { 438 494 : MUTABLE_CONSTRUCT_ON_FIRST_USE( 439 494 : Network::ConnectionInfoProviderSharedPtr, 440 494 : std::make_shared<Network::ConnectionInfoSetterImpl>(nullptr, nullptr)); 441 494 : } 442 : 443 : StreamInfoImpl( 444 : absl::optional<Http::Protocol> protocol, TimeSource& time_source, 445 : const Network::ConnectionInfoProviderSharedPtr& downstream_connection_info_provider, 446 : FilterStateSharedPtr filter_state) 447 : : time_source_(time_source), start_time_(time_source.systemTime()), 448 : start_time_monotonic_(time_source.monotonicTime()), protocol_(protocol), 449 : filter_state_(std::move(filter_state)), 450 : downstream_connection_info_provider_(downstream_connection_info_provider != nullptr 451 : ? downstream_connection_info_provider 452 : : emptyDownstreamAddressProvider()), 453 4381 : trace_reason_(Tracing::Reason::NotTraceable) {} 454 : 455 : std::shared_ptr<UpstreamInfo> upstream_info_; 456 : uint64_t bytes_received_{}; 457 : uint64_t bytes_retransmitted_{}; 458 : uint64_t packets_retransmitted_{}; 459 : uint64_t bytes_sent_{}; 460 : const Network::ConnectionInfoProviderSharedPtr downstream_connection_info_provider_; 461 : const Http::RequestHeaderMap* request_headers_{}; 462 : StreamIdProviderSharedPtr stream_id_provider_; 463 : absl::optional<DownstreamTiming> downstream_timing_; 464 : absl::optional<Upstream::ClusterInfoConstSharedPtr> upstream_cluster_info_; 465 : Tracing::Reason trace_reason_; 466 : // Default construct the object because upstream stream is not constructed in some cases. 467 : BytesMeterSharedPtr upstream_bytes_meter_{std::make_shared<BytesMeter>()}; 468 : BytesMeterSharedPtr downstream_bytes_meter_; 469 : bool is_shadow_{false}; 470 : std::string downstream_transport_failure_reason_; 471 : bool should_drain_connection_{false}; 472 : }; 473 : 474 : } // namespace StreamInfo 475 : } // namespace Envoy