-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Introducing UDP listener. #5473
Conversation
void UdpListenerImpl::enable() { event_add(&raw_event_, nullptr); } | ||
|
||
void UdpListenerImpl::readCallback(int fd, short flags, void* arg) { | ||
(void)flags; |
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.
UNREFERENCED_PARAMETER?
@mattklein123 @alyssawilk @mpwarres PTAL This PR is first of the series for UDP proxying. This is extracted from the WIP #5256. I will eventuallu close #5246. |
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.
This is cool!! Just a few high-level comments.
* @param bind_to_port controls whether the listener binds to a transport port or not. | ||
* @return Network::ListenerPtr a new listener that is owned by the caller. | ||
*/ | ||
virtual Network::ListenerPtr createUdpListener(Network::Socket& socket, |
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.
Wondering whether we will ever want to support proxying datagrams over Unix domain sockets, in addition to over UDP. (Analogous to current Envoy support for pipes vs. TCP connections.) If so, then it might be more general to name this createDatagramListener. Or maybe UDS datagrams aren't worth supporting, in which case current name SGTM.
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.
@mpwarres Does gQUIC currently use Unix domain sockets for proxying datagrams? I vaguely recall hearing about a potential experiment with them in a QUIC talk.
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.
Not that I'm aware. We have used SOCK_DGRAM + shared memory to allow GFEs (speaking QUIC) to efficiently front for other (non QUIC speaking) servers, but AIUI there the datagrams were just for coordinating shared memory use, not for carrying QUIC traffic. Not sure if @ianswett may have mentioned this in one of his talks, perhaps this one, though I don't see it in the slides. The comment I posted upthread was more hypothetical--I don't have a concrete use case.
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 don't have a strong opinion on this, though createDatagramListener()
does seem more generic.
include/envoy/network/listener.h
Outdated
* @param peer_address Network address of the peer. | ||
* @param data Data buffer received. | ||
*/ | ||
virtual void onData(Address::InstanceConstSharedPtr local_address, |
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.
Relaying a comment originally made by ianswett@chromium.org on an earlier listener sketch, which also applies here: from the perspective of QUIC (which will eventually use this), it would be desirable to bundle (local_address, peer_address, data) in a Datagram or Packet object, to accomodate possible future addition of other attributes, e.g. TTL. E.g., something like this.
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
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 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.
Seems fine to just make a struct now to carry the data if we want that? That will avoid a lot of code site changes later to add new fields.
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, let's totally make it a struct sooner rather than later.
*/ | ||
virtual void onError(const ErrorCode& err_code, int err_no) PURE; | ||
}; | ||
|
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.
Seems like the listener might also need to be notified when the UDP socket is writable? AIUI, in the TCP case, this interaction is a little hidden: ListenerCallbacks::onNewConnection() provides a Network::Connection, and that Connection is set up with the Dispatcher to receive events when the connection socket is readable or writable: link. The "is readable" transition is already covered by UdpListenerCallbacks::onData(), but seems like there will need to be something somewhere for the "is writable" side, to let the receipient know when it can flush/write more packets.
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.
Good point. So I guess we need another callback onWriteReady
?
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 it depends on the UdpListenerCallbacks vs. ListenerCallbacks question. If you go with the already existing ListenerCallbacks interface like @alyssawilk is suggesting, then it would make sense to reflect writability inside the Connection implementation, i.e. Event::FileReadyType::Write -> UdpConnectionImpl::onWriteReady() which could flush any buffered packets that are waiting to be written, paired with a UdpConnectionImpl::write() implementation that buffers packets when the socket is not currently writable.
If you go with UdpListenerCallbacks, then yeah, I guess there would need to be something like an onWriteReady(), and it would need to supply something to write to (either the Socket, or an interface for writing a packet).
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.
Not sure how to reuse existing ListenerCallbacks
for UDP since it has connection concepts. I am leaning towards having onWriteReady
in UdpListener
. Let me know if you (@alyssawilk) feel strongly about this.
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.
This is related to my comment above about whether we are doing connection oriented or not. IMO I'm leaning towads splitting UDP into 2 types: 1) What you have now, which is geared towards datagram, and 2) One listener type which uses normal listener callbacks, and spits out connections which then supports existing filters. Thoughts?
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.
Cool! Very excited to see progress here.
include/envoy/event/dispatcher.h
Outdated
* Create a logical udp listener on a specific port. | ||
* @param socket supplies the socket to listen on. | ||
* @param cb supplies the udp listener callbacks to invoke for listener events. | ||
* @param bind_to_port controls whether the listener binds to a transport port or not. |
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.
Any chance we can nix bind_to_port (always pass true to base classes)? We're trying to remove it for TCP (#5355) so I'd love to just not support it for UDP from the get go.
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.
makes sense
include/envoy/network/listener.h
Outdated
virtual ~UdpListenerCallbacks() = default; | ||
|
||
/** | ||
* On first packet received on a UDP socket. This allows the callback handler |
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.
super nitty: can we pick udp / UDP / Udp and use consistently?
I'd lean towards udp (Udp iff the first word in a sentence)
include/envoy/network/listener.h
Outdated
/** | ||
* Called when there is an error event. | ||
* | ||
* @param error_code `ErrorCode` for tbe error event. |
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.
tbe -> the error
I'd skip the backticks around ErrorCode too.
source/common/buffer/buffer_impl.cc
Outdated
Api::SysCallIntResult OwnedImpl::recvFrom(int fd, uint64_t max_length, sockaddr_storage& peer_addr, | ||
socklen_t& addr_len) { | ||
if (max_length == 0) { | ||
return {0, 0}; |
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.
not EINVALIDARG?
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 was trying to be consistent with the same case handled elsewhere in the code. But it makes sense to return EINVALIDARG
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.
Thinking about it a little more, here the system call is not invoked so would it be reflective of the real state of the process to change errno
?
source/common/buffer/buffer_impl.cc
Outdated
slice.len_ = std::min(slice.len_, static_cast<size_t>(rc)); | ||
commit(&slice, 1); | ||
|
||
return {static_cast<int>(rc), errno}; |
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.
unless you can prove that commit doesn't (and never will) tweak errno, I'd suggest either latching errno or passing an explicit 0 in the return here.
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.
makes sense
source/common/buffer/buffer_impl.cc
Outdated
const uint64_t num_slices = reserve(max_length, &slice, 1); | ||
|
||
ASSERT(num_slices == 1); | ||
// TODO(conqerAtapple): Use os_syscalls |
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'd like to structure this code to be recvmmsg friendly and I'm not sure how best to do it. Functionally here we
- tell the buffer to read one packet
- (eventually) dispatch one packet's worth of data to upper layers
Where I think we're doing to want to
- read many packets (via recvmmsg, rx_ring whatever)
- create shim buffers around those packets to hand data to upper layers
which just makes me wonder if we want this code to live in the buffer (as it does for TCP) or a utility function (which uses the raw reserved data).
I'm also 100% fine landing this today and moving it later as long as we keep in mind that it's likely to move.
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.
Wondering if we should leave it as is for now. I am still trying to figure out how this will fit into the QUIC implementation APIs. Looking at the chromium source, the API there looks to be recvfrom
friendly. Maybe I am reading it wrong. @mpwarres ?
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.
The Chromium QUIC code can do either. QuicPacketReader::ReadAndDispatchPackets() reads packets either via recvmsg or recvmmsg depending on whether the macro MMSG_MORE is set (see QuicPacketReader::ReadAndDispatchPackets()). Then, independent of whether the packets were read individually or as a batch, they are passed one by one into the ProcessPacket() method of either QuicDispatcher (if server) or QuicClientEpollNetworkHelper (if client).
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.
Yeah, I think both for QUIC and for other UDP applications we're going to want to read-many then dispatch-one-at-a-time. While I don't think we want to implement that code right now (launch and iterate!) I just want to make sure we design the APIs for it.
Then again I'm also fine landing this as is and moving it later - I don't personally mind a lot of code churn while we feel our way out as long as we all know what we're getting into :-P
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 agree that we need a recvmmsg
implementation also (thanks to @mpwarres for clarifying). I am not sure how do we pass configurable parameters (number of messages for recvmmsg) to the listener. At this this I am leaning towards adding TODO for recvmmsg and attack that in my next PR.
/** | ||
* UDP listener callbacks. | ||
*/ | ||
class UdpListenerCallbacks { |
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 thought Matt requested on the prior PR that we try to stick to listenercallbacks where possible?
I'd think the current code could be a subclass of ListenerCallbacks, where onAccept was commeted as "accepting new data" rather than "accepting a new connection", we call onNewConnection where we currently do (but with a UdpConnection subclass which may be filled with TODOs, but we pass the local address and the peer address to it) and then hand onData calls to the new connection?
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.
Same comment as above. The current ListenerCallbacks
interface exposes connection concept. Inheriting that interface would semantically mean - UdpListenerCallbacks
is-a
ListenerCallbacks
. Not sure if we mean that. What about having a bridge
that bridges the UDP listener to the existing ListenerCallbacks
? This bridge could be a concrete implementation of a UdpListenerCallbacks
interface. Thinking out loud here. Would he happy to hear what you think.
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.
See my comments below.
include/envoy/network/listener.h
Outdated
|
||
/** | ||
* On first packet received on a UDP socket. This allows the callback handler | ||
* to establish filter chain (or any other prepararion). |
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.
* to establish filter chain (or any other prepararion). | |
* to establish filter chain (or any other preparation). |
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.
Flushing out some comments at the interface layer. I did not look at the implementation/tests yet. Very cool to see this happening.
include/envoy/buffer/buffer.h
Outdated
@@ -168,6 +168,9 @@ class Instance { | |||
*/ | |||
virtual Api::SysCallIntResult read(int fd, uint64_t max_length) PURE; | |||
|
|||
virtual Api::SysCallIntResult recvFrom(int fd, uint64_t max_length, |
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.
nit: doc comments. As a larger comment, I would love to remove any type of file IO from the buffer interface moving forward since in the long term I don't think it fits with our FD refactors. Any thoughts on how we might not add it for this case since it's new? cc @brian-pane who is working on a new buffer impl.
* @param bind_to_port controls whether the listener binds to a transport port or not. | ||
* @return Network::ListenerPtr a new listener that is owned by the caller. | ||
*/ | ||
virtual Network::ListenerPtr createUdpListener(Network::Socket& socket, |
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 don't have a strong opinion on this, though createDatagramListener()
does seem more generic.
/** | ||
* UDP listener callbacks. | ||
*/ | ||
class UdpListenerCallbacks { |
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.
See my comments below.
include/envoy/network/listener.h
Outdated
* @param peer_address Network address of the peer. | ||
* @param data Data buffer received. | ||
*/ | ||
virtual void onNewConnection(Address::InstanceConstSharedPtr local_address, |
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 assume for the purpose of this PR, we are looking at stateless vs. connection oriented proxy, right? I guess my question comes down to, at this layer, what does onNewConnection()
give us. It seems like there must be internal tracking to figure out whether this is "new", but then how are connections ever going to get cleaned up? Where is the interface for that? It seems like at this datagram layer, we could just have onData()
and these are the interfaces for raw datagram listening. If we want connection oriented, could we just use the normal ListenerCallbacks which spit out normal connections which are then UdpConnectionImpl? Thoughts on this?
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.
@mattklein123
Thanks for reviewing.
What about layering the connection concept on top of UDP/datagram? This would allow us to have 1 common buffer
layer and then connections (eg QUIC) on top of it. When a connection oriented filter (QUIC) gets the onNewConnection
event, it can then decide to do things like 1) prepare the protocol layers 2) Carve a protocol specific Packet
and send it up the protocol layer.
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.
The problem is I don't understand how this layer is going to do conn tracking if the API looks like this. I think you need an API to "delete" a connection if that's the case?
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.
@mattklein123 Since this layer does not have a concept of Connection, it doesn't need to track connections. Right? I would think that something like QuicListener(that implements the UdpListenerCallbacks) could be tracking connections. No?
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.
But then I think the onNewConnection
API needs to be removed? What does a new connection mean without conn tracking?
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.
Yes that is a good point. The book keeping of if this is the first data packet
has to be done somewhere, assuming that the state of first data
is important to track. If it is not, then the API onNewConnection
need not be there.
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.
Yeah IMO if we are going to build connection oriented on top of this, I would kill onNewConnection
and any tracking from this PR.
include/envoy/network/listener.h
Outdated
* @param peer_address Network address of the peer. | ||
* @param data Data buffer received. | ||
*/ | ||
virtual void onData(Address::InstanceConstSharedPtr local_address, |
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.
Seems fine to just make a struct now to carry the data if we want that? That will avoid a lot of code site changes later to add new fields.
*/ | ||
virtual void onError(const ErrorCode& err_code, int err_no) PURE; | ||
}; | ||
|
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.
This is related to my comment above about whether we are doing connection oriented or not. IMO I'm leaning towads splitting UDP into 2 types: 1) What you have now, which is geared towards datagram, and 2) One listener type which uses normal listener callbacks, and spits out connections which then supports existing filters. Thoughts?
@mattklein123 @mpwarres @alyssawilk @cmluciano Thanks for reviewing. I am summarizing the changes:
In my next PR(s):
What do you guys think? |
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.
looking better and better!
include/envoy/network/listener.h
Outdated
*/ | ||
struct UdpData { | ||
Address::InstanceConstSharedPtr local_address_; | ||
Address::InstanceConstSharedPtr peer_address_; |
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 suspect we can get away with unique pointers here and I'd prefer to if we can get away with it, but I'm fine sorting out ownership in a follow-up.
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.
good point . Will change it to unique_ptr
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 was looking at it again and it looks like it might be difficult to change local_address
to a unique_ptr as it is derived from the listener's Socket
object. So I am thinking we could just have the peer_address
as unique_ptr. It will convey the right ownership semantics but will look odd. WDYT?
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.
If this is a per-packet UdpData struct, should it use a shared pointer address from the socket?
I think the common case for QUIC-as-a-large-scale-server (or DNS too) is you're going to have a listener on 0.0.0.0:whatever_port which gets packets for a bunch of addresses. Imagine we've got a quic listener on 0.0.0.0, which gets a packet for local_address 1.2.3.4 We stick 1.2.3.4 in local_address based on the UDP message headers, hand the local_address up the stack, some other object snags a shared pointer assuming that's the local address for the connection. Meanwhile another packet comes in from 6.7.8.9. We could create a new shared pointer for each packet for the server case, but I think we're better off perf-optimizing for the common case, having an impl (not even an unique pointer) in the per-packet data.
That said you can totally TODO this and we can revisit later :-)
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.
Wanted to clarify that I was talking about local_address
that is from the listening socket. peer_address
could be unique for each packet as its derived from the UDP packet. I assume you mean the same but just wanted to be clear :)
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 have updated comments based on ☝️
include/envoy/network/listener.h
Outdated
* @param error_code ErrorCode for the error event. | ||
* @param errno System error number. | ||
*/ | ||
virtual void onError(const ErrorCode& err_code, int err_no) PURE; |
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.
super nitty, but can you use full variable names?
error_code error_number etc.?
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 there's still a few of these outstanding. Mind fixing up?
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 fixed them (latest commits) but looking at your comment again, I missed fixing err_no
as you suggested. Will fix that.
include/envoy/event/dispatcher.h
Outdated
* @param cb supplies the udp listener callbacks to invoke for listener events. | ||
* @return Network::ListenerPtr a new listener that is owned by the caller. | ||
*/ | ||
virtual Network::ListenerPtr createDatagramListener(Network::Socket& socket, |
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 was about to ask that we be consistent with Udp vs Datagram when I realized you were totally doing this right per mpw@'s advice.
I think when we get to docs it's worth doccing up that this is meant to be generic (potentially extending to datagrams over sockets) where the listener is for UdpSockets for others who have the same question :-P
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 I take back my comment (sorry the the churn :-} ): since everything else in the PR refers to "Udp", it seems a little out of place and inconsistent to use "Datagram" here, better to go with "Udp" which you had originally.
/** | ||
* Tests UDP listener for actual destination and data. | ||
*/ | ||
TEST_P(ListenerImplTest, UseActualDstUdp) { |
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.
now that we have udp_listener_impl.* files, we should probably move shared test code to a common utility class and put these tests in /test/common/network/udp_listener_impl_test, yeah?
@alyssawilk PR is ready for another review. PTAL. |
@mattklein123 @alyssawilk ping |
Oh sorry, missed this yesterday. I'm out this morning but I'll try to do a pass this afternoon and sorry for the delay |
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 we've got all my concerns TODOd other than that one naming nit. @mattklein123 / @mpwarres anything else you want to land here or should we launch/land and iterate?
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.
Looks great, from my perspective! Since this is packet-level, we can layer the QuicListener on top of this.
include/envoy/event/dispatcher.h
Outdated
* @param cb supplies the udp listener callbacks to invoke for listener events. | ||
* @return Network::ListenerPtr a new listener that is owned by the caller. | ||
*/ | ||
virtual Network::ListenerPtr createDatagramListener(Network::Socket& socket, |
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 I take back my comment (sorry the the churn :-} ): since everything else in the PR refers to "Udp", it seems a little out of place and inconsistent to use "Datagram" here, better to go with "Udp" which you had originally.
* TODO(conqerAtapple): Maybe this belongs inside the UdpListenerCallbacks | ||
* class. | ||
*/ | ||
struct UdpData { |
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.
optional naming suggestion (feel free to disregard): UdpPacket
include/envoy/network/listener.h
Outdated
*/ | ||
class UdpListenerCallbacks { | ||
public: | ||
enum class ErrorCode { SYSCALL_ERROR, UNKNOWN_ERROR }; |
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.
nit: I think Envoy uses CamelCase for enum value names
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
- Removed bind_to_port from UdpListener ctor. - Spellchecks and comments - Added EV_WRITE flag for udp listener Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
@mattklein123 Thanks for review. I have addressed all comments , except the FileEvent one as I am not very clear on how the enable/disable functionality would work. |
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
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.
LGTM with small comment (though I think you have a CI issue)
/wait
include/envoy/event/dispatcher.h
Outdated
@@ -90,7 +90,7 @@ class Dispatcher { | |||
* initially listen on. | |||
*/ | |||
virtual FileEventPtr createFileEvent(int fd, FileReadyCb cb, FileTriggerType trigger, | |||
uint32_t events) PURE; | |||
uint32_t events) const PURE; |
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.
We are somewhat splitting hairs here, but IMO this is not a const operation on the dispatcher, it does modify its state. Instead of changing this to a const method can you pass a non-const Dispatcher to where you need it? This is what is done elsewhere.
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
@mattklein123 I have addressed all comments now. I think coverage tests are failing because of memory issues. |
/retest |
🔨 rebuilding |
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.
This is awesome. LGTM modulo a few remaining const reverts. Thank you!
/wait
@@ -30,7 +30,7 @@ class DispatcherImpl : Logger::Loggable<Logger::Id::main>, public Dispatcher { | |||
/** | |||
* @return event_base& the libevent base. | |||
*/ | |||
event_base& base() { return *base_; } | |||
event_base& base() const { return *base_; } |
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.
Can you revert this const change also and a couple of the other ones you added?
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 will remove them but I think they should be const :)
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com>
@mattklein123 Thanks again for the reviews. I think all reviews are addressed now. |
@mattklein123 The |
@conqerAtapple we are working on the CI issues, in the meantime you can rerun failed tests yourself, like so: /retest |
🔨 rebuilding |
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.
Awesome!!
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com> Signed-off-by: Jojy George Varghese <jojy.varghese@gmail.com>
Signed-off-by: Jojy G Varghese <jojy_varghese@apple.com> Signed-off-by: Fred Douglas <fredlas@google.com>
Signed-off-by: Jojy G Varghese jojy_varghese@apple.com
For an explanation of how to fill out the fields, please see the relevant section
in PULL_REQUESTS.md
Description: Base layer for UDP proxying. UDP listener provides a
Buffer
interface to the upper layers, which in turn can add features/services like filters on top.Risk Level: Medium
Testing: Unit testing
Docs Changes: n/a
Release Notes: n/a
[Optional Fixes #Issue]
[Optional Deprecated:]