Skip to content

Commit

Permalink
udp proxy: complete MVP
Browse files Browse the repository at this point in the history
Fixes #492

Signed-off-by: Matt Klein <mklein@lyft.com>
  • Loading branch information
mattklein123 committed Nov 16, 2019
1 parent a43e7f9 commit 8524995
Show file tree
Hide file tree
Showing 18 changed files with 707 additions and 104 deletions.
1 change: 1 addition & 0 deletions api/docs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ proto_library(
"//envoy/config/filter/network/zookeeper_proxy/v1alpha1:pkg",
"//envoy/config/filter/thrift/rate_limit/v2alpha1:pkg",
"//envoy/config/filter/thrift/router/v2alpha1:pkg",
"//envoy/config/filter/udp/udp_proxy/v2alpha:pkg",
"//envoy/config/grpc_credential/v2alpha:pkg",
"//envoy/config/health_checker/redis/v2:pkg",
"//envoy/config/listener/v2:pkg",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import "google/protobuf/duration.proto";

import "validate/validate.proto";

// TODO(mattklein123): docs
// [#protodoc-title: UDP proxy]
// UDP proxy :ref:`configuration overview <config_udp_listener_filters_udp_proxy>`.
// [#extension: envoy.filters.udp_listener.udp_proxy]

// Configuration for the UDP proxy filter.
message UdpProxyConfig {
Expand Down
5 changes: 3 additions & 2 deletions docs/root/api-v2/config/filter/filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ Filters
:glob:
:maxdepth: 2

listener/listener
network/network
udp/udp
http/http
thrift/thrift
accesslog/v2/accesslog.proto
fault/v2/fault.proto
listener/listener
dubbo/dubbo
thrift/thrift
8 changes: 8 additions & 0 deletions docs/root/api-v2/config/filter/udp/udp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
UDP listener filters
====================

.. toctree::
:glob:
:maxdepth: 2

*/v2alpha/*
1 change: 1 addition & 0 deletions docs/root/configuration/listeners/listeners.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ Listeners
stats
listener_filters/listener_filters
network_filters/network_filters
udp_filters/udp_filters
lds
11 changes: 11 additions & 0 deletions docs/root/configuration/listeners/udp_filters/udp_filters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.. _config_udp_listener_filters:

UDP listener filters
====================

Envoy has the following builtin UDP listener filters.

.. toctree::
:maxdepth: 2

udp_proxy
134 changes: 134 additions & 0 deletions docs/root/configuration/listeners/udp_filters/udp_proxy.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
.. _config_udp_listener_filters_udp_proxy:

UDP proxy
=========

.. attention::

UDP proxy support should be considered alpha and not production ready.

* :ref:`v2 API reference <envoy_api_msg_config.filter.udp.udp_proxy.v2alpha.UdpProxyConfig>`
* This filter should be configured with the name *envoy.filters.udp_listener.udp_proxy*

Overview
--------

The UDP proxy listener filter allows Envoy to operate as a *non-transparent* proxy between a
UDP client and server. The lack of transparency means that the upstream server will see the
source IP and port of the Envoy instance versus the client. All datagrams flow from the client, to
Envoy, to the upstream server, back to Envoy, and back to the client.

Because UDP is not a connection oriented protocol, Envoy must keep track of a client's *session*
such that the response datagrams from an upstream server can be routed back to the correct client.
Each session is index by the 4-tuple consisting of source IP/port and local IP/port that the
datagram is received on. Sessions last until the :ref:`idle timeout
<envoy_api_field_config.filter.udp.udp_proxy.v2alpha.UdpProxyConfig.idle_timeout>` is reached.

Load balancing and unhealthy host handling
------------------------------------------

Envoy will fully utilize the configured load balancer for the configured upstream cluster when
load balancing UDP datagrams. When a new session is created, Envoy will associate the session
with an upstream host selected using the configured load balancer. All future datagrams that
belong to the session will be routed to the same upstream host.

When an upstream host becomes unhealthy (due to :ref:`active health checking
<arch_overview_health_checking>`), Envoy will attempt to create a new session to a healthy host
when the next datagram is received.

Circuit breaking
----------------

The number of sessions that can be created per upstream cluster is limited by the cluster's
:ref:`maximum connection circuit breaker <arch_overview_circuit_break_cluster_maximum_connections>`.
By default this is 1024.

Example configuration
---------------------

The following example configuration will cause Envoy to listen on UDP port 1234 and proxy to a UDP
server listening on port 1235.

.. code-block:: yaml
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address:
protocol: TCP
address: 127.0.0.1
port_value: 9901
static_resources:
listeners:
- name: listener_0
address:
socket_address:
protocol: UDP
address: 127.0.0.1
port_value: 1234
listener_filters:
name: envoy.filters.udp_listener.udp_proxy
typed_config:
'@type': type.googleapis.com/envoy.config.filter.udp.udp_proxy.v2alpha.UdpProxyConfig
stat_prefix: service
cluster: service_udp
clusters:
- name: service_udp
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_udp
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 1235
Statistics
----------

The UDP proxy filter emits both its own downstream statistics as well as many of the :ref:`cluster
upstream statistics <config_cluster_manager_cluster_stats>` where applicable. The downstream
statistics are rooted at *udp.<stat_prefix>.* with the following statistics:

.. csv-table::
:header: Name, Type, Description
:widths: 1, 1, 2

downstream_sess_no_route, Counter, Number of datagrams not routed due to no cluster
downstream_sess_rx_bytes, Counter, Number of bytes received
downstream_sess_rx_datagrams, Counter, Number of datagrams received
downstream_sess_rx_errors, Counter, Number of datagram receive errors
downstream_sess_total, Counter, Number sessions created in total
downstream_sess_tx_bytes, Counter, Number of bytes transmitted
downstream_sess_tx_datagrams, Counter, Number of datagrams transmitted
downstream_sess_tx_errors, counter, Number of datagram transmission errors
idle_timeout, Counter, Number of sessions destroyed due to idle timeout
downstream_sess_active, Gauge, Number of sessions currently active

The following standard :ref:`upstream cluster stats <config_cluster_manager_cluster_stats>` are used
by the UDP proxy:

.. csv-table::
:header: Name, Type, Description
:widths: 1, 1, 2

upstream_cx_none_healthy, Counter, Number of datagrams dropped due to no healthy hosts
upstream_cx_overflow, Counter, Number of datagrams dropped due to hitting the session circuit breaker
upstream_cx_rx_bytes_total, Counter, Number of bytes received
upstream_cx_tx_bytes_total, Counter, Number of bytes transmitted

The UDP proxy filter also emits custom upstream cluster stats prefixed with
*cluster.<cluster_name>.udp.*:

.. csv-table::
:header: Name, Type, Description
:widths: 1, 1, 2

sess_rx_datagrams, Counter, Number of datagrams received
sess_rx_errors, Counter, Number of datagram receive errors
sess_tx_datagrams, Counter, Number of datagrams transmitted
sess_tx_errors, Counter, Number of datagrams tramsitted
16 changes: 15 additions & 1 deletion docs/root/intro/arch_overview/listeners/listeners.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ Listeners

The Envoy configuration supports any number of listeners within a single process. Generally we
recommend running a single Envoy per machine regardless of the number of configured listeners. This
allows for easier operation and a single source of statistics. Currently Envoy only supports TCP
allows for easier operation and a single source of statistics. Envoy supports both TCP and UDP
listeners.

TCP
---

Each listener is independently configured with some number :ref:`filter chains
<envoy_api_msg_listener.FilterChain>`, where an individual chain is selected based on its
:ref:`match criteria <envoy_api_msg_listener.FilterChainMatch>`. An individual filter chain is
Expand All @@ -29,3 +32,14 @@ Listeners can also be fetched dynamically via the :ref:`listener discovery servi
<config_listeners_lds>`.

Listener :ref:`configuration <config_listeners>`.

UDP
---

Envoy also supports UDP listeners and specifically :ref:`UDP listener filters
<config_udp_listener_filters>`. UDP listener filters are instantiated once per worker and are global
to that worker. Each listener filter processes each UDP datagram that is received by the worker
listening on the port. In practice, UDP listeners are configured with the SO_REUSEPORT kernel option
which will cause the kernel to consistently hash each UDP 4-tuple to the same worker. This allows a
UDP listener filter to be "session" oriented if it so desires. A built-in example of this
functionality is the :ref:`UDP proxy <config_udp_listener_filters_udp_proxy>` listener filter.
1 change: 1 addition & 0 deletions docs/root/intro/arch_overview/listeners/listeners_toc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Listeners
listener_filters
network_filters
tcp_proxy
udp_proxy
5 changes: 5 additions & 0 deletions docs/root/intro/arch_overview/listeners/udp_proxy.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
UDP proxy
=========

Envoy supports UDP proxy via the :ref:`UDP proxy listener filter
<config_udp_listener_filters_udp_proxy>`.
3 changes: 2 additions & 1 deletion docs/root/intro/version_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ Version history
* logger: added :ref:`--log-format-escaped <operations_cli>` command line option to escape newline characters in application logs.
* redis: performance improvement for larger split commands by avoiding string copies.
* router: added support for REQ(header-name) :ref:`header formatter <config_http_conn_man_headers_custom_request_headers>`.
* router: exposed DOWNSTREAM_REMOTE_ADDRESS as custom HTTP request/response headers.
* server: fixed a bug in config validation for configs with runtime layers
* tcp_proxy: added :ref:`ClusterWeight.metadata_match<envoy_api_field_config.filter.network.tcp_proxy.v2.TcpProxy.WeightedCluster.ClusterWeight.metadata_match>`
* tcp_proxy: added :ref:`hash_policy<envoy_api_field_config.filter.network.tcp_proxy.v2.TcpProxy.hash_policy>`
* thrift_proxy: added support for cluster header based routing.
* tls: remove TLS 1.0 and 1.1 from client defaults
* router: exposed DOWNSTREAM_REMOTE_ADDRESS as custom HTTP request/response headers.
* udp: added initial support for :ref:`UDP proxy <config_udp_listener_filters_udp_proxy>`

1.12.0 (October 31, 2019)
=========================
Expand Down
2 changes: 1 addition & 1 deletion include/envoy/upstream/resource_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class ResourceManager {
virtual ~ResourceManager() = default;

/**
* @return Resource& active TCP connections.
* @return Resource& active TCP connections and UDP sessions.
*/
virtual Resource& connections() PURE;

Expand Down
1 change: 0 additions & 1 deletion source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ EXTENSIONS = {
# UDP filters
#

# WiP
"envoy.filters.udp_listener.udp_proxy": "//source/extensions/filters/udp/udp_proxy:config",

#
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/filters/udp/udp_proxy/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ envoy_cc_extension(
srcs = ["config.cc"],
hdrs = ["config.h"],
security_posture = "robust_to_untrusted_downstream",
status = "wip",
status = "alpha",
deps = [
":udp_proxy_filter_lib",
"//include/envoy/registry",
Expand Down
Loading

0 comments on commit 8524995

Please sign in to comment.