1. Presence server

Last modified by Félix Olart on 2023/10/13 16:37

The Flexisip Presence server is a SIP user-agent handling SUBSCRIBE/NOTIFY for the "presence" event. It implements the following RFCs:

The overall behavior of the presence server is quite simple: it receives SIP SUBSCRIBEs from clients that wish to receive presence information for an individual contact URI, or a list of URIs which represents a set of SIP contacts. The presence server processes the target URIs for which the presence information is requested, and generates a SIP NOTIFY request back to the clients containing the presence information.

The presence information is obtained from two different sources:

  • from PUBLISH requests received by clients, which directly publish their presence information on a regular basis. This presence information is called "short term presence".
  • from the authentication database of Flexisip. Since this database contains the list of SIP users who are members of the service, it allows to distribute to clients a long term reachability information about other users. Independently on whether users are actively using their SIP application or not, the fact that some SIP users exist or not in the list of users who are registered on the SIP service gives a useful indication about their reachability. This presence information is referred as "long term presence".

The two sources are queried in that order: first long term presence, then short term presence. Then a presence PIDF+RPID document describing the results of the two sources is synthesized and sent within a SIP NOTIFY.

Operation in GNU/Linux

From a system perspective, the presence server runs as a daemon in its own process, and hence has no adherence on the proxy from an execution standpoint. It can be started, stopped, restarted using usual SystemD commands, for example:

systemctl status flexisip-presence

It can of course be started from a terminal, for example:

/opt/belledonne-communications/bin/flexisip --server presence --debug

The configuration of the presence server is read by default from /etc/flexisip/flexisip.conf, mainly from the [presence-server] section.

The presence server in the SIP network

The presence server itself performs no authentication, no request integrity checking, no DoS protection. These tasks are left to the proxy server. Furthermore, it only listens on SIP/TCP. It is then recommended to configure the presence server to listen on a private IP address or localhost, so that it cannot be reached directly from the internet.

Instead, all requests shall first go through the Flexisip proxy server, which can then forward presence-related requests to the presence server thanks to the Presence module of the proxy. This module is in charge of recognizing presence-related requests and forwards them to the presence server's URI.

Using long-term presence

The long-term presence information is obtained by querying the database setup in the module::Authentication section of flexisip.conf, using the same SQL request as the one configured to get passwords for a given user. In addition, the long-term presence information can be obtained through an alias indirection such as the e164 phone number of users. Indeed, users can typically be invited to register to the SIP service by providing two pieces of information:

  • a username
  • a phone number, usually verified through a short code sent by SMS.

A typical use case for a communication app running on a phone is then to be able to identify phone numbers that are part of the SIP service from the phone's address book. This can be done thanks to the "long term presence" ability to use the alias indirection, according to the following flow:

1. The SIP client sends a SIP SUBSCRIBE with a self-contained resource list (RFC5367) containing SIP URIs with "phone=" parameter, containing all the phone numbers of the address book, for example:

<resource-lists xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:ietf:params:xml:ns:resource-lists">
<entry uri="sip:+195XXXXXXXX@sip.linphone.org;user=phone"/>
<entry uri="sip:+332XXXXXXXX@sip.linphone.org;user=phone"/>
<entry uri="sip:+33XXXXXXXXX@sip.linphone.org;user=phone"/>

2. The presence server extracts the phone numbers, and queries the authentication database (as setup in module::Authentication) to search for these phone numbers and return the list of SIP users matching these numbers. When the authentication database is configured to use the soci connector, the 'soci-users-with-phones-request' SQL request is executed to obtain such a list.

3. The presence server generates and sends a NOTIFY request including a PIDF+RPID body, containing the list of matched phone numbers and their associated SIP URI as a <contact> XML element, as well as their associated presence information. The body is by default compressed to save bandwidth.

Using resource lists

Despite individual SUBSCRIBEs are supported, they are not an efficient way to obtain other users' presence in a real deployment. Indeed, for each contact in the address book of a given user, a SIP SUBSCRIBE will be generated, creating a dialog, and then NOTIFY requests will be received to get the presence of each contact. For that reason, the use of resource lists (RFC4662) by clients is highly recommended.

Resource lists can be of two types in the presence server.

Dynamically client provided resources lists

These are self-contained resource lists as described in RFC5367. This use case is the typical one for a SIP service where users have an address book already populated on their phones. Should the local address book be updated by the user, a new SUBSCRIBE can be sent to reflect the change. To save bandwidth, the SIP user-agent may compress the SIP body with the standard "deflate" encoding.

Server known resource lists

The SIP user-agent is configured to SUBSCRIBE to a URI identified resource list, such as "sip:bob-list@company.example.org". The user-agent has no idea about the elements of this list, but the server knows. When receiving such a SUBSCRIBE request for URI identified resource list, the presence server can query an SQL database to obtain the list of SIP contacts that are part of the list. Then, presence information (long term, short term) is queried following the same process as for SUBSCRIBE self-contained resource lists.

The 'rls-database-connection' and 'rls-database-request' properties of the [presence-server] section of the configuration define respectively the database connection and the SQL request to execute to obtain the content of the resource list. Please note that the SIP identity of the subscriber can be passed to the request, which allows to generate per-user content despite the name the SIP URI identifying the list can be the same for all users.

When the SIP client receives the NOTIFY from the server, it can then discover the members of the list. Since the NOTIFY contains all the elements of the resource lists, as well as presence documents for contacts for which presence is known.

The server knows resource lists which are suitable for a SIP service when users don't have a populated address book already: for example for employees in a company, so that each employee can have the list of contact information and presence for his/her colleagues.

Confidentiality rules for accessing the presence information

Before a SIP SUBSCRIBE reaches the presence server, it goes through the SIP proxy which can authenticate or reject the request. However to ensure a reasonable protection of users' privacy, the presence server restricts the distribution of presence information to users who subscribed to each other.

Let's take this concrete example:

  1. A subscribes to B's presence but B does not subscribe to A's presence. Then, A will receive no information about B's presence.
  2. B decides to subscribe to presence information of A. A and B are now mutually subscribed to each other's presence and the presence server notifies B's presence to A, as well as A's presence to B.

This rule stands for both long-term and short-term presence.

High availability and scalability

The presence server can be deployed redundantly, for example collocated with a proxy server node, as long as only long-term presence is required for the service.
Indeed, the distribution of short term presence information across presence server nodes is not currently implemented.