Skip to content
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

ProxyProtocolUpstream Transport socket should support connection pool setting #37126

Closed
lambdai opened this issue Nov 13, 2024 · 6 comments · Fixed by #37177
Closed

ProxyProtocolUpstream Transport socket should support connection pool setting #37126

lambdai opened this issue Nov 13, 2024 · 6 comments · Fixed by #37177
Labels
area/proxy_proto enhancement Feature requests. Not bugs or questions.

Comments

@lambdai
Copy link
Contributor

lambdai commented Nov 13, 2024

Title: ProxyProtocolUpstream Transport socket should support connection pool setting
Description:
Currently ProxyProtocolUpstreamTransport hard coded connection pool key as "src_address" + "dst_address" and require both address not null.

However, per Proxy protocol v2, UNSPEC address is supported.
This limitation blocks from using proxy protocol carrying arbitrary per connection metadata via proxy protocol TLV

Problem 1:
Although we can populate src address and dst address by authentic address, the fact that addresses participating connection pool hashkey would create unnecessary connection pool.
The best approach is to allow UNSPEC address that does not take address into connection pool.

Problem 2:
TLV is not involved in connection pool.
That means a connection created with metadata "foo" share the same connection pool with connection annotated metadata "bar".
That's a hard failure in some use cases.

Proposal


+++ b/api/envoy/extensions/transport_sockets/proxy_protocol/v3/upstream_proxy_protocol.proto
@@ -24,4 +24,14 @@ message ProxyProtocolUpstreamTransport {
 
   // The underlying transport socket being wrapped.
   config.core.v3.TransportSocket transport_socket = 2 [(validate.rules).message = {required: true}];
+
+  // Control the connection pool settings for PROXY protocol socket.
+  ConnectionPoolSetting connection_pool_settings = 3;
+}
+
+// ConnectionPool settings for PROXY protocol socket.
+
+message ConnectionPoolSetting {
+  bool allow_unspecified_address = 1;
+  bool tlv_as_pool_key = 2;
 }

A zero initialized ConnectionPoolSetting should maintain the current behavior.

Let me know if the API make sense.

I have the implementation running well at my side. If anyone is feeling useful, l can create the PR for the API and the follow up implementation.

Thank you!

Ref
proxy protocol: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

@lambdai lambdai added enhancement Feature requests. Not bugs or questions. triage Issue requires triage labels Nov 13, 2024
@yanavlasov
Copy link
Contributor

Which TLV will be used as key? There can be multiple TLVs in the header.

@yanavlasov yanavlasov added area/proxy_proto and removed triage Issue requires triage labels Nov 13, 2024
@lambdai
Copy link
Contributor Author

lambdai commented Nov 13, 2024

I think the short answer is all the TLVs.
I see ProxyProtocol transport sockets could select paritial downstream TLVs,
we can always extend ConnectionPoolSetting with initial hash all the TLVs

@lambdai
Copy link
Contributor Author

lambdai commented Nov 13, 2024

Let me know if you have cases that selecting subset of TLVs
I am +1 with that configuration.
At my side, I am using INCLUDE_ALL to relay all the downstream TLVs because I had the control of the downstream TLVs.
I didn't propose much more than I requested but I am happy to contribute and maintain more use cases

@lambdai
Copy link
Contributor Author

lambdai commented Nov 14, 2024

Actually, the best way to decribe the feature 1 is to allow LOCAL address along with TLVs.

Currently TLVs is not attached to the PP header if the address is local.

if (!options_ || !options_->proxyProtocolOptions().has_value()) {
Common::ProxyProtocol::generateV2LocalHeader(header_buffer_);
} else {
const auto options = options_->proxyProtocolOptions().value();
if (!Common::ProxyProtocol::generateV2Header(options, header_buffer_, pass_all_tlvs_,
pass_through_tlvs_)) {
// There is a warn log in generateV2Header method.
stats_.v2_tlvs_exceed_max_length_.inc();
}
ENVOY_LOG(trace, "generated proxy protocol v2 header, length: {}, buffer: {}",
header_buffer_.length(), toHex(header_buffer_));
}

@yanavlasov
Copy link
Contributor

I do not have specific use cases, just asking clarifying questions. The feature looks ok to me.

@lambdai
Copy link
Contributor Author

lambdai commented Nov 15, 2024

Thank you @yanavlasov
I am creating the PR

lambdai added a commit to lambdai/envoy-dai that referenced this issue Nov 15, 2024
Context: envoyproxy#37126

ConnectionPoolSettings in proxy_protocol upstream socket customizes
the behavior of connection pool.

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
lambdai added a commit to lambdai/envoy-dai that referenced this issue Nov 15, 2024
Context: envoyproxy#37126

ConnectionPoolSettings in proxy_protocol upstream socket customizes
the behavior of connection pool.

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/proxy_proto enhancement Feature requests. Not bugs or questions.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants