Skip to content

Commit d39bd81

Browse files
danzh2010mattklein123
authored andcommitted
udp_listener: refactor ActiveUdpListener creation (envoyproxy#7884)
Signed-off-by: Dan Zhang <[email protected]>
1 parent fdd0e01 commit d39bd81

25 files changed

+386
-102
lines changed

api/envoy/api/v2/BUILD

+2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ api_proto_library_internal(
109109
"//envoy/api/v2/core:address",
110110
"//envoy/api/v2/core:base",
111111
"//envoy/api/v2/listener",
112+
"//envoy/api/v2/listener:udp_listener_config",
112113
],
113114
)
114115

@@ -120,6 +121,7 @@ api_go_grpc_library(
120121
"//envoy/api/v2/core:address_go_proto",
121122
"//envoy/api/v2/core:base_go_proto",
122123
"//envoy/api/v2/listener:listener_go_proto",
124+
"//envoy/api/v2/listener:udp_listener_config_go_proto",
123125
],
124126
)
125127

api/envoy/api/v2/lds.proto

+10-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import "envoy/api/v2/core/address.proto";
1212
import "envoy/api/v2/core/base.proto";
1313
import "envoy/api/v2/discovery.proto";
1414
import "envoy/api/v2/listener/listener.proto";
15+
import "envoy/api/v2/listener/udp_listener_config.proto";
1516

1617
import "google/api/annotations.proto";
1718
import "google/protobuf/duration.proto";
@@ -44,7 +45,7 @@ service ListenerDiscoveryService {
4445
}
4546
}
4647

47-
// [#comment:next free field: 18]
48+
// [#comment:next free field: 19]
4849
message Listener {
4950
// The unique name by which this listener is known. If no name is provided,
5051
// Envoy will allocate an internal UUID for the listener. If the listener is to be dynamically
@@ -194,4 +195,12 @@ message Listener {
194195

195196
// Specifies the intended direction of the traffic relative to the local Envoy.
196197
core.TrafficDirection traffic_direction = 16;
198+
199+
// If the protocol in the listener socket address in :ref:`protocol
200+
// <envoy_api_field_core.SocketAddress.protocol>` is :ref:'UDP
201+
// <envoy_api_field_core.Protocol.UDP>`, this field specifies the actual udp listener to create,
202+
// i.e. :ref:`udp_listener_name
203+
// <envoy_api_field_listener.UdpListenerConfig.udp_listener_name>` = "raw_udp_listener" for
204+
// creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener".
205+
listener.UdpListenerConfig udp_listener_config = 18;
197206
}

api/envoy/api/v2/listener/BUILD

+17
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,20 @@ api_go_proto_library(
2222
"//envoy/api/v2/core:base_go_proto",
2323
],
2424
)
25+
26+
api_proto_library_internal(
27+
name = "udp_listener_config",
28+
srcs = ["udp_listener_config.proto"],
29+
visibility = ["//envoy/api/v2:friends"],
30+
deps = [
31+
"//envoy/api/v2/core:base",
32+
],
33+
)
34+
35+
api_go_proto_library(
36+
name = "udp_listener_config",
37+
proto = ":udp_listener_config",
38+
deps = [
39+
"//envoy/api/v2/core:base_go_proto",
40+
],
41+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
syntax = "proto3";
2+
3+
package envoy.api.v2.listener;
4+
5+
option java_outer_classname = "ListenerProto";
6+
option java_multiple_files = true;
7+
option java_package = "io.envoyproxy.envoy.api.v2.listener";
8+
option go_package = "listener";
9+
option csharp_namespace = "Envoy.Api.V2.ListenerNS";
10+
option ruby_package = "Envoy::Api::V2::ListenerNS";
11+
12+
import "google/protobuf/struct.proto";
13+
import "google/protobuf/any.proto";
14+
15+
// [#protodoc-title: Udp Listener Config]
16+
// Listener :ref:`configuration overview <config_listeners>`
17+
18+
message UdpListenerConfig {
19+
// Used to look up UDP listener factory, matches "raw_udp_listener" or
20+
// "quic_listener" to create a specific udp listener.
21+
// If not specified, treat as "raw_udp_listener".
22+
string udp_listener_name = 1;
23+
24+
// Used to create a specific listener factory. To some factory, e.g.
25+
// "raw_udp_listener", config is not needed.
26+
oneof config_type {
27+
google.protobuf.Struct config = 2;
28+
29+
google.protobuf.Any typed_config = 3;
30+
}
31+
}

docs/build.sh

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ PROTO_RST="
8282
/envoy/api/v2/srds/envoy/api/v2/srds.proto.rst
8383
/envoy/api/v2/lds/envoy/api/v2/lds.proto.rst
8484
/envoy/api/v2/listener/listener/envoy/api/v2/listener/listener.proto.rst
85+
/envoy/api/v2/listener/udp_listener_config/envoy/api/v2/listener/udp_listener_config.proto.rst
8586
/envoy/api/v2/ratelimit/ratelimit/envoy/api/v2/ratelimit/ratelimit.proto.rst
8687
/envoy/config/accesslog/v2/als/envoy/config/accesslog/v2/als.proto.rst
8788
/envoy/config/accesslog/v2/file/envoy/config/accesslog/v2/file.proto.rst

docs/root/api-v2/listeners/listeners.rst

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ Listeners
77

88
../api/v2/lds.proto
99
../api/v2/listener/listener.proto
10+
../api/v2/listener/udp_listener_config.proto

include/envoy/network/connection_handler.h

+50
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,59 @@ class ConnectionHandler {
6868
* after they have been temporarily disabled.
6969
*/
7070
virtual void enableListeners() PURE;
71+
72+
/**
73+
* Used by ConnectionHandler to manage listeners.
74+
*/
75+
class ActiveListener {
76+
public:
77+
virtual ~ActiveListener() = default;
78+
79+
/**
80+
* @return the tag value as configured.
81+
*/
82+
virtual uint64_t listenerTag() PURE;
83+
/**
84+
* @return the actual Listener object.
85+
*/
86+
virtual Listener* listener() PURE;
87+
/**
88+
* Destroy the actual Listener it wraps.
89+
*/
90+
virtual void destroy() PURE;
91+
};
92+
93+
using ActiveListenerPtr = std::unique_ptr<ActiveListener>;
7194
};
7295

7396
using ConnectionHandlerPtr = std::unique_ptr<ConnectionHandler>;
7497

98+
/**
99+
* A registered factory interface to create different kinds of
100+
* ActiveUdpListener.
101+
*/
102+
class ActiveUdpListenerFactory {
103+
public:
104+
virtual ~ActiveUdpListenerFactory() = default;
105+
106+
/**
107+
* Creates an ActiveUdpListener object and a corresponding UdpListener
108+
* according to given config.
109+
* @param parent is the owner of the created ActiveListener objects.
110+
* @param dispatcher is used to create actual UDP listener.
111+
* @param logger might not need to be passed in.
112+
* TODO(danzh): investigate if possible to use statically defined logger in ActiveUdpListener
113+
* implementation instead.
114+
* @param config provides information needed to create ActiveUdpListener and
115+
* UdpListener objects.
116+
* @return the ActiveUdpListener created.
117+
*/
118+
virtual ConnectionHandler::ActiveListenerPtr
119+
createActiveUdpListener(ConnectionHandler& parent, Event::Dispatcher& disptacher,
120+
spdlog::logger& logger, Network::ListenerConfig& config) const PURE;
121+
};
122+
123+
using ActiveUdpListenerFactoryPtr = std::unique_ptr<ActiveUdpListenerFactory>;
124+
75125
} // namespace Network
76126
} // namespace Envoy

include/envoy/network/listener.h

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace Envoy {
1414
namespace Network {
1515

1616
class UdpListenerFilterManager;
17+
class ActiveUdpListenerFactory;
1718

1819
/**
1920
* A configuration for an individual listener.
@@ -90,6 +91,12 @@ class ListenerConfig {
9091
* @return const std::string& the listener's name.
9192
*/
9293
virtual const std::string& name() const PURE;
94+
95+
/**
96+
* @return factory pointer if listening on UDP socket, otherwise return
97+
* nullptr.
98+
*/
99+
virtual const ActiveUdpListenerFactory* udpListenerFactory() PURE;
93100
};
94101

95102
/**

include/envoy/server/BUILD

+6
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,9 @@ envoy_cc_library(
256256
"@envoy_api//envoy/config/trace/v2:trace_cc",
257257
],
258258
)
259+
260+
envoy_cc_library(
261+
name = "active_udp_listener_config_interface",
262+
hdrs = ["active_udp_listener_config.h"],
263+
deps = ["//include/envoy/network:connection_handler_interface"],
264+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include "envoy/network/connection_handler.h"
4+
5+
namespace Envoy {
6+
namespace Server {
7+
8+
/**
9+
* Interface to create udp listener according to
10+
* envoy::api::v2::listener::UdpListenerConfig.udp_listener_name.
11+
*/
12+
class ActiveUdpListenerConfigFactory {
13+
public:
14+
virtual ~ActiveUdpListenerConfigFactory() = default;
15+
16+
/**
17+
* Create an ActiveUdpListenerFactory object according to given message.
18+
*/
19+
virtual Network::ActiveUdpListenerFactoryPtr
20+
createActiveUdpListenerFactory(const Protobuf::Message& message) PURE;
21+
22+
/**
23+
* Used to identify which udp listener to create: quic or raw udp.
24+
*/
25+
virtual std::string name() PURE;
26+
};
27+
28+
} // namespace Server
29+
} // namespace Envoy

source/server/BUILD

+21
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ envoy_cc_library(
6464
"//include/envoy/network:filter_interface",
6565
"//include/envoy/network:listen_socket_interface",
6666
"//include/envoy/network:listener_interface",
67+
"//include/envoy/server:active_udp_listener_config_interface",
6768
"//include/envoy/server:listener_manager_interface",
6869
"//include/envoy/stats:timespan",
6970
"//source/common/common:linked_object",
@@ -260,6 +261,8 @@ envoy_cc_library(
260261
":filter_chain_manager_lib",
261262
":lds_api_lib",
262263
":transport_socket_config_lib",
264+
":well_known_names_lib",
265+
"//include/envoy/server:active_udp_listener_config_interface",
263266
"//include/envoy/server:filter_config_interface",
264267
"//include/envoy/server:listener_manager_interface",
265268
"//include/envoy/server:transport_socket_config_interface",
@@ -441,3 +444,21 @@ envoy_cc_library(
441444
"//include/envoy/server:transport_socket_config_interface",
442445
],
443446
)
447+
448+
envoy_cc_library(
449+
name = "well_known_names_lib",
450+
hdrs = ["well_known_names.h"],
451+
deps = ["//source/common/singleton:const_singleton"],
452+
)
453+
454+
envoy_cc_library(
455+
name = "active_raw_udp_listener_config",
456+
srcs = ["active_raw_udp_listener_config.cc"],
457+
hdrs = ["active_raw_udp_listener_config.h"],
458+
deps = [
459+
":connection_handler_lib",
460+
":well_known_names_lib",
461+
"//include/envoy/registry",
462+
"//include/envoy/server:active_udp_listener_config_interface",
463+
],
464+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "server/active_raw_udp_listener_config.h"
2+
3+
#include "server/connection_handler_impl.h"
4+
#include "server/well_known_names.h"
5+
6+
namespace Envoy {
7+
namespace Server {
8+
9+
Network::ConnectionHandler::ActiveListenerPtr ActiveRawUdpListenerFactory::createActiveUdpListener(
10+
Network::ConnectionHandler& /*parent*/, Event::Dispatcher& dispatcher,
11+
spdlog::logger& /*logger*/, Network::ListenerConfig& config) const {
12+
return std::make_unique<ActiveUdpListener>(dispatcher, config);
13+
}
14+
15+
Network::ActiveUdpListenerFactoryPtr
16+
ActiveRawUdpListenerConfigFactory::createActiveUdpListenerFactory(
17+
const Protobuf::Message& /*message*/) {
18+
return std::make_unique<Server::ActiveRawUdpListenerFactory>();
19+
}
20+
21+
std::string ActiveRawUdpListenerConfigFactory::name() { return UdpListenerNames::get().RawUdp; }
22+
23+
REGISTER_FACTORY(ActiveRawUdpListenerConfigFactory, Server::ActiveUdpListenerConfigFactory);
24+
25+
} // namespace Server
26+
} // namespace Envoy
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include "envoy/network/connection_handler.h"
4+
#include "envoy/registry/registry.h"
5+
#include "envoy/server/active_udp_listener_config.h"
6+
7+
namespace Envoy {
8+
namespace Server {
9+
10+
class ActiveRawUdpListenerFactory : public Network::ActiveUdpListenerFactory {
11+
public:
12+
Network::ConnectionHandler::ActiveListenerPtr
13+
createActiveUdpListener(Network::ConnectionHandler& parent, Event::Dispatcher& disptacher,
14+
spdlog::logger& logger, Network::ListenerConfig& config) const override;
15+
};
16+
17+
// This class uses a protobuf config to create a UDP listener factory which
18+
// creates a Server::ConnectionHandlerImpl::ActiveUdpListener.
19+
// This is the default UDP listener if not specified in config.
20+
class ActiveRawUdpListenerConfigFactory : public ActiveUdpListenerConfigFactory {
21+
public:
22+
Network::ActiveUdpListenerFactoryPtr
23+
createActiveUdpListenerFactory(const Protobuf::Message&) override;
24+
25+
std::string name() override;
26+
};
27+
28+
DECLARE_FACTORY(ActiveRawUdpListenerConfigFactory);
29+
30+
} // namespace Server
31+
} // namespace Envoy

0 commit comments

Comments
 (0)