Internal Listener

How it works

This extension contains 2 major components to add a listener with an Envoy internal address and to create a client connection to that listener

envoy.bootstrap.internal_listener

This bootstrap extension is required to support looking up the target listener via an envoy internal address on each worker threads.

network.connection.client.envoy_internal

It is a client connection factory. The factory is implicitly instantiated by the dispatcher to establish a client connection to an internal listener address. This client connection factory is installed automatically when envoy.bootstrap.internal_listener is specified.

Example config

Below is a smallest static config that redirect TCP proxy on port 19000 to the TCP proxy binding to the internal address.

  1. static_resources:
  2. listeners:
  3. - name: outbound_tcp_svc_19000
  4. address:
  5. socket_address:
  6. address: 0.0.0.0
  7. port_value: 19000
  8. filter_chains:
  9. - filters:
  10. - name: tcp_proxy
  11. typed_config:
  12. "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
  13. cluster: bridge_internal_listener
  14. stat_prefix: svc_tcp_proxy
  15. - name: singleton_internal_encap
  16. address:
  17. envoy_internal_address:
  18. server_listener_name: singleton_internal_encap
  19. filter_chains:
  20. - filters:
  21. - name: tcp_proxy
  22. typed_config:
  23. "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
  24. cluster: singleton_internal_encap
  25. stat_prefix: encap_tcp_proxy
  26. clusters:
  27. - name: bridge_internal_listener
  28. connect_timeout: 3600s
  29. type: STATIC
  30. load_assignment:
  31. cluster_name: "bridge_internal_listener"
  32. endpoints:
  33. - lb_endpoints:
  34. - endpoint:
  35. address:
  36. envoy_internal_address:
  37. server_listener_name: singleton_internal_encap
  38. transport_socket:
  39. name: envoy.transport_sockets.raw_buffer
  40. typed_config:
  41. "@type": type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer
  42. - name: singleton_internal_encap
  43. connect_timeout: 3600s
  44. type: STATIC
  45. load_assignment:
  46. cluster_name: "singleton_internal_encap"
  47. endpoints:
  48. - lb_endpoints:
  49. - endpoint:
  50. address:
  51. socket_address:
  52. address: 0.0.0.0
  53. port_value: 19001
  54. bootstrap_extensions:
  55. - name: envoy.bootstrap.internal_listener
  56. typed_config:
  57. "@type": "type.googleapis.com/envoy.extensions.bootstrap.internal_listener.v3.InternalListener"
  58. layered_runtime:
  59. layers:
  60. - name: enable_internal_address
  61. static_layer:
  62. envoy.reloadable_features.internal_address: true

Real world use cases

Encap HTTP GET requests in a HTTP CONNECT request

Currently Envoy HTTP connection manager cannot proxy a GET request in an upstream HTTP CONNECT request. This requirement can be acomplished by setting up the upstream endpoint of HTTP connection manager to the internal listener address. Meanwhile, another internal listener binding to the above listener address includes a TCP proxy with tunneling config.

Decap the CONNECT requests

There are some complicated GET-in-CONNECT requests across services or edges. In order to proxy the GET request within Envoy, two layer of HTTP connection manager is demanded. The first HHTTP connection manager layer extract the TCP stream from a CONNECT request and redirect the TCP stream to the second HTTP connection manager layer to parse the common GET requests.