quiche: modify some envoy quic implementation for code sharing#8349
quiche: modify some envoy quic implementation for code sharing#8349mattklein123 merged 39 commits intoenvoyproxy:masterfrom
Conversation
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
|
/assign @alyssawilk |
Signed-off-by: Dan Zhang <danzh@google.com>
mattklein123
left a comment
There was a problem hiding this comment.
Thanks, flushing out a few more comments.
/wait
source/extensions/quic_listeners/quiche/quic_filter_manager_connection_impl.cc
Show resolved
Hide resolved
|
|
||
| void QuicFilterManagerConnectionImpl::addBytesSentCallback( | ||
| Network::Connection::BytesSentCb /*cb*/) { | ||
| // TODO(danzh): implement to support proxy. This interface is only called from |
There was a problem hiding this comment.
I would prefer that we either crash hard if things should not happen, or actually implement stuff. Since QUIC is not production ready yet, can we just make everything that shouldn't happen NOT_IMPLEMENTED for now? Same elsewhere?
| } | ||
|
|
||
| std::chrono::milliseconds QuicFilterManagerConnectionImpl::delayedCloseTimeout() const { | ||
| // Not called outside of Network::ConnectionImpl. Maybe remove this interface |
There was a problem hiding this comment.
That's fine, please make this an actual TODO.
| const Network::ConnectionSocket::OptionsSharedPtr& | ||
| QuicFilterManagerConnectionImpl::socketOptions() const { | ||
| ENVOY_CONN_LOG( | ||
| error, |
There was a problem hiding this comment.
Per elsewhere, let's please not log at error, etc. Let's either implement or NOT_IMPLEMENTED everywhere in this file.
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
mattklein123
left a comment
There was a problem hiding this comment.
Sorry to keep going back and forth on this but I would still like to tighten up the interfaces a bit more in terms of the things we need to implement, the things that can't happen, etc. Thank you!
/wait
| } | ||
|
|
||
| void QuicFilterManagerConnectionImpl::enableHalfClose(bool enabled) { | ||
| ASSERT(!enabled, "Quic connection doesn't support half close."); |
There was a problem hiding this comment.
Does this get called? Can this be NOT_IMPLEMENTED?
There was a problem hiding this comment.
This should only be called with enable == true. This is the implementation desired.
There was a problem hiding this comment.
I would make this a RELEASE_ASSERT then just to check our assumption.
| // TODO(danzh): add interface to quic for connection level buffer throttling. | ||
| // Currently read buffer is capped by connection level flow control. And | ||
| // write buffer is not capped. | ||
| ENVOY_CONN_LOG(error, "Quic manages its own buffer currently.", *this); |
There was a problem hiding this comment.
Does this get called? Can this be NOT_IMPLEMENTED? If it does get called can we just have this be an empty function with the TODO?
There was a problem hiding this comment.
According to my next PR, this method shouldn't be called. I changed it to NOT_REACHED here.
| void QuicFilterManagerConnectionImpl::close(Network::ConnectionCloseType type) { | ||
| if (type != Network::ConnectionCloseType::NoFlush) { | ||
| // TODO(danzh): Implement FlushWrite and FlushWriteAndDelay mode. | ||
| ENVOY_CONN_LOG(error, "Flush write is not implemented for QUIC.", *this); |
There was a problem hiding this comment.
Same here? Basically can we remove the error logs and just crash or have a TODO?
There was a problem hiding this comment.
We don't want to crash, as it's called by HCM with other CloseType. Removed the error log. The empty if block looks weird though...
| } | ||
|
|
||
| Ssl::ConnectionInfoConstSharedPtr QuicFilterManagerConnectionImpl::ssl() const { | ||
| // TODO(danzh): construct Ssl::ConnectionInfo from crypto stream |
There was a problem hiding this comment.
Per the comments above can we just remove the error logs? If something will be implemented later I think it's fine to just leave a TODO?
Essentially what I would like to see is:
- No error logs in this type of code
- NOT_IMPLEMENTED if it can't happen with a comment why.
- Or a default implementation with a TODO to implement the real thing.
| void setDelayedCloseTimeout(std::chrono::milliseconds timeout) override; | ||
| std::chrono::milliseconds delayedCloseTimeout() const override; | ||
| void readDisable(bool disable) override { | ||
| ASSERT(!disable, "Quic connection should be able to read through out its life time."); |
There was a problem hiding this comment.
For these normal asserts, do these functions get called? Or should they not get called at all? Same elsewhere.
There was a problem hiding this comment.
It shouldn't be called for multiplexing case according to my reading of the HCM implementation. I might be wrong, but NOT_REACHED for now.
Signed-off-by: Dan Zhang <danzh@google.com>
danzh2010
left a comment
There was a problem hiding this comment.
I changed error log and ASSERT to NOT_REACHED in most of the places according to my current understanding. But I'm not sure how meaningful it would be to tighten the interface at this point, considering they might get reverted in integration tests if it turns out those places are reachable.
| } | ||
|
|
||
| void QuicFilterManagerConnectionImpl::enableHalfClose(bool enabled) { | ||
| ASSERT(!enabled, "Quic connection doesn't support half close."); |
There was a problem hiding this comment.
This should only be called with enable == true. This is the implementation desired.
| void QuicFilterManagerConnectionImpl::close(Network::ConnectionCloseType type) { | ||
| if (type != Network::ConnectionCloseType::NoFlush) { | ||
| // TODO(danzh): Implement FlushWrite and FlushWriteAndDelay mode. | ||
| ENVOY_CONN_LOG(error, "Flush write is not implemented for QUIC.", *this); |
There was a problem hiding this comment.
We don't want to crash, as it's called by HCM with other CloseType. Removed the error log. The empty if block looks weird though...
| // TODO(danzh): add interface to quic for connection level buffer throttling. | ||
| // Currently read buffer is capped by connection level flow control. And | ||
| // write buffer is not capped. | ||
| ENVOY_CONN_LOG(error, "Quic manages its own buffer currently.", *this); |
There was a problem hiding this comment.
According to my next PR, this method shouldn't be called. I changed it to NOT_REACHED here.
| void setDelayedCloseTimeout(std::chrono::milliseconds timeout) override; | ||
| std::chrono::milliseconds delayedCloseTimeout() const override; | ||
| void readDisable(bool disable) override { | ||
| ASSERT(!disable, "Quic connection should be able to read through out its life time."); |
There was a problem hiding this comment.
It shouldn't be called for multiplexing case according to my reading of the HCM implementation. I might be wrong, but NOT_REACHED for now.
|
/retest |
|
🤷♀️ nothing to rebuild. |
|
/azp envoy-linux(bazel release) |
|
Command 'envoy-linux(bazel' is not supported by Azure Pipelines. Supported commands
See additional documentation. |
mattklein123
left a comment
There was a problem hiding this comment.
Thanks, almost there. Just a few more small comments. Also, can you please make it consistent between NOT_REACHED/NOT_IMPLEMENTED, or better, use NOT_REACHED when it for real should never happen and NOT_IMPLEMENTED/RELEASE_ASSERT when we need to implement it later as we add tests? Thank you!
/wait
| } | ||
|
|
||
| void QuicFilterManagerConnectionImpl::enableHalfClose(bool enabled) { | ||
| ASSERT(!enabled, "Quic connection doesn't support half close."); |
There was a problem hiding this comment.
I would make this a RELEASE_ASSERT then just to check our assumption.
| } | ||
|
|
||
| Ssl::ConnectionInfoConstSharedPtr QuicFilterManagerConnectionImpl::ssl() const { | ||
| // TODO(danzh): construct Ssl::ConnectionInfo from crypto stream |
There was a problem hiding this comment.
Sorry I'm not following what is going on here. Presumably this does need to be implemented eventually but if you NOT_IMPLEMENTED this now it crashes? I would remove the error log and just track with a TODO.
| const Network::Address::InstanceConstSharedPtr& localAddress() const override; | ||
| absl::optional<Network::Connection::UnixDomainSocketPeerCredentials> | ||
| unixSocketPeerCredentials() const override { | ||
| ASSERT(false, "Unix domain socket is not supported."); |
| NOT_REACHED_GCOVR_EXCL_LINE; | ||
| } | ||
| bool localAddressRestored() const override { | ||
| // SO_ORIGINAL_DST not supported by QUIC. |
There was a problem hiding this comment.
I'm pretty sure this will never get called. NOT_IMPLEMENTED?
| // them. | ||
| std::list<Network::ConnectionCallbacks*> network_connection_callbacks_; | ||
| std::string transport_failure_reason_; | ||
| uint64_t id_; |
Signed-off-by: Dan Zhang <danzh@google.com>
mattklein123
left a comment
There was a problem hiding this comment.
Nice, let's ship and iterate!
…proxy#8349) Signed-off-by: Dan Zhang <danzh@google.com>
Refactor EnvoyQuicServerSession to inherit from QuicFilterManagerConnectionImpl which implements most of the Network::FilterManagerConnection interface. This base class can be shared with client side implementation. Also split out some server side logic from EnvoyQuicConnection into EnvoyQuicServerConnection. So that EnvoyQuicConnection can be shared with client connection implementation
Modify EnvoyQuicPacketWriter to wrap a Socket& rather than Listener& because client side doesn't have listener. Extract socket write code from UdpListenerImpl::send() to Network::Utility so that writer can use same code for writing.
Alike wise, move some socket read logic in UdpListenerImpl::handleReadCallback() into Utility for code sharing with client connection later.
Made a slight change in EnvoyQuicServerSession to raiseEvent with type
Connectedwhen handshake is done.Convert some ASSERT of not implemented feature to NOT_IMPLEMENT or NOT_REACHED.
Risk Level: low, refactor to unused code
Testing: existing tests
Part of #2557