1
#pragma once
2

            
3
#include "envoy/network/parent_drained_callback_registrar.h"
4
#include "envoy/server/instance.h"
5

            
6
#include "source/common/stats/stat_merger.h"
7
#include "source/server/hot_restarting_base.h"
8

            
9
namespace Envoy {
10
namespace Server {
11

            
12
/**
13
 * The child half of hot restarting. Issues requests and commands to the parent.
14
 */
15
class HotRestartingChild : public HotRestartingBase,
16
                           public Network::ParentDrainedCallbackRegistrar {
17
public:
18
  // A structure to record the set of registered UDP listeners keyed on their addresses,
19
  // to support QUIC packet forwarding.
20
  class UdpForwardingContext {
21
  public:
22
    using ForwardEntry = std::pair<Network::Address::InstanceConstSharedPtr,
23
                                   std::shared_ptr<Network::UdpListenerConfig>>;
24

            
25
    // Returns the address and UdpListenerConfig associated with the given address.
26
    // The addresses are not necessarily identical, as e.g. the listener might be listening on
27
    // 0.0.0.0.
28
    // This is called from the thread to which the hot restart Event::Dispatcher
29
    // dispatches, which is expected to be the same main thread as registerListener
30
    // is called from.
31
    absl::optional<ForwardEntry>
32
    getListenerForDestination(const Network::Address::Instance& address);
33

            
34
    // Registers a UdpListenerConfig and address into the map, to be matched using
35
    // getListenerForDestination for UDP packet forwarding.
36
    // This is called from the main thread during listening socket creation.
37
    void registerListener(Network::Address::InstanceConstSharedPtr address,
38
                          std::shared_ptr<Network::UdpListenerConfig> listener_config);
39

            
40
  private:
41
    // Map keyed on address as a string, because Network::Address::Instance isn't hashable.
42
    absl::flat_hash_map<std::string, ForwardEntry> listener_map_;
43
  };
44

            
45
  HotRestartingChild(int base_id, int restart_epoch, const std::string& socket_path,
46
                     mode_t socket_mode, bool skip_hot_restart_on_no_parent,
47
                     bool skip_parent_stats);
48
34
  ~HotRestartingChild() override = default;
49

            
50
  void initialize(Event::Dispatcher& dispatcher);
51
  void shutdown();
52

            
53
  int duplicateParentListenSocket(const std::string& address, uint32_t worker_index,
54
                                  absl::string_view network_namespace);
55
  void registerUdpForwardingListener(Network::Address::InstanceConstSharedPtr address,
56
                                     std::shared_ptr<Network::UdpListenerConfig> listener_config);
57
  // From Network::ParentDrainedCallbackRegistrar.
58
  void registerParentDrainedCallback(const Network::Address::InstanceConstSharedPtr& addr,
59
                                     absl::AnyInvocable<void()> action) override;
60
  std::unique_ptr<envoy::HotRestartMessage> getParentStats();
61
  void drainParentListeners();
62
  absl::optional<HotRestart::AdminShutdownResponse> sendParentAdminShutdownRequest();
63
  void sendParentTerminateRequest();
64
  void mergeParentStats(Stats::Store& stats_store,
65
                        const envoy::HotRestartMessage::Reply::Stats& stats_proto);
66

            
67
protected:
68
  absl::Status onSocketEventUdpForwarding();
69
  void onForwardedUdpPacket(uint32_t worker_index, Network::UdpRecvData&& data);
70
  // When call to terminate parent is sent, or parent is already terminated,
71
  void allDrainsImplicitlyComplete();
72

            
73
private:
74
  bool abortDueToFailedParentConnection();
75
  friend class HotRestartUdpForwardingTestHelper;
76
  absl::Mutex registry_mu_;
77
  const int restart_epoch_;
78
  bool parent_terminated_;
79
  bool parent_drained_ ABSL_GUARDED_BY(registry_mu_);
80
  const bool skip_hot_restart_on_no_parent_;
81
  const bool skip_parent_stats_;
82
  sockaddr_un parent_address_;
83
  sockaddr_un parent_address_udp_forwarding_;
84
  std::unique_ptr<Stats::StatMerger> stat_merger_{};
85
  Stats::StatName hot_restart_generation_stat_name_;
86
  // There are multiple listener instances per address that must all be reactivated
87
  // when the parent is drained, so a multimap is used to contain them.
88
  std::unordered_multimap<std::string, absl::AnyInvocable<void()>>
89
      on_drained_actions_ ABSL_GUARDED_BY(registry_mu_);
90
  Event::FileEventPtr socket_event_udp_forwarding_;
91
  UdpForwardingContext udp_forwarding_context_;
92
};
93

            
94
} // namespace Server
95
} // namespace Envoy