Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/envoy/network/address.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ class Instance {
*/
virtual const std::string& asString() const PURE;

/**
* @param port
* @return returns the same address but bound on the given port.
*/
virtual std::unique_ptr<Instance> withPort(uint16_t port) const PURE;

/**
* Bind a socket to this address. The socket should have been created with a call to socket() on
* this object.
Expand Down
12 changes: 12 additions & 0 deletions include/envoy/upstream/upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ class Host : virtual public HostDescription {
*/
virtual CreateConnectionData createConnection(Event::Dispatcher& dispatcher) const PURE;

/**
* Create a connection for this host on a specific port.
* @param dispatcher supplies the owning dispatcher.
* @return the connection data which includes the raw network connection as well as the *real*
* host that backs it. The reason why a 2nd host is returned is that some hosts are
* logical and wrap multiple real network destinations. In this case, a different host
* will be returned along with the connection vs. the host the method was called on.
* If it matters, callers should not assume that the returned host will be the same.
*/
virtual CreateConnectionData
createConnectionWithNewPort(uint16_t port, Event::Dispatcher& dispatcher) const PURE;

/**
* @return host specific gauges.
*/
Expand Down
5 changes: 5 additions & 0 deletions source/common/json/config_schemas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,11 @@ const std::string Json::Schema::CLUSTER_SCHEMA(R"EOF(
"type" : "string",
"enum" : ["http", "tcp"]
},
"port": {
"type" : "integer",
"minimum" : 1,
"exclusiveMinimum" : true
},
"timeout_ms" : {
"type" : "integer",
"minimum" : 0,
Expand Down
19 changes: 19 additions & 0 deletions source/common/network/address_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class Ipv4Instance : public InstanceBase {
const Ip* ip() const override { return &ip_; }
int socket(SocketType type) const override;

std::unique_ptr<Instance> withPort(uint16_t port) const override { return ip_.withPort(port); }

private:
struct Ipv4Helper : public Ipv4 {
uint32_t address() const override { return address_.sin_addr.s_addr; }
Expand All @@ -73,6 +75,11 @@ class Ipv4Instance : public InstanceBase {
uint32_t port() const override { return ntohs(ipv4_.address_.sin_port); }
IpVersion version() const override { return IpVersion::v4; }

std::unique_ptr<Instance> withPort(uint16_t port) const {
return std::unique_ptr<Instance>(
new Ipv4Instance(friendly_address_, static_cast<uint32_t>(port)));
}

Ipv4Helper ipv4_;
std::string friendly_address_;
};
Expand Down Expand Up @@ -112,6 +119,8 @@ class Ipv6Instance : public InstanceBase {
const Ip* ip() const override { return &ip_; }
int socket(SocketType type) const override;

std::unique_ptr<Instance> withPort(uint16_t port) const override { return ip_.withPort(port); }

private:
struct Ipv6Helper : public Ipv6 {
std::array<uint8_t, 16> address() const override;
Expand All @@ -129,6 +138,12 @@ class Ipv6Instance : public InstanceBase {
uint32_t port() const override { return ipv6_.port(); }
IpVersion version() const override { return IpVersion::v6; }

std::unique_ptr<Instance> withPort(uint16_t port) const {
auto cpy = ipv6_.address_;
cpy.sin6_port = htons(port);
return std::unique_ptr<Instance>(new Ipv6Instance(cpy));
}

Ipv6Helper ipv6_;
std::string friendly_address_;
};
Expand Down Expand Up @@ -157,6 +172,10 @@ class PipeInstance : public InstanceBase {
const Ip* ip() const override { return nullptr; }
int socket(SocketType type) const override;

std::unique_ptr<Instance> withPort(uint16_t) const override {
throw std::logic_error("Cannot have a Pipe with a port.");
}

private:
sockaddr_un address_;
};
Expand Down
6 changes: 4 additions & 2 deletions source/common/upstream/health_checker_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ HttpHealthCheckerImpl::HttpHealthCheckerImpl(const Cluster& cluster, const Json:
Runtime::Loader& runtime,
Runtime::RandomGenerator& random)
: HealthCheckerImplBase(cluster, config, dispatcher, runtime, random),
path_(config.getString("path")) {
path_(config.getString("path")), port_(config.getInteger("port", 0)) {
if (config.hasObject("service_name")) {
service_name_.value(config.getString("service_name"));
}
Expand Down Expand Up @@ -224,7 +224,9 @@ void HttpHealthCheckerImpl::HttpActiveHealthCheckSession::onInterval() {
parent_.stats_.attempt_.inc();

if (!client_) {
Upstream::Host::CreateConnectionData conn = host_->createConnection(parent_.dispatcher_);
Upstream::Host::CreateConnectionData conn =
parent_.port_ != 0 ? host_->createConnectionWithNewPort(parent_.port_, parent_.dispatcher_)
: host_->createConnection(parent_.dispatcher_);
client_.reset(parent_.createCodecClient(conn));
client_->addConnectionCallbacks(*this);
expect_reset_ = false;
Expand Down
1 change: 1 addition & 0 deletions source/common/upstream/health_checker_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class HttpHealthCheckerImpl : public HealthCheckerImplBase {
const std::vector<HostPtr>& hosts_removed) override;

const std::string path_;
const uint16_t port_;
std::unordered_map<HostPtr, HttpActiveHealthCheckSessionPtr> active_sessions_;
Optional<std::string> service_name_;
};
Expand Down
16 changes: 15 additions & 1 deletion source/common/upstream/upstream_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,23 @@ Host::CreateConnectionData HostImpl::createConnection(Event::Dispatcher& dispatc
return {createConnection(dispatcher, *cluster_, address_), shared_from_this()};
}

Host::CreateConnectionData
HostImpl::createConnectionWithNewPort(uint16_t port, Event::Dispatcher& dispatcher) const {
return {createConnection(dispatcher, *cluster_, address_, port), shared_from_this()};
}

Network::ClientConnectionPtr HostImpl::createConnection(Event::Dispatcher& dispatcher,
const ClusterInfo& cluster,
Network::Address::InstancePtr address) {
Network::Address::InstancePtr _address,
uint16_t port) {
Network::Address::InstancePtr address;
if (port != 0) {
auto ptr = _address->withPort(port);
address.reset(ptr.release());
} else {
address = std::move(_address);
}

if (cluster.sslContext()) {
return Network::ClientConnectionPtr{
dispatcher.createSslClientConnection(*cluster.sslContext(), address)};
Expand Down
5 changes: 4 additions & 1 deletion source/common/upstream/upstream_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class HostImpl : public HostDescriptionImpl,
// Upstream::Host
std::list<Stats::CounterPtr> counters() const override { return stats_store_.counters(); }
CreateConnectionData createConnection(Event::Dispatcher& dispatcher) const override;
CreateConnectionData createConnectionWithNewPort(uint16_t port,
Event::Dispatcher& dispatcher) const override;
std::list<Stats::GaugePtr> gauges() const override { return stats_store_.gauges(); }
void healthFlagClear(HealthFlag flag) override { health_flags_ &= ~enumToInt(flag); }
bool healthFlagGet(HealthFlag flag) const override { return health_flags_ & enumToInt(flag); }
Expand All @@ -90,7 +92,8 @@ class HostImpl : public HostDescriptionImpl,
protected:
static Network::ClientConnectionPtr createConnection(Event::Dispatcher& dispatcher,
const ClusterInfo& cluster,
Network::Address::InstancePtr address);
Network::Address::InstancePtr address,
uint16_t port = 0);

private:
std::atomic<uint64_t> health_flags_{};
Expand Down
7 changes: 7 additions & 0 deletions test/mocks/upstream/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ class MockHost : public Host {
return {Network::ClientConnectionPtr{data.connection_}, data.host_};
}

// XXX: mock me
CreateConnectionData createConnectionWithNewPort(uint16_t,
Event::Dispatcher& dispatcher) const override {
MockCreateConnectionData data = createConnection_(dispatcher);
return {Network::ClientConnectionPtr{data.connection_}, data.host_};
}

void setOutlierDetector(Outlier::DetectorHostSinkPtr&& outlier_detector) override {
setOutlierDetector_(outlier_detector);
}
Expand Down