network: add DownstreamTransportSocketConfigFactory and registry#2437
network: add DownstreamTransportSocketConfigFactory and registry#2437alyssawilk merged 23 commits intoenvoyproxy:masterfrom
Conversation
Signed-off-by: Lizan Zhou <zlizan@google.com>
|
Will add changes to listeners after #2346, PTAL on the interface @mattklein123 @alyssawilk cc/ @PiotrSikora |
alyssawilk
left a comment
There was a problem hiding this comment.
Looks good - only a few minor nits. Hurrah for (bidirectional) pluggable crypto!
| }; | ||
|
|
||
| /** | ||
| * Implemented by each transport socket and registered via class RegisterFactory for upstream |
There was a problem hiding this comment.
Do we have a requirement that each transport socket needs both ends or should this be "implemented by each transport socket which does upstream connections"?
GFE has some things it speaks upstream and not downstream. With Envoy I have a hard time figuring out how we'd do testing without doing both so it's quite likely this comment should stand, maybe with an additional comment somewhere that it's required we always do both.
There was a problem hiding this comment.
No such requirement. Though I expect most implementations will have both upstream and downstream, nothing blocks an implementation with upstream only or downstream only, the interfaces and configuration support that. I will update the comments.
Tests could be done with external process, in some cases it could be done with existing other implementations, e.g. a transport socket is using other TLS implementation than BoringSSL.
| * Create a particular downstream transport socket factory implementation. | ||
| * TODO(lizan): Revisit the interface when TLS sniffing and filter chain match are implemented. | ||
| * @param listener_name const std::string& the name of the listener. | ||
| * @param server_names const std::vector<std::string>& the names of the server. |
There was a problem hiding this comment.
Mind adding a bit more detail here?
I assumed it was for SNI, then didn't know how SNI worked if you have a vector of server names. I was going to dig through code but I think our API comments should have enough data us non-crypto folk can puzzle it out. If it's blatantly obvious to crypto folk that may be enough =P
| * TODO(lizan): Revisit the interface when TLS sniffing and filter chain match are implemented. | ||
| * @param listener_name const std::string& the name of the listener. | ||
| * @param server_names const std::vector<std::string>& the names of the server. | ||
| * @param skip_ssl_context_update bool indicates whether the ssl context update should be skipped. |
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
6db3bac to
1abb513
Compare
Signed-off-by: Lizan Zhou <zlizan@google.com>
|
@alyssawilk @zuercher This is ready to be reviewed, PTAL. |
mattklein123
left a comment
There was a problem hiding this comment.
LGTM, some random small comments. Thanks!
| Ssl::Context* ssl_ctx) PURE; | ||
| virtual Network::ConnectionPtr | ||
| createServerConnection(Network::ConnectionSocketPtr&& socket, | ||
| Network::TransportSocketPtr&& transport_socket) PURE; |
| }; | ||
|
|
||
| /** | ||
| * Implemented by each transport socket which does downstream connection. Registered via class |
There was a problem hiding this comment.
nit: "used for downstream connections."
| }; | ||
|
|
||
| /** | ||
| * Implemented by each transport socket which does upstream connection. Registered via class |
There was a problem hiding this comment.
nit: "used for upstream connections."
source/common/ssl/ssl_socket.h
Outdated
| bool implementsSecureTransport() const override; | ||
|
|
||
| private: | ||
| ServerContextPtr ssl_ctx_; |
| } | ||
|
|
||
| void ConnectionHandlerImpl::ActiveListener::newConnection(Network::ConnectionSocketPtr&& socket) { | ||
| auto ts = config_.transportSocketFactory().createTransportSocket(); |
| } | ||
|
|
||
| ASSERT(!transport_socket_factories_.empty()); | ||
| ASSERT(transport_socket_factories_[0]); |
| Server::Configuration::DownstreamTransportSocketConfigFactory>(transport_socket.name()); | ||
| ProtobufTypes::MessagePtr message = | ||
| Config::Utility::translateToFactoryConfig(transport_socket, config_factory); | ||
| transport_socket_factories_.emplace_back(config_factory.createTransportSocketFactory( |
There was a problem hiding this comment.
Given that right now we effectively only support a single filter chain, I would recommend not using a vector here and just storing a single filter chain. The check at the end verifies that all filter chains are the same if they are implemented. All of this is going to have to get refactored when we do real matching. I would also add some TODO comments about the coming refactoring.
There was a problem hiding this comment.
We do support multiple filter chain, only with same filters, to support SNI. There are tests here:
https://github.com/envoyproxy/envoy/blob/master/test/server/listener_manager_impl_test.cc#L842
Since TransportSocketFactory replaces ServerContext here, it has to be vector.
There was a problem hiding this comment.
If you always return the 0th element of the vector, what is the point of the vector?
There was a problem hiding this comment.
Inside the SslServerContext, it switches the the context to others based on ClientHello here, unless skip_context_update is true. So now the default is being used until SslServerContext process client hello, and then switch the context after. Since SslContextManager doesn't own the SslServerContexts, the transport socket factories owns them here.
This behavior should be updated once SNI based filter chain match is implemented correctly, right @PiotrSikora?
There was a problem hiding this comment.
Ohh. OK I see. Now that factory holds context, you need to store them all. Hmm, yeah this is pretty hacky/ugly but I get why you did it until filter chain matching is implemented. Can you add a bunch of comments? This is really unclear from reading. Thank you.
test/test_common/network_utility.h
Outdated
| Address::SocketType type); | ||
|
|
||
| /** | ||
| * Create a transport socket for testing purpse. |
There was a problem hiding this comment.
typo: "purpse" same below. Also should be "testing purposes"
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
test/integration/fake_upstream.cc
Outdated
| server_initialized_.waitReady(); | ||
|
|
||
| if (ssl_ctx_) { | ||
| throw EnvoyException("debug"); |
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
Signed-off-by: Lizan Zhou <zlizan@google.com>
|
|
||
| // Each transport socket factory owns one SslServerContext, we need to store them all in a | ||
| // vector since Ssl::ContextManager doesn't owns SslServerContext. While | ||
| // transportSocketFacotry() always return the first element of transport_socket_factories_, |
There was a problem hiding this comment.
nit: "transportSocketFactory()" and "returns the first element"
| // Each transport socket factory owns one SslServerContext, we need to store them all in a | ||
| // vector since Ssl::ContextManager doesn't owns SslServerContext. While | ||
| // transportSocketFacotry() always return the first element of transport_socket_factories_, | ||
| // other transport socket facotires are needed when the default Ssl::ServerContext updates |
include/envoy/network/listener.h
Outdated
|
|
||
| /** | ||
| * @return Ssl::ServerContext* the default SSL context. | ||
| * @return TransportSocketFacotry& the transport socket factory. |
| }; | ||
|
|
||
| /** | ||
| * Implemented by each transport socket which used for upstream connections. Registered via class |
There was a problem hiding this comment.
nit: rm which (repeated below for DownstreamTransportSocketConfigFactory)
|
Hmm, I ran coverage locally and it says coverage is 98.0%, and I double checked every file I changed that didn't lose coverage. Not sure why CircleCI complain it is 97.9%... The artifacts wasn't uploaded. |
|
@lizan sorry. You can either find some coverage to add, or wait until we do some coverage fixes. |
zuercher
left a comment
There was a problem hiding this comment.
one last question, but otherwise LGTM
| } | ||
|
|
||
| ASSERT(!transport_socket_factories_.empty()); | ||
| ASSERT(transport_socket_factories_[0] != nullptr); |
There was a problem hiding this comment.
Question: should this be asserting that the just-added pointer is not null?
alyssawilk
left a comment
There was a problem hiding this comment.
One more nit on my end as well
| has_stk++; | ||
|
|
||
| auto transport_socket = filter_chain.transport_socket(); | ||
| if (!filter_chain.has_transport_socket()) { |
There was a problem hiding this comment.
Snagging transport_socket before checking has_transport_socket is weird and could definitely use some commenting. Would it instead make more sense to have string name from transport_socket and if name were empty to override it based on has_tls_config?
There was a problem hiding this comment.
Added a comment (also to upstream_impl). Checking the name does same thing. proto here is validated, so the name won't be empty if filter chain has transport socket.
mattklein123
left a comment
There was a problem hiding this comment.
small nit, LGTM other than remaining @zuercher and @alyssawilk comments.
| Config::Utility::translateToFactoryConfig(transport_socket, config_factory); | ||
|
|
||
| // Each transport socket factory owns one SslServerContext, we need to store them all in a | ||
| // vector since Ssl::ContextManager doesn't owns SslServerContext. While |
There was a problem hiding this comment.
typo: "doesn't owns". While you are here please reflow comment.
Signed-off-by: Lizan Zhou <zlizan@google.com>
mattklein123
left a comment
There was a problem hiding this comment.
@lizan small nit since you have to do a master merge anyway. Thanks!
| ProtobufTypes::MessagePtr message = | ||
| Config::Utility::translateToFactoryConfig(transport_socket, config_factory); | ||
|
|
||
| // Each transport socket factory owns one SslServerContext, we need to store them all in a |
There was a problem hiding this comment.
nit: Can you please reflow this comment out to 100 cols? I think the sentences got broken up when the formatter kicked in.
Signed-off-by: Lizan Zhou <zlizan@google.com>
alyssawilk
left a comment
There was a problem hiding this comment.
@mattklein123 @zuercher any final comments?
We were on a very old release. This is also going to be needed to update to the latest bazel 6.x release which we need to do to update Envoy. Signed-off-by: JP Simard <jp@jpsim.com>
We were on a very old release. This is also going to be needed to update to the latest bazel 6.x release which we need to do to update Envoy. Signed-off-by: JP Simard <jp@jpsim.com>
Signed-off-by: Lizan Zhou zlizan@google.com
Description:
Add DownstreamTransportSocketConfigFactory and its implementations.
Risk Level: Medium
Testing:
unit test, integration tests
Docs Changes:
Release Notes:
Fixes #1840.