Skip to content

tls: add functionality to override requested server name in the upstream cluster#4973

Merged
htuch merged 38 commits intoenvoyproxy:masterfrom
vadimeisenbergibm:override_server_name
Nov 21, 2018
Merged

tls: add functionality to override requested server name in the upstream cluster#4973
htuch merged 38 commits intoenvoyproxy:masterfrom
vadimeisenbergibm:override_server_name

Conversation

@vadimeisenbergibm
Copy link
Copy Markdown
Contributor

Description: add functionality to override requested server name in the upstream cluster
Risk Level: medium
Testing: unit tests
Docs Changes: yes
Release Notes: yes
Related to #4076

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
…luster

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
@vadimeisenbergibm
Copy link
Copy Markdown
Contributor Author

@lizan I have extracted the override server name functionality from the extension PR #4334. Could you please review it? Are the tests I wrote sufficient?

The test on mac fails for some reason, could you please rerun it?

@lizan lizan self-assigned this Nov 6, 2018
*/
virtual TransportSocketPtr createTransportSocket() const PURE;
virtual TransportSocketPtr
createTransportSocket(absl::optional<std::string> override_server_name) const PURE;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be const reference everywhere.

Thinking more, I think we would like some sort of TransportSocketOptions to passed into here, like an interface:

class TransportSocketOptions {
public:
  virtual ~TransportSocketOptions();
  virtual absl::optional<string> overrideServerName() const PURE;
  virtual void hashKey(std::vector<uint8_t>& key) const PURE;
}

typedef std::shared_ptr<TransportSocketOptions> TransportSocketOptionsSharedPtr;

and pass TransportSocketOptionsSharedPtr around. This will help when we want to have more than override_server_name, and you can put this into FilterState as something called UpstreamTransportSocketOption.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lizan OK, thank you for the feedback, let me implement it.

@lizan
Copy link
Copy Markdown
Member

lizan commented Nov 6, 2018

Thanks @vadimeisenbergibm for extracting this. The structure looks nice though I think it can be more future proof. I re-kicked mac CI as it seems unrelated.

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
class ContextImpl : public virtual Context {
public:
virtual bssl::UniquePtr<SSL> newSsl() const;
virtual bssl::UniquePtr<SSL> newSsl(absl::optional<std::string> override_server_name) const;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const ref for parameter

TimeSource& time_source);

bssl::UniquePtr<SSL> newSsl() const override;
bssl::UniquePtr<SSL> newSsl(absl::optional<std::string> override_server_name) const override;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const ref for parameter (everywhere)

class TransportSocketOptions {
public:
virtual ~TransportSocketOptions() {}
virtual absl::optional<std::string> overrideServerName() const PURE;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return a const reference for this.

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
lizan
lizan previously requested changes Nov 8, 2018
Copy link
Copy Markdown
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The transport socket part LGTM modulo test.

EXPECT_TRUE(transport_socket_options->overrideServerName().has_value());
EXPECT_EQ(transport_socket_options->overrideServerName().value(), "www.example.com");

(void)priority; // suppress unused warning
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just make the parameter unnamed. or UNREFERENCED_PARAMETER macro is for this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lizan It seems lambda requires the parameters to be named. I will use UNREFERENCED_PARAMETER.

Copy link
Copy Markdown
Member

@lizan lizan Nov 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, lambda with unnamed parameters appears many times in the code base.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I was probably confused by some other error before. Done.

@@ -0,0 +1,10 @@
#include "common/stream_info/forward_requested_server_name.h"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(cont from #4334 (comment))

I don't think this should be here and named like this. Name it "upstream_server_name" or "upstream_transport_socket_options" (if you put the class here).

The filter is not related directly to the TCP proxy. The filter specifies the intention that the SNI must be forwarded. Other filters, such as TCP proxy, can extract that information and forward the SNI.

The consumer of this is tcp_proxy, or you should make this into network namespace, as stream_info is for both L4/L7, while this is specific to transport socket / connection.

So there are three different names here:

  1. Forward Requested Server Name in the Stream Info, means that there is some requested server name, not necessarrily SNI, maybe requested server name from some other protocol, that must be forwarded to the upstream, not necessarily by tcp_proxy.

"forward" (i.e. propagating downstream server name to upstream) is decided by the filter setting this, this filter state doesn't imply that. Another filter can set this to arbitrary value.

The filter is not related directly to the TCP proxy. The filter specifies the intention that the SNI must be forwarded. Other filters, such as TCP proxy, can extract that information and forward the SNI.

  1. Override Server Name in tcp_proxy, cluster manager etc. it means that the server name of the upstream cluster must be overridden by that value. It does not specify that it is SNI and does not specify where this server name comes from.

Yes, this is right, now it is a struct named TransportSocketOptions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lizan So, making that struct into the network namespace, and calling it upstream_server_name will be OK?

Should I make this upstream_transport_socket_options to hold TransportSocketOptions? My intention was to decouple Filter state objects from TransportSocketOptions. We can have different Filter State objects holding basic types as strings and different filters like tcp_proxy can compose TransportSocketOptions differently, according to their logic.

I am OK with both solutions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think upstream_server_name should be OK, then we can keep every filter state small.

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
…rk/upstream_server_name

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
@vadimeisenbergibm
Copy link
Copy Markdown
Contributor Author

@lizan I have implemented your comments, the tests pass.

Copy link
Copy Markdown
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks for working on this.

@htuch @zuercher PTAL?

class TransportSocketOptions {
public:
virtual ~TransportSocketOptions() {}
virtual const absl::optional<std::string>& overrideServerName() const PURE;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment for each method

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to serverNameOverride or just simply serverName; otherwise, it sounds like a mutating method vs. an option.

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
required for clang_tidy

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo remaining comments.


absl::string_view UpstreamServerName::key() {
// Construct On First Use Idiom: https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
static const char* cstring_key = "envoy.network.upstream_server_name";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use the existing macro for this,

CONSTRUCT_ON_FIRST_USE(std::string, build_scm_revision);
, here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in b31e6f6

template <typename T> void pushScalarToByteVector(T val, std::vector<uint8_t>& bytes) {
uint8_t* byte_ptr = reinterpret_cast<uint8_t*>(&val);
for (unsigned int byte_index = 0; byte_index < sizeof val; byte_index++) {
bytes.push_back(*byte_ptr);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: collapse two lines to bytes.push_back(*byte_ptr++);

Copy link
Copy Markdown
Contributor Author

@vadimeisenbergibm vadimeisenbergibm Nov 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in d84b467

namespace Envoy {
template <typename T> void pushScalarToByteVector(T val, std::vector<uint8_t>& bytes) {
uint8_t* byte_ptr = reinterpret_cast<uint8_t*>(&val);
for (unsigned int byte_index = 0; byte_index < sizeof val; byte_index++) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Envoy style prefers fixed type sizes, e.g. uint32_t here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in d6583b9

public:
virtual bssl::UniquePtr<SSL> newSsl() const;
virtual bssl::UniquePtr<SSL>
newSsl(const absl::optional<std::string>& override_server_name) const;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: making this argument an absl::optional<absl::string_view> (without reference) might be strictly more flexible.

Copy link
Copy Markdown
Contributor Author

@vadimeisenbergibm vadimeisenbergibm Nov 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 505cce2

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
This reverts commit 6c9128d.

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
@vadimeisenbergibm
Copy link
Copy Markdown
Contributor Author

@htuch I have applied your comments, all the tests pass.

Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, one last test fix and we can merge, thanks.

Network::MockActiveDnsQuery active_dns_query;
EXPECT_CALL(*dns_resolver, resolve(_, _, _))
.WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query)));
create(parseBootstrapFromJson(json));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you switch this to v2 YAML config? v1 is deprecated and will be deleted real soon now.

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Appreciate your patience while working through the final nits, I think this PR looks great.

@vadimeisenbergibm
Copy link
Copy Markdown
Contributor Author

@htuch My pleasure! Thank you for your patient reviewing.

@vadimeisenbergibm
Copy link
Copy Markdown
Contributor Author

@lizan Could you please approve this PR? @htuch has approved it.

@htuch htuch dismissed lizan’s stale review November 21, 2018 22:12

I think the earlier review indicated this was fine modulo test, and these LGTM.

@htuch htuch merged commit 48b161e into envoyproxy:master Nov 21, 2018
@htuch
Copy link
Copy Markdown
Member

htuch commented Nov 21, 2018

@lizan if you have any further feedback, I'm thinking this will only be test related, so we can punt that to a further PR.

yuval-k added a commit to solo-io/envoy-gloo that referenced this pull request Dec 6, 2018
* no need to submit git to google cloud;
document how to invoke cloud build on local state

* update latest envoy that

* fix envoy compilation. see envoyproxy/envoy#4973
vadimeisenbergibm added a commit to vadimeisenbergibm/envoy that referenced this pull request Dec 25, 2018
…sted server name, in HTTP filters

similar to envoyproxy#4973

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
fredlas pushed a commit to fredlas/envoy that referenced this pull request Mar 5, 2019
…eam cluster (envoyproxy#4973)

Add functionality to override requested server name in the upstream cluster

Risk Level: medium
Testing: unit tests
Docs Changes: yes
Release Notes: yes

Related to envoyproxy#4076

Signed-off-by: Vadim Eisenberg <vadime@il.ibm.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants