network: add transport socket interface#2116
network: add transport socket interface#2116mattklein123 merged 18 commits intoenvoyproxy:masterfrom
Conversation
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
|
This is ready to review, PTAL @mattklein123 @htuch. cc @PiotrSikora |
alyssawilk
left a comment
There was a problem hiding this comment.
This looks great overall - the SSL logic came out really cleanly and I think the read/write semantics work better with a "socket" interface than a "crypto" interface.
I have a bunch of style nits but no major structural changes. Let's get this cleaned up and in! :-)
| virtual ~TransportSocketCallbacks() {} | ||
|
|
||
| /** | ||
| * @return the file descriptor associated with the connection. |
There was a problem hiding this comment.
Also mild preference for Connection or Network::Connection where we're actually talking about a Network::Connection
| virtual Connection& connection() PURE; | ||
|
|
||
| /** | ||
| * @return return whether the read buffer should be drained |
There was a problem hiding this comment.
A bit more context on this would be nice now that it has moved away from where the code is using it.
You could maybe mention the example that this can be used to enforce yielding for configured read limits or some such
| * Raise a connection event to the connection. | ||
| * @param event supplies the connection event | ||
| */ | ||
| virtual void raiseEvent(ConnectionEvent event) PURE; |
There was a problem hiding this comment.
If this is done on the connection, I'd lean towards exposing it there rather than having a wrapper function here. I guess since this is not accessible to all entities that have a connection it could be useful to scope it? Your call.
Either way you could doc up a bit more what this does. It basically fakes the connection getting the specific event from the kernel, no?
| virtual ~TransportSocket() {} | ||
|
|
||
| /** | ||
| * Called by connection once to intiialize the transport socket callbacks that the transport |
|
|
||
| /** | ||
| * Closes the transport socket. | ||
| * @param event suuplies the connection event that closing the socket. |
| Address::InstanceConstSharedPtr remote_address, | ||
| Address::InstanceConstSharedPtr local_address, | ||
| Address::InstanceConstSharedPtr bind_to_address, | ||
| TransportSocketPtr transport_socket, bool using_original_dst, bool connected); |
There was a problem hiding this comment.
TransportSocketPtr&& transport_socket for ownership clarity?
| void setTransportSocketCallbacks(TransportSocketCallbacks& callbacks) override; | ||
| std::string protocol() const override; | ||
| bool canFlushClose() override { return true; } | ||
| void closeSocket(Network::ConnectionEvent) override {} |
There was a problem hiding this comment.
Doesn't this need to close the socket?
There was a problem hiding this comment.
No, the raw buffer socket doesn't have to do anything other than the one does in ConnectionImpl.
| ENVOY_CONN_LOG(debug, "connected", *this); | ||
| state_ &= ~InternalState::Connecting; | ||
| onConnected(); | ||
| transport_socket_->onConnected(); |
There was a problem hiding this comment.
This seems a little weird - the Network::Connection tells the socket it's connected, and then the socket calls raiseEvents back on the connection.
I suspect there's a good reason to pass through the socket but I'm missing it :-)
There was a problem hiding this comment.
The main purpose of this is for SSL handshake
- Connection calls TransportSocket::onConnected then transport socket starts the handshake.
- transport socket call raiseEvents when handshake is complete.
There was a problem hiding this comment.
Cool, that's a level of detail which might be worth documenting somewhere (the API file?) that onConnected is called on the transport when the underlying transport is connected, and raiseEvent(connected) is called when any transport-level handshakes are completed.
| ~ConnectionImpl(); | ||
|
|
||
| // Network::Connection | ||
| Ssl::Connection* ssl() override { return dynamic_cast<SslSocket*>(transport_socket_.get()); } |
There was a problem hiding this comment.
Hm. If ssl() is a weird function on the base connection class (which returns nullptr) what do you think of making it an additional weird function on the transport socket? It'd let us avoid the dynamic cast, and I think do away with the ConnectionImpl entirely (as we could create the base connection class with a new SslSocket explicitly, and the regular connection class would call the null-returning ssl() for the raw socket.
There was a problem hiding this comment.
Yes, I'm planning to remove the whole Ssl::ConnectionImpl at the end. The ssl() is kept here for compatibility with others, as it is used widely in filters, etc. That refactor will involve many classes, can be done in a separate PR.
There was a problem hiding this comment.
Cool, let's TODO that cleanup just so it's clear what the plan is. I'm fine with a follow-up to keep this clean and simple
| virtual void raiseEvent(ConnectionEvent event) PURE; | ||
| }; | ||
|
|
||
| class TransportSocket { |
There was a problem hiding this comment.
I think we could have a bit more detail. What is a transport socket vs a socket? We expect it's doing transformations on the data (TLS/LOAS) which might be worth calling out as part of the "transport" nature?
Signed-off-by: Lizan Zhou <zlizan@google.com>
alyssawilk
left a comment
There was a problem hiding this comment.
Sorry, just got out of a meeting so I don't have time for another full pass tonight. Looking better, here's what I had left so far!
|
|
||
| /** | ||
| * @return return whether the read buffer should be drained | ||
| * @return whether the read buffer should be drained. This is used to enforce yielding for |
There was a problem hiding this comment.
@return bool
still missing types on a few others as well
| virtual void raiseEvent(ConnectionEvent event) PURE; | ||
| }; | ||
|
|
||
| class TransportSocket { |
There was a problem hiding this comment.
I think we could have a bit more detail. What is a transport socket vs a socket? We expect it's doing transformations on the data (TLS/LOAS) which might be worth calling out as part of the "transport" nature?
| /** | ||
| * Closes the transport socket. | ||
| * @param event suuplies the connection event that closing the socket. | ||
| * @param event suuplies the connection event that is closing the socket. |
Signed-off-by: Lizan Zhou <zlizan@google.com>
|
@alyssawilk ping. |
|
@lizan @alyssawilk is out on Fridays. I will take a look at this also this weekend. |
mattklein123
left a comment
There was a problem hiding this comment.
At a high level this LGTM, other than my thinking out loud about FD, which I don't think we can do anything about easily right now.
@lizan I would prefer to hold this PR until we tag 1.5.0. So if possible can you just start working on your next PR on top of this one and we can get this merged later next week?
| }; | ||
|
|
||
| /** | ||
| * Callbacks used by transport socket instances to communicate with connection |
There was a problem hiding this comment.
nit: period end of sentence.
| /** | ||
| * @return int the file descriptor associated with the connection. | ||
| */ | ||
| virtual int fd() PURE; |
There was a problem hiding this comment.
Not all transport sockets are going to have a fd. Can this be removed from the interface somehow? (I haven't yet looked in detail at how the rest of the code is factored).
In now reading more of the PR, I guess this is due to the fact that fundamentally we are passing FDs around from listeners. I suppose at some point we may need to turn this into some type of generic handle but this is probably ok for now. Just thinking out loud.
There was a problem hiding this comment.
Yeah I thought we need some type of generic handle but it is not easy and out of scope of this PR. We can refactor when we have something other than FDs.
There was a problem hiding this comment.
I had the same concern but the SSL stack at least needs this.
We never found a good workaround in the GFE - just made -1 a permissible value which allows all sorts of bad feature creep :-(
Signed-off-by: Lizan Zhou <zlizan@google.com>
alyssawilk
left a comment
There was a problem hiding this comment.
@mattklein123 if we are waiting for 1.5 should this include release notes?
It's not a functional change, but it allows a feature we and others might care about so I assume it's worth doccing up.
Lizan, I'd suggest adding a few lines about the new API and what it allows to RAW_RELEASE_NOTES.md
| /** | ||
| * @return int the file descriptor associated with the connection. | ||
| */ | ||
| virtual int fd() PURE; |
There was a problem hiding this comment.
I had the same concern but the SSL stack at least needs this.
We never found a good workaround in the GFE - just made -1 a permissible value which allows all sorts of bad feature creep :-(
| virtual std::string protocol() const PURE; | ||
|
|
||
| /** | ||
| * @return bool whether the socket can be flush closed. |
There was a problem hiding this comment.
"can be flushed and closed" since I'm not sure flush closed is a thing :-)
I'm kind of bummed we can't infer this from Connected. It'd work for TLS since we always raiseEvent Connected() right after the handshake is complete, but it might cause problems for TCP, as the socket isn't flagged connected until it processes the initial event. Matt, think this is worth fixing?
There was a problem hiding this comment.
@lizan the question is for @mattklein123 but can you still update the comment in the interim?
sorry I meant I would like to wait until after 1.5 is tagged. Either today or tomorrow. We can merge this later in the week? (For 1.6 cycle). |
|
Oops nevermind re: my release notes comment, we were saying the same thing. @alyssawilk yeah if we are waiting for 1.6.0 we should add a comment to raw release notes. Thank you! |
|
Sure, let's merge this in 1.6 cycle, and I'll start the rest of work. Hopefully there will be no merge conflicts by then :) |
Signed-off-by: Lizan Zhou <zlizan@google.com>
alyssawilk
left a comment
There was a problem hiding this comment.
Thanks for adding release notes :-)
LGTM pending that one last comment nit.
Signed-off-by: Lizan Zhou <zlizan@google.com>
…to envoy logs. (envoyproxy#2116) * Added simple logging abstraction so mixer client logs can be relayed to envoy logs when running inside envoy, stderr when running standalone. * Log threshold guards that prevent needless serialization of logging arguments are now embedded in the log macros. * Format * Added do/while guards around logging statements.
Description: `TARGET_OS_MAC` is defined on iOS, but is not truth-y, so the previous checks were not sufficient. Risk Level: Low, re-enabling something that used to be enabled on iOS. Testing: Verified in our sample apps that WLAN/WWAN interfaces are properly logged when reachability changes. Docs Changes: Release Notes: [Optional Fixes #Issue] [Optional Deprecated:] Signed-off-by: JP Simard <jp@jpsim.com>
Description: `TARGET_OS_MAC` is defined on iOS, but is not truth-y, so the previous checks were not sufficient. Risk Level: Low, re-enabling something that used to be enabled on iOS. Testing: Verified in our sample apps that WLAN/WWAN interfaces are properly logged when reachability changes. Docs Changes: Release Notes: [Optional Fixes #Issue] [Optional Deprecated:] Signed-off-by: JP Simard <jp@jpsim.com>
network: add transport socket interface
Description:
Add transport socket interface and refactors out
RawBufferSocketfromNetwork::ConnectionImplandSslSocketfromSsl::ConnectionImpl.A step towards #1840, factory for register and instantiate transport sockets will be in next PRs.
API Changes:
envoyproxy/data-plane-api#218
Risk Level: Medium
Testing:
unit test and integration test.