Push Gateway

Last modified by Félix Olart on 2025/09/01 11:35

These instructions will help you to configure a Flexisip server to be used as push gateway.

Information

Push gateways are SIP proxies that are in charge of routing INVITE requests to user agents and, if one of these does not answer, send a push notification to this user agent so it can be notified of the incoming call. Such a proxy typically has no authentication capabilities and then must delegate authentication to another proxy, called the backend server.

Principle

Registration of mobile user agents

Each mobile user agent uses the push gateway as outbound-proxy for REGISTER requests. Then, when a user agent starts, a REGISTER request from sip:alice@example.com and to sip:example.com is sent to the push gateway. The contact header of the request contains the resolved URI to use for connecting to the user agent and several key/value parameters containing all the information needed in order to send a push notification to the mobile device.

Once the REGISTER request is received by the push gateway, it is forwarded to the backend server by resolving the domain name of the request URI. Before forwarding, the push gateway replaces the domain of the contact URI by its own IP address and replaces all the URI parameters by a unique parameter called CtRt<random_key> containing the old domain. The random key is generated on Flexisip starting and does not change along instance lifetime. At this moment, no registration is done on the push gateway but the old contact URI is stored into a cache until the backend server responds to the REGISTER request.

Next, the backend server receives the REGISTER request coming from the push gateway. Then, it carries out the registration by associating the SIP identity of the user agent to the masqueraded contact URI. So, when the backend server receives INVITE requests addressed to that SIP identity it will forward them to the push gateway.

Once the registration is done, the backend server will answer a 200 response to the push gateway. On 200 response receipt, the push gateway updates its registration database binding the SIP identity of the user agent to the contact URI with push notification information it has saved before. Then, it forwards the 200 response to the user agent to notify that the registration is successful.

600px-Pushgateway_register.png

Incoming calls

The backend server receives an INVITE request addressed to sip:alice@example.com. Then, it checks its registrar DB and finds out that it must forward the request to the push gateway. The request URI is substituted by the contact URI found in the registrar DB before sending to the push gateway.

600px-Pushgateway_incoming_call.png

Next, the push gateway receives the INVITE request. Then, it reverses the masquerading by substituting the IP address contained in the request URI by the domain contained in the CtRt parameter. The request URI should be sip:alice@example.com then. So, the push gateway can find out the real contact URI of the user agent by searching in its registrar DB. Then, the push gateway will first try to directly connect to the user agent and send a push notification to the device if it does not respond after a little delay. In that last case, the INVITE request will be sent again as soon as the user agent registers again.

600px-Pushgateway_incoming_call_2.png

Outgoing calls

There are two cases:

  • The user agent does not use the push gateway to send INVITE requests but the backend server directly. Then, we are exactly in the situation described in the section above.
  • The push gateway is used as an outbound proxy and then has to be customized in order to perform registrar DB checks only for requests coming from the backend server. That tweak will be detailed in that wiki later.

Requirements for the backend SIP server

The Flexisip push gateway mode will work provided that the backend SIP server meets some reasonable requirements:

  • The backend SIP server must record the SIP URI contact address set by the client in the REGISTER as it is, without removing parameters. However, IP address and port may be modified to fix NAT issues.
    For example: If the client sends a REGISTER with Contact: <sip:bob@sip.example.org;someparameter=somevalue>;expires=3600, the registrar of the backend SIP server must route SIP requests to this client with the target URI set to sip:bob@sip.example.org;someparameter=somevalue ; not just sip:bob@sip.example.org, or even worse sip:sip.example.org .
  • It is better (but not mandatory) if the backend SIP server supports the Path header as defined in RFC3327.

Configure a push gateway with Flexisip

Information

It is highly recommended that the backend server be hosted on a different server (with a public IP address) than the Flexisip/Proxy instance.

Configuring SIP transports

Here is a procedure to help you configure Flexisip SIP transports.

This configuration is important to make sure that requests are correctly being forwarded to the backend server and that clients can successfully reach the push gateway.

The backend server is hosted on a different server

Make sure the backend server has a public IP address along with correct DNS, NAPTR and SRV records.

The routing should work gracefully thanks to DNS resolution.

[global]
# If Flexisip/Proxy is not hosted behind a NAT, you may remove the 'maddr' URI parameter.
transports=sip:<public_ip>:<listening_port>;maddr=<private_ip>;transport=<protocol>

The backend server is hosted on the same server or local network

Here is a typical network architecture for this case:

doc-push-gateway.png

The NAT between public network and Flexisip/Proxy may or may not be present.

Before 2.6

[global]
# Transports used by Flexisip to communicate with the public and private network
# as well as the backend server. It is mandatory to define the public transport as
# the first one in this list.
#
# First  transport "public"  (1): be available to SIP clients on the Internet.
# Second transport "private" (2): communicate with the backend server and
#                                 clients on the private network.
#
# If Flexisip/Proxy is not hosted behind a NAT, you may remove the 'maddr' URI
# parameter from the "public" transport.
transports=sip:<public_ip>:<listening_port>;maddr=<private_ip>;transport=<protocol> sip:<private_ip>:<listening_port>;transport=<protocol>

In this version, Flexisip is not able to determine the correct outgoing transport to use to send requests to the backend server. Therefore, the following additional configuration must be added:

[module::Forward]
routes-config-path=/etc/flexisip/routes.conf

With routes.conf:

<sip:<backend_server_ip>:<backend_server_port>;transport=<backend_server_protocol>>  is_request && (request.uri.domain == '<backend_server_domain>')

Since 2.6

Since Flexisip version 2.6.0, a new URI parameter named 'network' is available for the 'global/transports' parameter. This one can be used to instructs the server the correct outgoing transport to use for outgoing requests. For more information on this parameter, see: global section documentation

[global]
# If Flexisip/Proxy is not hosted behind a NAT, you may remove the 'maddr' URI parameter.
transports=sip:<public_ip>:<listening_port>;maddr=<private_ip>;transport=<protocol> sip:<private_ip>:<listening_port>;transport=<protocol>;network=<network_address>

Example:

[global]
transports=sip:1.2.3.4:5060;maddr=10.0.0.1;transport=tcp sip:10.0.1.1:5080;transport=tcp;network=10.0.1.0/24

Modules configuration

Make sure to configure Flexisip as indicated below:

[global]
# If user agents connect to the push gateway by using a host name instead of
# its IP address you must add the host name into that list. You can put
# several host names.
aliases=localhost

[module::Registrar]
# The Registrar module must be enabled.
enabled=true

# A '*' means the push gateway will register identities regardless of the domain.
# That is safe because the registration will be done only if the backend server
# answers '200 OK' to the forwarded REGISTER request.
reg-domains=*

# Instructs the Registrar module to do the registration once the backend server
# answers '200 OK'.
reg-on-response=true

[module::Router]
# This rule must be enabled if you intend to use the push gateway as the
# outbound proxy. Using this rule, only requests coming from the backend server
# will go through in the Router module. All other requests will be forwarded
# directly. The 'doroute' tag is automatically inserted into the masqueraded
# contact address by the ContactRouteInserter module before being forwarded
# to the backend server. So, requests coming from the backend server will have
# a ''doroute'' parameter in their request URI.
filter=(is_request && request.uri.params contains 'doroute') || is_response

# Do not fail immediately when the push gateway cannot connect to a user agent
# but wait for a register from that last one before trying again.
fork-late=true

# Be careful to set all the information needed by Flexisip to send push
# notifications on each platforms.
# See https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/Push%20notifications/
[module::PushNotification]
# The push notification module must of course be enabled. 
enabled=true

# This module will masquerade contact headers before forwarding REGISTER
# requests.Settings for that module are not displayed in the default
# configuration file. So, you have to add it manually.
[module::ContactRouteInserter]
# The module must be enabled.
enabled=true

# If not true, Flexisip will put the IP address of the user agent in the 'CtRt'
# parameter instead of the domain used in the request URI of the REGISTER.
insert-domain=true