forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconnection_handler_impl.h
158 lines (134 loc) · 6.52 KB
/
connection_handler_impl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#pragma once
#include <atomic>
#include <cstdint>
#include <list>
#include <memory>
#include "envoy/network/connection_handler.h"
#include "envoy/network/filter.h"
#include "envoy/network/listen_socket.h"
#include "envoy/network/listener.h"
#include "envoy/server/listener_manager.h"
#include "envoy/stats/scope.h"
#include "source/common/common/non_copyable.h"
#include "spdlog/spdlog.h"
namespace Envoy {
namespace Server {
class ActiveUdpListenerBase;
class ActiveTcpListener;
class ActiveInternalListener;
/**
* Server side connection handler. This is used both by workers as well as the
* main thread for non-threaded listeners.
*/
class ConnectionHandlerImpl : public Network::TcpConnectionHandler,
public Network::UdpConnectionHandler,
public Network::InternalListenerManager,
NonCopyable,
Logger::Loggable<Logger::Id::conn_handler> {
public:
using UdpListenerCallbacksOptRef =
absl::optional<std::reference_wrapper<Network::UdpListenerCallbacks>>;
using ActiveTcpListenerOptRef = absl::optional<std::reference_wrapper<ActiveTcpListener>>;
ConnectionHandlerImpl(Event::Dispatcher& dispatcher, absl::optional<uint32_t> worker_index);
// Network::ConnectionHandler
uint64_t numConnections() const override { return num_handler_connections_; }
void incNumConnections() override;
void decNumConnections() override;
void addListener(absl::optional<uint64_t> overridden_listener, Network::ListenerConfig& config,
Runtime::Loader& runtime) override;
void removeListeners(uint64_t listener_tag) override;
void removeFilterChains(uint64_t listener_tag,
const std::list<const Network::FilterChain*>& filter_chains,
std::function<void()> completion) override;
void stopListeners(uint64_t listener_tag) override;
void stopListeners() override;
void disableListeners() override;
void enableListeners() override;
void setListenerRejectFraction(UnitFloat reject_fraction) override;
const std::string& statPrefix() const override { return per_handler_stat_prefix_; }
// Network::TcpConnectionHandler
Event::Dispatcher& dispatcher() override { return dispatcher_; }
Network::BalancedConnectionHandlerOptRef
getBalancedHandlerByTag(uint64_t listener_tag,
const Network::Address::Instance& address) override;
Network::BalancedConnectionHandlerOptRef
getBalancedHandlerByAddress(const Network::Address::Instance& address) override;
// Network::UdpConnectionHandler
Network::UdpListenerCallbacksOptRef
getUdpListenerCallbacks(uint64_t listener_tag,
const Network::Address::Instance& address) override;
// Network::InternalListenerManager
Network::InternalListenerOptRef
findByAddress(const Network::Address::InstanceConstSharedPtr& listen_address) override;
private:
struct PerAddressActiveListenerDetails {
// Strong pointer to the listener, whether TCP, UDP, QUIC, etc.
Network::ConnectionHandler::ActiveListenerPtr listener_;
Network::Address::InstanceConstSharedPtr address_;
uint64_t listener_tag_;
absl::variant<absl::monostate, std::reference_wrapper<ActiveTcpListener>,
std::reference_wrapper<Network::UdpListenerCallbacks>,
std::reference_wrapper<Network::InternalListener>>
typed_listener_;
// Helpers for accessing the data in the variant for cleaner code.
ActiveTcpListenerOptRef tcpListener();
UdpListenerCallbacksOptRef udpListener();
Network::InternalListenerOptRef internalListener();
};
struct ActiveListenerDetails {
std::vector<std::shared_ptr<PerAddressActiveListenerDetails>> per_address_details_list_;
using ListenerMethodFn = std::function<void(Network::ConnectionHandler::ActiveListener&)>;
/**
* A helper to execute specific method on each PerAddressActiveListenerDetails item.
*/
void invokeListenerMethod(ListenerMethodFn fn) {
std::for_each(per_address_details_list_.begin(), per_address_details_list_.end(),
[&fn](std::shared_ptr<PerAddressActiveListenerDetails>& details) {
fn(*details->listener_);
});
}
/**
* Add an ActiveListener into the list.
*/
template <class ActiveListener>
void addActiveListener(Network::ListenerConfig& config,
const Network::Address::InstanceConstSharedPtr& address,
UnitFloat& listener_reject_fraction, bool disable_listeners,
ActiveListener&& listener) {
auto per_address_details = std::make_shared<PerAddressActiveListenerDetails>();
per_address_details->typed_listener_ = *listener;
per_address_details->listener_ = std::move(listener);
per_address_details->address_ = address;
if (disable_listeners) {
per_address_details->listener_->pauseListening();
}
if (auto* listener = per_address_details->listener_->listener(); listener != nullptr) {
listener->setRejectFraction(listener_reject_fraction);
}
per_address_details->listener_tag_ = config.listenerTag();
per_address_details_list_.emplace_back(per_address_details);
}
};
using ActiveListenerDetailsOptRef = absl::optional<std::reference_wrapper<ActiveListenerDetails>>;
ActiveListenerDetailsOptRef findActiveListenerByTag(uint64_t listener_tag);
using PerAddressActiveListenerDetailsOptRef =
absl::optional<std::reference_wrapper<PerAddressActiveListenerDetails>>;
PerAddressActiveListenerDetailsOptRef
findPerAddressActiveListenerDetails(const ActiveListenerDetailsOptRef active_listener_details,
const Network::Address::Instance& address);
// This has a value on worker threads, and no value on the main thread.
const absl::optional<uint32_t> worker_index_;
Event::Dispatcher& dispatcher_;
const std::string per_handler_stat_prefix_;
// Declare before its users ActiveListenerDetails.
std::atomic<uint64_t> num_handler_connections_{};
absl::flat_hash_map<uint64_t, std::unique_ptr<ActiveListenerDetails>> listener_map_by_tag_;
absl::flat_hash_map<std::string, std::shared_ptr<PerAddressActiveListenerDetails>>
tcp_listener_map_by_address_;
absl::flat_hash_map<std::string, std::shared_ptr<PerAddressActiveListenerDetails>>
internal_listener_map_by_address_;
bool disable_listeners_;
UnitFloat listener_reject_fraction_{UnitFloat::min()};
};
} // namespace Server
} // namespace Envoy