1
#pragma once
2

            
3
#include "envoy/extensions/quic/connection_id_generator/quic_lb/v3/quic_lb.pb.h"
4

            
5
#include "source/common/quic/envoy_quic_connection_id_generator_factory.h"
6

            
7
#include "quiche/quic/load_balancer/load_balancer_encoder.h"
8

            
9
#if defined(__linux__)
10
#include <linux/filter.h>
11
#endif
12

            
13
namespace Envoy {
14
namespace Quic {
15
namespace Extensions {
16
namespace ConnectionIdGenerator {
17
namespace QuicLb {
18

            
19
// If this type changes such that more bytes are required, update the docs in quic_lb.proto which
20
// specifies the maximum length of the server_id and nonce combined.
21
using WorkerRoutingIdValue = uint8_t;
22

            
23
class QuicLbConnectionIdGenerator : public quic::ConnectionIdGeneratorInterface {
24
public:
25
  class ThreadLocalData : public ThreadLocal::ThreadLocalObject {
26
  public:
27
    static absl::StatusOr<std::shared_ptr<ThreadLocalData>>
28
    create(const envoy::extensions::quic::connection_id_generator::quic_lb::v3::Config& config,
29
           absl::string_view server_id);
30

            
31
    absl::Status updateKeyAndVersion(absl::string_view key, uint8_t version);
32

            
33
    quic::LoadBalancerEncoder encoder_;
34

            
35
  private:
36
    ThreadLocalData(
37
        const envoy::extensions::quic::connection_id_generator::quic_lb::v3::Config& config,
38
        absl::string_view server_id);
39

            
40
    const bool unencrypted_mode_;
41
    const uint32_t nonce_length_bytes_;
42
    const quic::LoadBalancerServerId server_id_;
43
  };
44

            
45
  QuicLbConnectionIdGenerator(ThreadLocal::TypedSlot<ThreadLocalData>& tls, uint32_t worker_id);
46

            
47
  // quic::ConnectionIdGeneratorInterface
48
  absl::optional<quic::QuicConnectionId>
49
  GenerateNextConnectionId(const quic::QuicConnectionId& original) override;
50
  absl::optional<quic::QuicConnectionId>
51
  MaybeReplaceConnectionId(const quic::QuicConnectionId& original,
52
                           const quic::ParsedQuicVersion& version) override;
53
  uint8_t ConnectionIdLength(uint8_t first_byte) const override;
54

            
55
  absl::optional<quic::QuicConnectionId> appendRoutingId(quic::QuicConnectionId& new_connection_id);
56

            
57
private:
58
  ThreadLocal::TypedSlot<ThreadLocalData>& tls_slot_;
59
  const WorkerRoutingIdValue worker_id_;
60
};
61

            
62
class Factory : public EnvoyQuicConnectionIdGeneratorFactory {
63
public:
64
  static absl::StatusOr<std::unique_ptr<Factory>>
65
  create(const envoy::extensions::quic::connection_id_generator::quic_lb::v3::Config& config,
66
         Server::Configuration::FactoryContext& context);
67

            
68
  // EnvoyQuicConnectionIdGeneratorFactory.
69
  QuicConnectionIdGeneratorPtr createQuicConnectionIdGenerator(uint32_t worker_index) override;
70
  Network::Socket::OptionConstSharedPtr
71
  createCompatibleLinuxBpfSocketOption(uint32_t concurrency) override;
72
  QuicConnectionIdWorkerSelector
73
  getCompatibleConnectionIdWorkerSelector(uint32_t concurrency) override;
74

            
75
private:
76
  Factory(const envoy::extensions::quic::connection_id_generator::quic_lb::v3::Config& config);
77
  absl::Status updateSecret(Api::Api& api);
78

            
79
  const envoy::extensions::quic::connection_id_generator::quic_lb::v3::Config config_;
80
  Secret::GenericSecretConfigProviderSharedPtr secrets_provider_;
81
  Common::CallbackHandlePtr secrets_provider_validation_callback_handle_;
82
  Common::CallbackHandlePtr secrets_provider_update_callback_handle_;
83
  ThreadLocal::TypedSlotPtr<QuicLbConnectionIdGenerator::ThreadLocalData> tls_slot_;
84

            
85
#if defined(SO_ATTACH_REUSEPORT_CBPF) && defined(__linux__)
86
  sock_fprog prog_;
87
  std::vector<sock_filter> filter_;
88
#endif
89
};
90

            
91
} // namespace QuicLb
92
} // namespace ConnectionIdGenerator
93
} // namespace Extensions
94
} // namespace Quic
95
} // namespace Envoy