Sip proxy: Support for outbound transactions#23435
Sip proxy: Support for outbound transactions#23435arejasco wants to merge 64 commits intoenvoyproxy:mainfrom
Conversation
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
ConnectionManger DownstreamConnectionInfos now needs to be a friend of the ConnectionManager so that it may access the item class. Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Copy the required state from ActiveTrans decoderFilterCallbacks into the Upstream request, as ActiveTrans will be deleted after tx time at 32 seconds. Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
DecoderFilterCallbacks may have been deleted before a downstream tx is recvd, so UpstreamRequest must keep its own ref. +Clean up logs a little. Signed-off-by: Jonah Murphy <jonamurp@cisco.com>
Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
…change Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
-X-Envoy-Origin-Ingress header added to all messages (not only requests) Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
…am connection creation (might require hardening). - Additional debug logs for debugging downstream connection map management (remove them when productizing) Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
…er heading downstream Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
…oder - AppException class being able to work with other error codes besides 503 Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
…ons failure Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
…ystem for clearing cache Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
…th it Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
…hout std:regex, against code styling Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
Signed-off-by: Adrian Rejas Conde <arejasco@cisco.com>
|
@durd07 would you mind giving this another pass |
|
As this is so big a PR, I need some time to review, I will began to review this soon. |
|
thanks /wait-any |
|
|
||
| #include <sstream> | ||
|
|
||
| #include "sip.h" |
| #include "contrib/sip_proxy/filters/network/source/filters/well_known_names.h" | ||
| #include "contrib/sip_proxy/filters/network/source/router/router_impl.h" | ||
| #include "contrib/sip_proxy/filters/network/source/stats.h" | ||
| #include "filters/filter.h" |
| setLocalResponseSent(decoder_->metadata()->transactionId().value()); | ||
|
|
||
| if (decoder_->metadata()->msgType() == MsgType::Request) { | ||
| sendLocalReply(*(decoder_->metadata()), ex, false); |
| // } | ||
| std::string&& k = std::string(metadata->transactionId().value()); | ||
| if (metadata->msgType() == MsgType::Request) { | ||
| stats_.counterFromElements(methodStr[metadata->methodType()], "request_received").inc(); |
There was a problem hiding this comment.
low performance, I have changed, will merge in my next PR.
| FilterStatus ConnectionManager::UpstreamActiveTrans::transportEnd() { | ||
| parent_.stats_.upstream_response_.inc(); | ||
| parent_.stats_ | ||
| .counterFromElements(methodStr[metadata_->methodType()], "upstream_response_proxied") |
| } | ||
|
|
||
| void complete(); | ||
| void complete() { complete(true); }; |
| ASSERT(new_headers_pos_ != absl::string_view::npos); | ||
|
|
||
| absl::string_view str_type = HeaderTypes::get().header2Str(type); | ||
| std::string header = std::string(str_type) + ": " + value + "\r\n"; |
| } | ||
|
|
||
| bool MessageMetadata::hasMsgHeader(HeaderType type) { | ||
| auto init_pos = raw_msg_.find(HeaderTypes::get().header2Str(type).data()); |
There was a problem hiding this comment.
check whether header name exist in headers_
| */ | ||
| void setTransactionId(absl::string_view data); | ||
|
|
||
| OriginIngress* originIngress() { return origin_ingress_.get(); }; |
| {"P-Nokia-Cookie-IP-Mapping", HeaderType::PCookieIPMap}, | ||
| {"X-Envoy-Origin-Ingress", HeaderType::XEnvoyOriginIngress}}; | ||
|
|
||
| const std::map<HeaderType, absl::string_view> sip_header_type_reverse_map_{ |
There was a problem hiding this comment.
please help to replace std::map into absl_flat_map
|
Thanks for your review @durd07. I'll try to address all your comments in the following days |
|
@arejasco I merged one PR #24165 (comment) with the latest stats change, please merge this and adapt the new stats changes. Sorry for any inconvenience. |
|
assigning myself to merge after this has @durd07's LGTM |
|
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
Sorry for the lack of activity on this PR, I've been on a long abscence. I'll try to address your comments between this week and the next one |
|
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
Still working on it |
|
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
This pull request has been automatically closed because it has not had activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Commit Message: Add support for outbound transactions to SIP proxy extension
Co-authored-by: Jonah Murphy jonamurp@cisco.com
Additional Description: See below
Risk Level: Medium
Testing: Unit testing & Manual testing
Docs Changes: API for SIP proxy plugin settings updated
Release Notes:
Platform Specific Features:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Fixes commit #PR or SHA]
[Optional Deprecated:]
[Optional API Considerations:]
This PR provides to SIP proxy extension for Envoy with support for handling outbound transactions, that is, transactions being initiated in the SIP server towards the client.
Background
SIP proxy contrib extension was implemented in September 2021 to enable Service Mesh for SIP protocol, taking into account SIP specific router mechanisms and features.
Current behavior of SIP proxy extension supports the forwarding of inbound messages (request coming from the client to be redirected to an endpoint), but only responses to existing transactions initiated by an inbound request are supported to be forwarded from the endpoint to the client. The forwarding of outbound request coming from an endpoint is not currently supported by SIP proxy extension, as Envoy does not know to which downstream connection has to forward the message when received.
This PR provides through the usage of a new header the routing mechanisms for forwarding an outbound request coming from an endpoint to the target client, providing in that way support for outbound initiated transactions.
Design
The basic idea is to provide support for outbound transactions by adding a new header, X-Envoy-Origin-Ingress, which will provide information about the thread and downstream connection where to forward any outbound transaction initiated. This X-Envoy-Origin-Ingress header will be composed of two parameters:
These parameters will be initiated in the beginning, when a client connects to Envoy and a ConnectionManager is initiated. For each thread, a local map will relate the downstream connection ID with its ConnectionManager instance through a wrapper object called DownstreamConnection (new class).
Each message coming from the client (either request or response) will be modified by adding the X-Envoy-Origin-Ingress header before being forwarded to an endpoint.
The endpoint, when receiving a request coming from Envoy, will process the request as usual, but storing the value from X-Envoy-Origin-Ingress header for being used in future outbound transactions.
Each outbound request coming from a server will need to have the X-Envoy-Origin-Ingress header. It will be parsed and the DownstreamConnection associated will be recovered, providing the ConnectionManager instance to be used for forwarding the message to the client. An UpstreamTransaction instance (new class) will be created and mapped in a thread local map, saving the address of the endpoint sending the request.
Each response coming from the client to an outbound request will be processed by getting the UpstreamTransaction instance from the transaction ID and routing the message but setting the address of the endpoint which started the transaction as preferred destination. In that way the response to an outbound request will be routed by setting an affinity with the origin endpoint of the request, having the response forwarded to the same endpoint.
System architecture
This is the relationship between classes in the forwarding of an outbound initiated request to a client:
And this is the relationship between classes in the forwarding of the response to an outbound initiated request to the original endpoint:
Call flows
Here is the call flow for the connection and register of the client to the SIP server through Envoy:
Here is the call flow for a successful outbound transaction (an INVITE in this case):
Configuration
For configuring the SIP proxy plugin to allow the management of upstream transactions as an optional feature, API files for SIP proxy extension has been modified to include a new node for SIP proxy clusters, called upstream_transactions. In that way, it will be possible to enable/disable upstream transactions at a cluster level.
This node will define for now just one parameter, enabled, which enables or disables the support for outbound transactions in that cluster. Disabling outbound transactions will provoke the following actions in the cluster:
Main changes done
Here is the summary of the main changes done in this PR: