Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/extensions/filters/udp/udp_proxy/config.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/extensions/filters/udp/udp_proxy/config.h"
2
3
#include "source/common/formatter/substitution_format_string.h"
4
5
namespace Envoy {
6
namespace Extensions {
7
namespace UdpFilters {
8
namespace UdpProxy {
9
10
constexpr uint32_t DefaultMaxConnectAttempts = 1;
11
constexpr uint32_t DefaultMaxBufferedDatagrams = 1024;
12
constexpr uint64_t DefaultMaxBufferedBytes = 16384;
13
14
TunnelingConfigImpl::TunnelingConfigImpl(const TunnelingConfig& config,
15
                                         Server::Configuration::FactoryContext& context)
16
    : header_parser_(Envoy::Router::HeaderParser::configure(config.headers_to_add())),
17
      proxy_port_(), target_port_(config.default_target_port()), use_post_(config.use_post()),
18
      post_path_(config.post_path()),
19
      max_connect_attempts_(config.has_retry_options()
20
                                ? PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.retry_options(),
21
                                                                  max_connect_attempts,
22
                                                                  DefaultMaxConnectAttempts)
23
                                : DefaultMaxConnectAttempts),
24
      buffer_enabled_(config.has_buffer_options()),
25
      max_buffered_datagrams_(config.has_buffer_options()
26
                                  ? PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.buffer_options(),
27
                                                                    max_buffered_datagrams,
28
                                                                    DefaultMaxBufferedDatagrams)
29
                                  : DefaultMaxBufferedDatagrams),
30
      max_buffered_bytes_(config.has_buffer_options()
31
                              ? PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.buffer_options(),
32
                                                                max_buffered_bytes,
33
                                                                DefaultMaxBufferedBytes)
34
0
                              : DefaultMaxBufferedBytes) {
35
0
  if (!post_path_.empty() && !use_post_) {
36
0
    throw EnvoyException("Can't set a post path when POST method isn't used");
37
0
  }
38
39
0
  if (post_path_.empty()) {
40
0
    post_path_ = "/";
41
0
  } else if (post_path_.rfind("/", 0) != 0) {
42
0
    throw EnvoyException("Path must start with '/'");
43
0
  }
44
45
0
  envoy::config::core::v3::SubstitutionFormatString proxy_substitution_format_config;
46
0
  proxy_substitution_format_config.mutable_text_format_source()->set_inline_string(
47
0
      config.proxy_host());
48
0
  proxy_host_formatter_ = Formatter::SubstitutionFormatStringUtils::fromProtoConfig(
49
0
      proxy_substitution_format_config, context);
50
51
0
  if (config.has_proxy_port()) {
52
0
    uint32_t port = config.proxy_port().value();
53
0
    if (port == 0 || port > 65535) {
54
0
      throw EnvoyException("Port value not in range");
55
0
    }
56
57
0
    proxy_port_ = port;
58
0
  }
59
60
0
  envoy::config::core::v3::SubstitutionFormatString target_substitution_format_config;
61
0
  target_substitution_format_config.mutable_text_format_source()->set_inline_string(
62
0
      config.target_host());
63
0
  target_host_formatter_ = Formatter::SubstitutionFormatStringUtils::fromProtoConfig(
64
0
      target_substitution_format_config, context);
65
0
}
66
67
UdpProxyFilterConfigImpl::UdpProxyFilterConfigImpl(
68
    Server::Configuration::ListenerFactoryContext& context,
69
    const envoy::extensions::filters::udp::udp_proxy::v3::UdpProxyConfig& config)
70
    : cluster_manager_(context.clusterManager()), time_source_(context.timeSource()),
71
      router_(std::make_shared<Router::RouterImpl>(config, context.getServerFactoryContext())),
72
      session_timeout_(PROTOBUF_GET_MS_OR_DEFAULT(config, idle_timeout, 60 * 1000)),
73
      use_original_src_ip_(config.use_original_src_ip()),
74
      use_per_packet_load_balancing_(config.use_per_packet_load_balancing()),
75
      stats_(generateStats(config.stat_prefix(), context.scope())),
76
      // Default prefer_gro to true for upstream client traffic.
77
0
      upstream_socket_config_(config.upstream_socket_config(), true) {
78
0
  if (use_per_packet_load_balancing_ && config.has_tunneling_config()) {
79
0
    throw EnvoyException(
80
0
        "Only one of use_per_packet_load_balancing or tunneling_config can be used.");
81
0
  }
82
83
0
  if (use_per_packet_load_balancing_ && !config.session_filters().empty()) {
84
0
    throw EnvoyException(
85
0
        "Only one of use_per_packet_load_balancing or session_filters can be used.");
86
0
  }
87
88
0
  if (use_original_src_ip_ &&
89
0
      !Api::OsSysCallsSingleton::get().supportsIpTransparent(
90
0
          context.getServerFactoryContext().options().localAddressIpVersion())) {
91
0
    ExceptionUtil::throwEnvoyException(
92
0
        "The platform does not support either IP_TRANSPARENT or IPV6_TRANSPARENT. Or the envoy "
93
0
        "is not running with the CAP_NET_ADMIN capability.");
94
0
  }
95
96
0
  session_access_logs_.reserve(config.access_log_size());
97
0
  for (const envoy::config::accesslog::v3::AccessLog& log_config : config.access_log()) {
98
0
    session_access_logs_.emplace_back(AccessLog::AccessLogFactory::fromProto(log_config, context));
99
0
  }
100
101
0
  proxy_access_logs_.reserve(config.proxy_access_log_size());
102
0
  for (const envoy::config::accesslog::v3::AccessLog& log_config : config.proxy_access_log()) {
103
0
    proxy_access_logs_.emplace_back(AccessLog::AccessLogFactory::fromProto(log_config, context));
104
0
  }
105
106
0
  if (!config.hash_policies().empty()) {
107
0
    hash_policy_ = std::make_unique<HashPolicyImpl>(config.hash_policies());
108
0
  }
109
110
0
  if (config.has_tunneling_config()) {
111
0
    tunneling_config_ = std::make_unique<TunnelingConfigImpl>(config.tunneling_config(), context);
112
0
  }
113
114
0
  for (const auto& filter : config.session_filters()) {
115
0
    ENVOY_LOG(debug, "    UDP session filter #{}", filter_factories_.size());
116
0
    ENVOY_LOG(debug, "      name: {}", filter.name());
117
0
    ENVOY_LOG(debug, "    config: {}",
118
0
              MessageUtil::getJsonStringFromMessageOrError(
119
0
                  static_cast<const Protobuf::Message&>(filter.typed_config()), true));
120
121
0
    auto& factory = Config::Utility::getAndCheckFactory<NamedUdpSessionFilterConfigFactory>(filter);
122
0
    ProtobufTypes::MessagePtr message = Envoy::Config::Utility::translateToFactoryConfig(
123
0
        filter, context.messageValidationVisitor(), factory);
124
0
    FilterFactoryCb callback = factory.createFilterFactoryFromProto(*message, context);
125
0
    filter_factories_.push_back(callback);
126
0
  }
127
0
}
128
129
static Registry::RegisterFactory<UdpProxyFilterConfigFactory,
130
                                 Server::Configuration::NamedUdpListenerFilterConfigFactory>
131
    register_;
132
133
} // namespace UdpProxy
134
} // namespace UdpFilters
135
} // namespace Extensions
136
} // namespace Envoy