This module implements a presence server, i.e. entity that receives SUBSCRIBE requests and sends NOTIFY when presence status of a user changes and allows user to use PUBLISH request for publishing presence status information.
handle SUBSCRIBE requests
handle PUBLISH requests
XCAP authorization of subscriptions
failover - all subscription's data including SIP dialogs can be stored into database and reloaded on startup
offline watcher info - watchers can be stored into database when presentity is offline and sent in watcher info notification when presentity subscribes to its watcherinfo again
User's presence status is hold internaly (in memory); it can be taken from:
registrar - online/offline information with contact
published information by user (see [publish])
to be done: from reg events subscriptions
to be done: from subscriptions to users
TODO: cache mode needed by large setups, when the presence status will be in memory only cached, not fully stored (limited size of cache, possibility to switch it off). [status: design in progress, coding will start after Ottendorf will be branched]
Supported document formats in PUBLISH:
Supported document formats in NOTIFY:
Modules
tm
dialog
usrloc
optionaly database module (mysql, ...)
optionaly xcap module for XCAP authorization
Libraries
libxml2 - external library for parsing XML documents
libcds (internal)
libxcap (internal) - XCAP queries (authorization)
libpresence (internal) - used for internal subscriptions from RLS
Short notes to be remembered...
There are two possibilities how to get authorization rules from XCAP when creating new presentity (controled by module parameter async_auth_queries):
asynchronously - XCAP is not queried when processing SUBSCRIBE request which created presentity what results into 202 response and delayed authorization of such first watcher. First NOTIFY in this case will carry no information and "pending" status; later (as soon as will be authorization rules got from XCAP) will be generated other NOTIFY with correct authorization status.
synchronously - XCAP is queried for presence rules immediately, but this slows down processing of such SUBSCRIBE request and may bring problems under heavy load so it is not recommended. In this case first NOTIFY contains correct subscription status and data.
Other SUBSCRIBE requests than the first one which creates the presentity already have authorization document which is stored within presentity's data and don't need to wait for XCAP. But this can consume lots of memory [TODO: this will be solved by intelligent document caching within XCAP module only].
Re-authorization is done by timer - authorization document queries for each presentity are sent time after time and all presentity's watchers are reauthorized. This is due to missing implementation of notification mechanism for XCAP server data changes (might be implemented in the future, but XCAP server able to do it is needed!).
One of reasons which lead to timer-based reauthorization was that previous method, when reauthorization was done only when watcher is resubscribing, was not acceptable for users which want to propagate changes in authorization document immediately.
When a non-2xx final response to a NOTIFY comes, the subscription is destroyed (really needed under high load). It is possible to say that 408 responses are ignored (see parameter ignore_408_on_notify) but this should be used for testing only.
PA modules does state aggregation from multiple sources:
Information from registrar is taken by callbacks to usrloc module. Each registered contact is taken as a standalone tuple. Status may be “open” or “closed”, contact for the tuple is taken from contact registration. Priority of such tuples is taken from parameter default_priority_percentage. It is recommended to have this value lower than priority of tuples published by PUBLISH.
You can ommit this source by setting use_callbacks to 0.
State published by clients using PUBLISH request according to RFC 3903. There can be more published tuples, each of them is identified by its id in PIDF document. This id is used for tuple identification in re-publications, but it is NOT used as id in NOTIFYs sent from PA. Instead of it is used newly generated tuple id because this id must be unique (across all presentity's UACs).
It is NOT possible to replace existing tuple with publishing information for tuple with the same id - this would be against RFC 3903! When publishing status it is only possible to have influence on tuples published with the same entity tag (see Sip-If-Match and SIP-ETag header fields).
PA understoods only basic PIDF, but it can handle PIDF extensions like RPID too. PIDF extensions are hold as whole XML elements without knowing about their definition and thus publishing client is responsible for correct content of them. PA ignores "mustUnderstand" attribute (see [pidf]). [Are there any problems with it?]
You can control this source by PUBLISH request handling in config script (function handle_publish).
Presence authorization documents are described in [presence auth] and they are not fully supported now. We ignore sphere, transformations and date and time conditions. [Are there any clients supporting this?].
Example 1. presence authorization document
This document has two rules: one named “blacklist” disabling subscriptions from user “smith” and one named “whitelist” enabling subscriptions from all other users from domain “test-domain.com”. (It doesn't depend on names of rules but on actions for them.)
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <ruleset xmlns="urn:ietf:params:xml:ns:common-policy" xmlns:pr="urn:ietf:params:xml:ns:pres-rules"> <rule id="blacklist"> <conditions> <identity> <id>sip:smith@test-domain.com</id> </identity> </conditions> <actions> <pr:sub-handling>block</pr:sub-handling> </actions> <transformations/> </rule> <rule id="whitelist"> <conditions> <identity> <domain domain="test-domain.com"/> <except entity="smith"/> </identity> </conditions> <actions> <pr:sub-handling>allow</pr:sub-handling> </actions> <transformations/> </rule> </ruleset>
Authorization documents are read for presentities according to their presentity URIs (presentity URI is URI in To header of SUBSCRIBE request). Resulting XCAP URI with authorization document is:
<xcap-root>/pres-rules/users/<username>/presence-rules.xml,
where <xcap-root> is set in configuration of XCAP module and <username> is UUID (unique user identification used in SER everywhere) discovered from presentity URI.
If you need to use other filename than default “presence-rules.xml”, you can redefine it by parameter pres_rules_file. Problem can be, that pres_rules_file is specified as module parameter and thus common for all users.
Message authorization documents are described in MESSAGE authorization rules. We ignore sphere, transformations and date and time conditions like in the case of presence authorization.
Example 3. message authorization document
This document has one rule named “blacklist” disabling messages sent from users “jan@test-domain.com” and “jana@test-domain.com”.
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <ruleset xmlns="urn:ietf:params:xml:ns:common-policy" xmlns:im="urn:iptel:xml:ns:im-rules"> <rule id="blacklist"> <conditions> <identity> <id>sip:jana@test-domain.com</id> <id>sip:jan@test-domain.com</id> </identity> </conditions> <actions> <im:im-handling>block</im:im-handling> </actions> <transformations/> </rule> </ruleset>
Authorization documents are read for recipients according to To URIs. Resulting URI for XCAP query will be:
<xcap-root>/im-rules/users/<username>/im-rules.xml where <xcap-root> is set in configuration of XCAP module, im-rules.xml is default filename for message authorization rules (may be redefined in authorize_message call parameter) and <username> is UUID discovered from To URI.
One of the worst disadvantages of XCAP authorization is slowness of XCAP queries compared to - for example - data stored in local database. This is the reason for caching XCAP queries and responses, but there is a problem - how to detect changes in data stored on XCAP server. One of possible solutions is to implement client for “XCAP change notifications” described in [xcap_diff] and [xcap_profiles] (planned in future versions).
XCAP authorization support is not finished yet, there are some standard incompliances now:
ignored sphere
ignored date and time conditions
ignored transformations
Presentity URI is taken from To header field instead of AOR because AOR in consequent SUBSCRIBE requests is set to "contact to server URI" instead of user's URI (RFCs contradict themselves).
We use UUID instead of whole presentity URI as <username> due to possibility of using the same authorization document for more user's aliases (TODO: control this by module parameter?).
According to current presence authorization draft should presence server look for ALL authorization documents within user's directory on XCAP server, but listing documents on XCAP server is NOT defined. This will be partialy solved in future by possibility of having list of authorization documents as user's attributes.
Default expiration value to be used when the client doesn't supply one (in seconds). It is used for both subscriptions and publications.
Default value is 3600.
Maximal subscription expiration value in seconds.
Default value is 3600.
Maximal expiration of presence status information published via PUBLISH in seconds.
Default value is 3600.
If set to 1, PA module stores all subscription data into database and reloads them on startup. Requires db_url to be set.
Default value is 1.
Database connection URL. It has to be specified if use_db or use_offline_winfo is set.
Default value is empty.
If set to 1 callbacks to registrar/jabber will be used, if set to 0 callbacks will not be used, thus it will work only with published information.
Default value is 1.
If set to 1 PA module will accept internal subscriptions via Querry Status API otherwise not. Set this to 1 if you want RLS module to be using internal subscriptions to PA. You can't use presence B2B UA in this case!
Default value is 0.
Set this to 1 if you want to enable subscriptions to "presence.winfo" events. If set to 0, watcherinfo subscriptions are denied.
Default value is 1.
Set this to 1 if you want to use offline watcher info notifications. In such case can be watcher information stored in database and later dumped to presentity in watcher info notification, requires db_url to be set. See functions for example.
Default value is 0.
Expiration time of stored "offline watcher information" in seconds. After this time is the information removed from database.
Default value is 259200.
Number of seconds after which is triggered automatic cleanup of expired offline watcherinfo.
Default value is 3600.
This variable specifies authorization type for presence watchers (event package is “presence”). Value can be one of:
All watchers are always authorized. This is not recommended because it ignores user's wish.
All watchers are always pending. This is not recommended because it means, that no presence data is sent to all watchers.
This type of authorization means, that authorization rules are read from XCAP server and processed [presence auth]. In this case the xcap module must be loaded.
Default value is empty. In this case “implict” authorization is used with an error message.
This variable specifies authorization type for watcher info watchers (event package is “presence.winfo”). Value can be one of:
All watcher info watchers are always authorized. This is not recommended.
This value means, that presentity can subscribe to its own watcher info data and nobody else. This is done via comparing watcher's and presentity's uri. If these values equals, the subscription is allowed. In other cases is the subscription rejected.
Default value is “implict”
Name of the file with presence rules on XCAP server. The filename is by default “presence-rules.xml”. It is common for all subscriptions/users which seems to be insufficient. It will be replaced by holding this information for each user separately in user attributes (TODO).
If set to 1 the 408 response to NOTIFY is ignored, otherwise all 4xx responses including 408 destroys the subscription.
Reason for this parameter is that some clients are not able to process two NOTIFY requests received shortly in sequence and unresponded NOTIFY resulting in generated 408 response destroyed subscription created by them.
Default value is 0.
Interval in seconds when the timer runs and clears expired watchers/tuples and send NOTIFYs for changed presentities.
Priority value used for tuples created by registration in percents. Default value is 0.
Time interval specifying amount of time between re-reading of authorization documents stored on XCAP server. In other words it means the time interval of subscription reauthorization.
Default value is 300.
Set to 1 if you want to use asynchronous XCAP queries (recommended), 0 otherwise.
Default value is 0.
Maximum number of asynchronous XCAP requests done at once (within one second).
Default value is 600.
This function processes SUBSCRIBE requests to "presence" and "presence.winfo" (see watcherinfo_notify parameter) events.
Meaning of the parameters is as follows:
domain - This can be either "registrar" or "jabber".
Processes PUBLISH request and generates response to it.
This function returns 1 if the target (using get_to_uid on current message) is online, -1 otherwise.
This function returns 1 if last subscription is in status given by parameter, -1 otherwise. The status can have values:
Subscription was created but no status information will be sent to the watcher.
Subscription was established and all presence information will be sent to the watcher.
Subscription was terminated.
This function stores data about currently created subscription into database for later dumping in the form of watcherinfo notification. It should be called after handle_subscription during processing SUBSCRIBE request.
This function tries to send stored watcherinfo data in the context of existing watcherinfo subscription. It uses get_to_uid as target for notification. If there is no watcherinfo subscription to such presentity, no information is sent.
If the client responds with 2xx on generated NOTIFY request, the stored information is removed from database.
Example 7. target_online, store_winfo, dump_stored_winfo usage
... if (method=="SUBSCRIBE") { if (!t_newtran()) { sl_reply_error(); break; }; if (handle_subscription("registrar")) {; # uses uid from AVP (get_to_uid) if (@msg.event=~"presence\.winfo") { log(1, "subscription to watcherinfo\n"); dump_stored_winfo("registrar", "presence"); log(1, "OFFLINE AUTH: watcherinfo dumped\n"); } else { if ((@msg.event=~"presence") && (check_subscription_status("pending"))) { log(1, "pending subscription to presence\n"); # if offline user and new "pending" subscription if (!target_online("registrar") && (@to.tag=="")) { log(1, "OFFLINE AUTH: storing for offline user\n"); store_winfo("registrar"); } } } } break; }; ...
This function reads and processes IM authorization data and returns 1 if message can be accepted by destination user. If there is no IM authorization document on given XCAP server, it returns 1 too (MESSAGE is enabled by default). If the sender is blocked by recipient rules, this function returns -1. For more details about authorization documents see MESSAGE authorization rules.
Filename parameter specifies the name of file on XCAP server which contains message authorization rules. It is “im-rules.xml” by default.
Table holding presentities for PA module. It is basic PA table, most of other PA tables are related to this one.
Table holding <note> elements published directly in <presence> element i.e. notes related to whole presentity not only for tuples.
Table holding extension elements (non-PIDF) published directly in <presence>.
Table holding published tuples (NOT tuples generated by registrations).
Table holding information about watchers. Here are both presence and presence.winfo watchers.
Tuple related published notes.
Extension elements published within tuples.
Table used to store information about subscriptions to "offline presentities". Data here can be manipulated using functions store_winfo and dump_stored_winfo.
Table 1. Table "presentity"
name | type | size | description |
---|---|---|---|
pres_id | string | 64 | Generated presentity identifier unique across pdomains. |
uri | string | 255 | Presentity URI used when creating presentity. |
uid | string | 64 | Presentity UID (unique user identification in SER). |
pdomain | string | 128 | PA domain name. It represents separate "group" of presentities. There can be two pdomains now - named registrar and jabber. |
xcap_params | binary | XCAP parameters (in serialized form) used to obtain authorization information. Stored due to possibility to change user's XCAP parameters from script, but this is quite ineffective and it will be thrown out because XCAP parameters are mostly the same for all presentities. |
Table 2. Table "presentity_notes"
name | type | size | description |
---|---|---|---|
dbid | string | 64 | Generated ID used for unique identification. |
pres_id | string | 64 | Presentity ID for which is given note. |
etag | string | 64 | Entity tag used for note publication. |
note | string | 128 | String value of note element. |
lang | string | 64 | Lang attribute value of note element. |
expires | datetime | Expiration value of note element i.e. value of Expires header used in PUBLISH. |
Table 3. Table "presentity_extensions"
name | type | size | description |
---|---|---|---|
dbid | string | 64 | Generated ID used for unique identification. |
pres_id | string | 64 | Presentity ID for which is given extension element. |
etag | string | 64 | Entity tag used for note publication. |
element | binary | Whole extension element in serialized form. | |
expires | datetime | Expiration value of extension element i.e. value of Expires header used in PUBLISH. |
Table 4. Table "presentity_contact"
name | type | size | description |
---|---|---|---|
pres_id | string | 64 | Presentity ID. |
basic | int | 3 | Basic status as number. It can have values 0 (open) or 1 (closed). |
expires | datetime | Expiration value. | |
priority | float | Contact priority value. | |
contact | string | 255 | Published contact information. |
tupleid | string | 64 | Generated tuple identification. |
etag | string | 64 | Entity tag used for tuple publication. |
published_id | string | 64 | Tuple identification used in PUBLISH. |
Table 5. Table "watcherinfo"
name | type | size | description |
---|---|---|---|
w_uri | string | 255 | Watcher's URI (From header uri used in first SUBSCRIBE request). |
display_name | string | 128 | |
s_id | string | 64 | Generated watcher's identification. |
package | string | 32 | Watcher's event package - presence or presence.winfo. |
status | string | 32 | Watcher's status as string (pending, active, rejected, terminated or pending_terminated). |
event | string | 32 | Event which lead to watcher's status (subscribe, ...). |
expires | datetime | Subscription expiration value. | |
accepts | int | MIME type used in NOTIFYs. | |
pres_id | string | 64 | Watched presentity identification. |
server_contact | string | 255 | Contact address used for resubscriptions. |
dialog | binary | Serialized subscription dialog. | |
doc_index | int | Last index used in NOTIFY (some document formats use numbers incremented in each NOTIFY). |
Table 6. Table "tuple_notes"
name | type | size | description |
---|---|---|---|
pres_id | string | 64 | Presentity ID. |
tupleid | string | 64 | Tuple identification. |
note | string | 128 | Note text. |
lang | string | 64 | Note language (possible note element attribute). |
Table 7. Table "tuple_extensions"
name | type | size | description |
---|---|---|---|
pres_id | string | 64 | Presentity ID. |
tupleid | string | 64 | Tuple identification. |
element | binary | Whole extension element in serialized form. | |
status_extension | int | 1 | Flag set to nonzero if element is nested in <status>, otherwise is extension element nested in <tuple>. |
Table 8. Table "offline_winfo"
name | type | size | description |
---|---|---|---|
uid | string | 64 | UID of presentity. |
watcher | string | 255 | Watcher's URI. |
events | string | 64 | Subscription event header (presence). |
domain | string | 128 | Presence domain (registrar or jabber). |
status | string | 32 | Subscription status. |
created_on | datetime | Time of row creation used to discard expired rows. Row expires when its creation time is older than configured value. | |
expires_on | datetime | Time when row expires. | |
dbid | unsigned int | 10 | Auto-generated key. |
There might be new versions of internet drafts and thus links to them my be obsolete. In such case try increment version in link or find the draft on IETF by name.
[xcap] draft-ietf-simple-xcap-07.txt - XCAP specification.
[xcap_diff] draft-ietf-simple-xcap-diff-01.txt - XCAP changes notifications format.
[xcap_profiles] draft-ietf-sipping-config-framework-07.txt -XCAP user profiles.
[events] RFC 3265 - SIP Events.
[presence] RFC 3856 - Presence Event package.
[publish] RFC 3903 - Event state publication.
[winfo_doc] RFC 3858 - Data Format for watcher info.
[reg] RFC 3680 - SIP Reg Events.
[common auth] draft-ietf-geopriv-common-policy-05.txt.
[presence auth] draft-ietf-simple-presence-rules-03.txt - presence authorization XML based data format and usage with XCAP.
[rls] draft-ietf-simple-xcap-list-usage-05.txt - XML formats for representing resource lists.
[sip rls] draft-ietf-simple-event-list-07.txt - Event Notification Extension for Resource Lists.