Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,21 @@ These input functions are available for matching HTTP requests:
Network Input Functions
***********************

These input functions are available for matching both TCP connections and UDP datagrams:
These input functions are available for matching TCP connections, UDP datagrams, and HTTP requests:

* :ref:`Destination IP <extension_envoy.matching.inputs.destination_ip>`.
* :ref:`Destination port <extension_envoy.matching.inputs.destination_port>`.
* :ref:`Source IP <extension_envoy.matching.inputs.source_ip>`.
* :ref:`Source port <extension_envoy.matching.inputs.source_port>`.

These input functions are available for matching TCP connections:
These input functions are available for matching TCP connections and HTTP requests:

* :ref:`Direct source IP <extension_envoy.matching.inputs.direct_source_ip>`.
* :ref:`Source type <extension_envoy.matching.inputs.source_type>`.
* :ref:`Server name <extension_envoy.matching.inputs.server_name>`.

These input functions are available for matching TCP connections:

* :ref:`Transport protocol <extension_envoy.matching.inputs.transport_protocol>`.
* :ref:`Application protocol <extension_envoy.matching.inputs.application_protocol>`.

Expand Down
1 change: 1 addition & 0 deletions envoy/http/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,7 @@ class HttpMatchingData {
virtual RequestTrailerMapOptConstRef requestTrailers() const PURE;
virtual ResponseHeaderMapOptConstRef responseHeaders() const PURE;
virtual ResponseTrailerMapOptConstRef responseTrailers() const PURE;
virtual const Network::ConnectionInfoProvider& connectionInfoProvider() const PURE;
};

/**
Expand Down
4 changes: 4 additions & 0 deletions envoy/network/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,10 @@ class MatchingData {
virtual ~MatchingData() = default;

virtual const ConnectionSocket& socket() const PURE;

const ConnectionInfoProvider& connectionInfoProvider() const {
return socket().connectionInfoProvider();
}
};

/**
Expand Down
9 changes: 6 additions & 3 deletions source/common/http/filter_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,8 @@ class FilterManager : public ScopeTrackedObject,
addStreamDecoderFilterWorker(
filter,
std::make_shared<FilterMatchState>(std::move(match_tree),
std::make_shared<Matching::HttpMatchingDataImpl>()),
std::make_shared<Matching::HttpMatchingDataImpl>(
stream_info_.downstreamAddressProvider())),
false);
return;
}
Expand All @@ -715,7 +716,8 @@ class FilterManager : public ScopeTrackedObject,
addStreamEncoderFilterWorker(
filter,
std::make_shared<FilterMatchState>(std::move(match_tree),
std::make_shared<Matching::HttpMatchingDataImpl>()),
std::make_shared<Matching::HttpMatchingDataImpl>(
stream_info_.downstreamAddressProvider())),
false);
return;
}
Expand All @@ -736,7 +738,8 @@ class FilterManager : public ScopeTrackedObject,
// the result to both filters after the first match evaluation.
if (match_tree) {
auto matching_state = std::make_shared<FilterMatchState>(
std::move(match_tree), std::make_shared<Matching::HttpMatchingDataImpl>());
std::move(match_tree), std::make_shared<Matching::HttpMatchingDataImpl>(
stream_info_.downstreamAddressProvider()));
addStreamDecoderFilterWorker(filter, matching_state, true);
addStreamEncoderFilterWorker(filter, std::move(matching_state), true);
return;
Expand Down
8 changes: 8 additions & 0 deletions source/common/http/matching/data_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ namespace Matching {
*/
class HttpMatchingDataImpl : public HttpMatchingData {
public:
explicit HttpMatchingDataImpl(const Network::ConnectionInfoProvider& connection_info_provider)
: connection_info_provider_(connection_info_provider) {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do you think it would be better to provide a StreamInfo directly for HTTP matching data, compared to ConnectionSocket for network matching data?

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.

StreamInfo is complicated, it can be nested for internal redirects so I wanted to avoid bringing all that complexity implicitly.
I think we'll probably end-up using it though.


static absl::string_view name() { return "http"; }

void onRequestHeaders(const RequestHeaderMap& request_headers) {
Expand Down Expand Up @@ -47,7 +50,12 @@ class HttpMatchingDataImpl : public HttpMatchingData {
return makeOptRefFromPtr(response_trailers_);
}

const Network::ConnectionInfoProvider& connectionInfoProvider() const override {
return connection_info_provider_;
}

private:
const Network::ConnectionInfoProvider& connection_info_provider_;
const RequestHeaderMap* request_headers_{};
const ResponseHeaderMap* response_headers_{};
const RequestTrailerMap* request_trailers_{};
Expand Down
1 change: 1 addition & 0 deletions source/common/network/matching/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ envoy_cc_library(
srcs = ["inputs.cc"],
hdrs = ["inputs.h"],
deps = [
"//envoy/http:filter_interface",
"//envoy/matcher:matcher_interface",
"//envoy/network:filter_interface",
"//envoy/registry",
Expand Down
108 changes: 38 additions & 70 deletions source/common/network/matching/inputs.cc
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
#include "source/common/network/matching/inputs.h"

#include "envoy/http/filter.h"
#include "envoy/registry/registry.h"

#include "source/common/network/utility.h"

#include "absl/strings/str_cat.h"

namespace Envoy {
namespace Network {
namespace Matching {

template <>
Matcher::DataInputGetResult DestinationIPInput<MatchingData>::get(const MatchingData& data) const {
const auto& address = data.socket().connectionInfoProvider().localAddress();
if (address->type() != Network::Address::Type::Ip) {
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::nullopt};
}
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable,
address->ip()->addressAsString()};
}

template <>
Matcher::DataInputGetResult
DestinationIPInput<UdpMatchingData>::get(const UdpMatchingData& data) const {
Expand All @@ -31,17 +20,6 @@ DestinationIPInput<UdpMatchingData>::get(const UdpMatchingData& data) const {
address.ip()->addressAsString()};
}

template <>
Matcher::DataInputGetResult
DestinationPortInput<MatchingData>::get(const MatchingData& data) const {
const auto& address = data.socket().connectionInfoProvider().localAddress();
if (address->type() != Network::Address::Type::Ip) {
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::nullopt};
}
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable,
absl::StrCat(address->ip()->port())};
}

template <>
Matcher::DataInputGetResult
DestinationPortInput<UdpMatchingData>::get(const UdpMatchingData& data) const {
Expand All @@ -53,16 +31,6 @@ DestinationPortInput<UdpMatchingData>::get(const UdpMatchingData& data) const {
absl::StrCat(address.ip()->port())};
}

template <>
Matcher::DataInputGetResult SourceIPInput<MatchingData>::get(const MatchingData& data) const {
const auto& address = data.socket().connectionInfoProvider().remoteAddress();
if (address->type() != Network::Address::Type::Ip) {
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::nullopt};
}
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable,
address->ip()->addressAsString()};
}

template <>
Matcher::DataInputGetResult SourceIPInput<UdpMatchingData>::get(const UdpMatchingData& data) const {
const auto& address = data.remoteAddress();
Expand All @@ -73,16 +41,6 @@ Matcher::DataInputGetResult SourceIPInput<UdpMatchingData>::get(const UdpMatchin
address.ip()->addressAsString()};
}

template <>
Matcher::DataInputGetResult SourcePortInput<MatchingData>::get(const MatchingData& data) const {
const auto& address = data.socket().connectionInfoProvider().remoteAddress();
if (address->type() != Network::Address::Type::Ip) {
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::nullopt};
}
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable,
absl::StrCat(address->ip()->port())};
}

template <>
Matcher::DataInputGetResult
SourcePortInput<UdpMatchingData>::get(const UdpMatchingData& data) const {
Expand All @@ -94,32 +52,6 @@ SourcePortInput<UdpMatchingData>::get(const UdpMatchingData& data) const {
absl::StrCat(address.ip()->port())};
}

Matcher::DataInputGetResult DirectSourceIPInput::get(const MatchingData& data) const {
const auto& address = data.socket().connectionInfoProvider().directRemoteAddress();
if (address->type() != Network::Address::Type::Ip) {
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::nullopt};
}
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable,
address->ip()->addressAsString()};
}

Matcher::DataInputGetResult SourceTypeInput::get(const MatchingData& data) const {
const bool is_local_connection = Network::Utility::isSameIpOrLoopback(data.socket());
if (is_local_connection) {
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, "local"};
}
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::nullopt};
}

Matcher::DataInputGetResult ServerNameInput::get(const MatchingData& data) const {
const auto server_name = data.socket().requestedServerName();
if (!server_name.empty()) {
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable,
std::string(server_name)};
}
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::nullopt};
}

Matcher::DataInputGetResult TransportProtocolInput::get(const MatchingData& data) const {
const auto transport_protocol = data.socket().detectedTransportProtocol();
if (!transport_protocol.empty()) {
Expand All @@ -138,17 +70,53 @@ Matcher::DataInputGetResult ApplicationProtocolInput::get(const MatchingData& da
return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::nullopt};
}

class DestinationIPInputFactory : public DestinationIPInputBaseFactory<MatchingData> {};
class UdpDestinationIPInputFactory : public DestinationIPInputBaseFactory<UdpMatchingData> {};
class HttpDestinationIPInputFactory : public DestinationIPInputBaseFactory<Http::HttpMatchingData> {
};
REGISTER_FACTORY(DestinationIPInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(UdpDestinationIPInputFactory, Matcher::DataInputFactory<UdpMatchingData>);
REGISTER_FACTORY(HttpDestinationIPInputFactory, Matcher::DataInputFactory<Http::HttpMatchingData>);

class DestinationPortInputFactory : public DestinationPortInputBaseFactory<MatchingData> {};
class UdpDestinationPortInputFactory : public DestinationPortInputBaseFactory<UdpMatchingData> {};
class HttpDestinationPortInputFactory
: public DestinationPortInputBaseFactory<Http::HttpMatchingData> {};
REGISTER_FACTORY(DestinationPortInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(UdpDestinationPortInputFactory, Matcher::DataInputFactory<UdpMatchingData>);
REGISTER_FACTORY(HttpDestinationPortInputFactory,
Matcher::DataInputFactory<Http::HttpMatchingData>);

class SourceIPInputFactory : public SourceIPInputBaseFactory<MatchingData> {};
class UdpSourceIPInputFactory : public SourceIPInputBaseFactory<UdpMatchingData> {};
class HttpSourceIPInputFactory : public SourceIPInputBaseFactory<Http::HttpMatchingData> {};
REGISTER_FACTORY(SourceIPInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(UdpSourceIPInputFactory, Matcher::DataInputFactory<UdpMatchingData>);
REGISTER_FACTORY(HttpSourceIPInputFactory, Matcher::DataInputFactory<Http::HttpMatchingData>);

class SourcePortInputFactory : public SourcePortInputBaseFactory<MatchingData> {};
class UdpSourcePortInputFactory : public SourcePortInputBaseFactory<UdpMatchingData> {};
class HttpSourcePortInputFactory : public SourcePortInputBaseFactory<Http::HttpMatchingData> {};
REGISTER_FACTORY(SourcePortInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(UdpSourcePortInputFactory, Matcher::DataInputFactory<UdpMatchingData>);
REGISTER_FACTORY(HttpSourcePortInputFactory, Matcher::DataInputFactory<Http::HttpMatchingData>);

class DirectSourceIPInputFactory : public DirectSourceIPInputBaseFactory<MatchingData> {};
class HttpDirectSourceIPInputFactory
: public DirectSourceIPInputBaseFactory<Http::HttpMatchingData> {};
REGISTER_FACTORY(DirectSourceIPInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(SourceTypeInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(HttpDirectSourceIPInputFactory, Matcher::DataInputFactory<Http::HttpMatchingData>);

class ServerNameInputFactory : public ServerNameInputBaseFactory<MatchingData> {};
class HttpServerNameInputFactory : public ServerNameInputBaseFactory<Http::HttpMatchingData> {};
REGISTER_FACTORY(ServerNameInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(HttpServerNameInputFactory, Matcher::DataInputFactory<Http::HttpMatchingData>);

class SourceTypeInputFactory : public SourceTypeInputBaseFactory<MatchingData> {};
class HttpSourceTypeInputFactory : public SourceTypeInputBaseFactory<Http::HttpMatchingData> {};
REGISTER_FACTORY(SourceTypeInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(HttpSourceTypeInputFactory, Matcher::DataInputFactory<Http::HttpMatchingData>);

REGISTER_FACTORY(TransportProtocolInputFactory, Matcher::DataInputFactory<MatchingData>);
REGISTER_FACTORY(ApplicationProtocolInputFactory, Matcher::DataInputFactory<MatchingData>);

Expand Down
Loading