Line data Source code
1 : #pragma once 2 : 3 : #include <cstdint> 4 : 5 : #include "envoy/access_log/access_log.h" 6 : #include "envoy/api/api.h" 7 : #include "envoy/common/random_generator.h" 8 : #include "envoy/config/core/v3/health_check.pb.h" 9 : #include "envoy/data/core/v3/health_check_event.pb.h" 10 : #include "envoy/grpc/status.h" 11 : #include "envoy/network/socket.h" 12 : #include "envoy/server/health_checker_config.h" 13 : #include "envoy/type/v3/http.pb.h" 14 : #include "envoy/type/v3/range.pb.h" 15 : 16 : #include "source/common/common/dump_state_utils.h" 17 : #include "source/common/common/logger.h" 18 : #include "source/common/grpc/codec.h" 19 : #include "source/common/http/codec_client.h" 20 : #include "source/common/router/header_parser.h" 21 : #include "source/common/stream_info/stream_info_impl.h" 22 : #include "source/common/upstream/health_checker_impl.h" 23 : #include "source/extensions/health_checkers/common/health_checker_base_impl.h" 24 : 25 : #include "src/proto/grpc/health/v1/health.pb.h" 26 : 27 : namespace Envoy { 28 : namespace Upstream { 29 : 30 : class TcpHealthCheckerFactory : public Server::Configuration::CustomHealthCheckerFactory { 31 : public: 32 : Upstream::HealthCheckerSharedPtr 33 : createCustomHealthChecker(const envoy::config::core::v3::HealthCheck& config, 34 : Server::Configuration::HealthCheckerFactoryContext& context) override; 35 : 36 148 : std::string name() const override { return "envoy.health_checkers.tcp"; } 37 12 : ProtobufTypes::MessagePtr createEmptyConfigProto() override { 38 12 : return ProtobufTypes::MessagePtr{new envoy::config::core::v3::HealthCheck::TcpHealthCheck()}; 39 12 : } 40 : }; 41 : 42 : DECLARE_FACTORY(TcpHealthCheckerFactory); 43 : 44 : /** 45 : * TCP health checker implementation. 46 : */ 47 : class TcpHealthCheckerImpl : public HealthCheckerImplBase { 48 : public: 49 : TcpHealthCheckerImpl(const Cluster& cluster, const envoy::config::core::v3::HealthCheck& config, 50 : Event::Dispatcher& dispatcher, Runtime::Loader& runtime, 51 : Random::RandomGenerator& random, HealthCheckEventLoggerPtr&& event_logger); 52 : 53 : private: 54 : struct TcpActiveHealthCheckSession; 55 : 56 : struct TcpSessionCallbacks : public Network::ConnectionCallbacks, 57 : public Network::ReadFilterBaseImpl { 58 15 : TcpSessionCallbacks(TcpActiveHealthCheckSession& parent) : parent_(parent) {} 59 : 60 : // Network::ConnectionCallbacks 61 22 : void onEvent(Network::ConnectionEvent event) override { parent_.onEvent(event); } 62 0 : void onAboveWriteBufferHighWatermark() override {} 63 0 : void onBelowWriteBufferLowWatermark() override {} 64 : 65 : // Network::ReadFilter 66 10 : Network::FilterStatus onData(Buffer::Instance& data, bool) override { 67 10 : parent_.onData(data); 68 10 : return Network::FilterStatus::StopIteration; 69 10 : } 70 : 71 : TcpActiveHealthCheckSession& parent_; 72 : }; 73 : 74 : struct TcpActiveHealthCheckSession : public ActiveHealthCheckSession { 75 : TcpActiveHealthCheckSession(TcpHealthCheckerImpl& parent, const HostSharedPtr& host) 76 11 : : ActiveHealthCheckSession(parent, host), parent_(parent) {} 77 : ~TcpActiveHealthCheckSession() override; 78 : 79 : void onData(Buffer::Instance& data); 80 : void onEvent(Network::ConnectionEvent event); 81 : 82 : // ActiveHealthCheckSession 83 : void onInterval() override; 84 : void onTimeout() override; 85 : void onDeferredDelete() final; 86 : 87 : TcpHealthCheckerImpl& parent_; 88 : Network::ClientConnectionPtr client_; 89 : std::shared_ptr<TcpSessionCallbacks> session_callbacks_; 90 : // If true, stream close was initiated by us, not e.g. remote close or TCP reset. 91 : // In this case healthcheck status already reported, only state cleanup required. 92 : bool expect_close_{}; 93 : }; 94 : 95 : using TcpActiveHealthCheckSessionPtr = std::unique_ptr<TcpActiveHealthCheckSession>; 96 : 97 : // HealthCheckerImplBase 98 11 : ActiveHealthCheckSessionPtr makeSession(HostSharedPtr host) override { 99 11 : return std::make_unique<TcpActiveHealthCheckSession>(*this, host); 100 11 : } 101 4 : envoy::data::core::v3::HealthCheckerType healthCheckerType() const override { 102 4 : return envoy::data::core::v3::TCP; 103 4 : } 104 : 105 : const PayloadMatcher::MatchSegments send_bytes_; 106 : PayloadMatcher::MatchSegments receive_bytes_; 107 : }; 108 : 109 : } // namespace Upstream 110 : } // namespace Envoy