-
Notifications
You must be signed in to change notification settings - Fork 5.3k
WIP: UDP proxy - basic listener. #5256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ef4b057
c392741
45a4431
28d1dd9
f86d37d
8bfc49c
bd92dab
9fdbd18
05c0656
c40d66b
bf64f9d
0f3f8c6
d00d04b
ba93d69
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,10 +125,14 @@ envoy_cc_library( | |
| envoy_cc_library( | ||
| name = "listener_lib", | ||
| srcs = [ | ||
| "base_listener_impl.cc", | ||
| "listener_impl.cc", | ||
| "udp_listener_impl.cc", | ||
|
||
| ], | ||
| hdrs = [ | ||
| "base_listener_impl.h", | ||
| "listener_impl.h", | ||
| "udp_listener_impl.h", | ||
| ], | ||
| deps = [ | ||
| ":address_lib", | ||
|
|
@@ -138,6 +142,7 @@ envoy_cc_library( | |
| "//include/envoy/network:listener_interface", | ||
| "//include/envoy/stats:stats_interface", | ||
| "//include/envoy/stats:stats_macros", | ||
| "//source/common/buffer:buffer_lib", | ||
| "//source/common/common:assert_lib", | ||
| "//source/common/common:empty_string", | ||
| "//source/common/common:linked_object", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #include "common/network/base_listener_impl.h" | ||
|
|
||
| #include <sys/un.h> | ||
|
|
||
| #include "envoy/common/exception.h" | ||
|
|
||
| #include "common/common/assert.h" | ||
| #include "common/common/empty_string.h" | ||
| #include "common/common/fmt.h" | ||
| #include "common/event/dispatcher_impl.h" | ||
| #include "common/event/file_event_impl.h" | ||
| #include "common/network/address_impl.h" | ||
|
|
||
| #include "event2/listener.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Network { | ||
|
|
||
| Address::InstanceConstSharedPtr BaseListenerImpl::getLocalAddress(int fd) { | ||
| return Address::addressFromFd(fd); | ||
| } | ||
|
|
||
| BaseListenerImpl::BaseListenerImpl(const Event::DispatcherImpl& dispatcher, Socket& socket) | ||
| : local_address_(nullptr), dispatcher_(dispatcher), socket_(socket) { | ||
| const auto ip = socket.localAddress()->ip(); | ||
|
|
||
| // Only use the listen socket's local address for new connections if it is not the all hosts | ||
| // address (e.g., 0.0.0.0 for IPv4). | ||
| if (!(ip && ip->isAnyAddress())) { | ||
| local_address_ = socket.localAddress(); | ||
| } | ||
| } | ||
|
|
||
| } // namespace Network | ||
| } // namespace Envoy |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| #pragma once | ||
|
|
||
| #include "envoy/network/listener.h" | ||
|
|
||
| #include "common/event/dispatcher_impl.h" | ||
| #include "common/event/libevent.h" | ||
| #include "common/network/listen_socket_impl.h" | ||
|
|
||
| #include "event2/event.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Network { | ||
|
|
||
| /** | ||
| * Base libevent implementation of Network::Listener. | ||
| */ | ||
| class BaseListenerImpl : public Listener { | ||
| public: | ||
| BaseListenerImpl(const Event::DispatcherImpl& dispatcher, Socket& socket); | ||
|
|
||
| protected: | ||
| virtual Address::InstanceConstSharedPtr getLocalAddress(int fd); | ||
|
|
||
| Address::InstanceConstSharedPtr local_address_; | ||
| const Event::DispatcherImpl& dispatcher_; | ||
| Socket& socket_; | ||
| }; | ||
|
|
||
| } // namespace Network | ||
| } // namespace Envoy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think at some layer we're going to want to have the Udp stack have the equivalent of the existing ListenerCallbacks. While it's true that there's no UDP accept, the concepts "I have a new connection" and "I have gone through a series of filters acting at a very low level before I formally accept the connection" may still apply. Looking at Envoy listener filters, there's proxy proto and tls inspector. I think we can have similar functionality for UDP - we have our own hacked version of the proxy protocol header which we achieve via packet munging and Envoy will want an equivalent, and you can totally SNI-sniff QUIC.
Envoy current listener filters do work by delaying accept and doing peek, which is so not working for UDP :-P That said in-house there are areas where we do light-weight packet queueing until we have enough data we can tell how to proceed, so I think a logical equivalent of listener filters and "peek" do still kind of work and we will want them at the end of the day.
I'm fine landing this as-is, with a TODO to investigate sharing ListenerCallback in future once we have more of a handle of how things are going, but I figure it's at least worth discussing now. It may be worth at least considering if we can reuse more of the existing listener code now, with just config rejection if anyone tries to insert a tcp listener filter on the UDP stack.
@mpwarres @mattklein123
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, my thinking was to share as many of the public interfaces we have now as possible until we figure out we absolutely can't do it. Could we start potentially with that being the goal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also the original_src filter I'm writing (#5337). It should work just as well with UDP as with TCP as long as something can figure out the source (i.e. UDP version of proxy protocol) prior to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alyssawilk I think the UDP listener should be able to do what you suggested. Since at the UDP listener layer, we are still dealing with "Buffer", we should be able to stack filters. Right?