Page MenuHomePhabricator

MSRP Chat Software Initial Design
Updated 3,030 Days AgoPublic

Introduction

MSRP-Components.png (462×376 px, 40 KB)

This page describes the design for a baseline MSRP chat server supporting chat sessions between several SIP/MSRP endpoints, to be integrated with the OpenSER SIP Proxy.

Normative references

Relation to RFC 4579

MSRP Conference server implements following sections from "RFC 4579":http://www.faqs.org/rfcs/rfc4579.html

  • 5.1. INVITE: Joining a Conference Using the Conference URI - Dial-In
  • 5.11. REFER with BYE: Requesting That the Focus Remove a Participant from a Conference
  • 5.13. Discovery of URI Properties Using OPTIONS

Also a variant of scenario described in RFC:

  • 5.2. INVITE: Adding a Participant by the Focus - Dial-Out

Additional users listed in a the resource-list attached to the INVITE are invited to the conference by letting the focus send a REFER to the end-points. This scenario aims to implement the same functionality while passing the responsibility of sending out the INVITE and management of the dialogs to the end-points, this allows the server to scale better while preserving the control of the conference, and most importantly an be implemented in OpenSER without the need of a complex B2BUA.

Relation to draft-ietf-simple-chat-02

MSRP Conference Server implements following sections of draft-ietf-simple-chat-02

  • 5.2. Joining a Chat Room
  • 6.2. Private Messages

Sections of the draft related to creating/deleting conferences

  • 5.1. Creating a Chat Room
  • 5.3. Deleting a Chat Room

are implemented in a slightly different way, by using ad-hoc conferences.

There are two types of conferences in MSRP Conference Server:

  • static conference - pre-provisioned in the server by administrative interface
  • ad-hoc conference - created on the fly by participants

Static conferences are created via special management interface (not part of SIP/MSRP). Ad-hoc conferences are created on-the-fly, when the first user joins a particular SIP URI. A static conference cannot be deleted by SIP/MSRP means. An ad-hoc conference is removed when the last participant exits.

Following sections of the draft related to private messages and nicknames aren't covered yet by this document:

  • 6.1. Regular Messages
  • 7. Nicknames

Design overview

There are multiple entities working together to implement the functionality:

msrp-conference-focus

An OpenSER module that:

  • provides the conference handling logic
  • handles incoming INVITE/BYE/CANCEL for join and leave to a conference
  • handles BYE/CANCEL to terminate or cancel a session
  • sends 200 OK or other specific negative codes
  • answer to OPTIONS for discovery whether a SIP URI is a conference focus
  • publishes conference-info to the presence-msrp-conference

msrp-conference-focus doesn't hold conference state, but requests it from msrp-conference-server (via msrp-conference-dispatcher)

presence-msrp-conference

An OpenSER presence module that:

  • handles SUBSCRIBE from SIP UAs
  • sends NOTIFYs to SIP UAs
  • handles PUBLISH from msrp-conference-focus (for the full conference state)
  • handles PUBLISH from properly authorized SIP UAs (some parts of state, like conference title)
  • check policy in pres-rules XCAP document managed by msrp-conference-focus

This module maintains a dialog with every subscriber, but it's a different dialog than the one started by INVITE.

msrp-conference-server

A standalone server that:

  • handles MSRP connections
  • mixes media to multiple partipants
  • maintains the conference state
  • is controlled by msrp-conference-focus
  • manages XCAP policy for the conference URI
  • generates and sends to focus conference-info

msrp-conference-dispatcher

A stand alone component collocated with msrp-conference-focus:

  • keeps track of msrp-conference-server used for each sessions
  • establishes TLS communications with msrp-conference-server
  • listens for incoming notifications from msrp-conference-server
  • informs msrp-conference-focus about dropped connections so that it can notify recipients

Communication between msrp-conference-focus and msrp-conference-server

msrp-conference-server needs the following information about incoming INVITE

from SIP:

  • Request-URI, "sip:conf1@conf.ag-projects.com" to know which room the user is being added to;
  • From, to introduce the user to other participants;
  • dialog info (From, To, Call-ID, CSeq) to supply it back to msrp-conference-focus when someone is needed to be kicked out.

from SDP:

  • a=accept-types:text/plain, to negotiate about message format;
  • a=path:msrp://alicepc.example.com:7777/iau39soe2843z;tcp, to authentificate incoming msrp messages as belonging to this user.

Other fields may be needed in the future, we could send the whole request (SIP+SDP) to msrp-conference-server unchanged, although msrp-conference-server will look only for fields it understands.

msrp-conference-server responds with

  • status - whether joining to (or creation of) conference was successful in "123 Text" format
  • dialog-related fields of SIP request
  • full SDP response with, among other things,
    • ip:port of the msrp-conference-server
    • msrp uri of the msrp-conference-server
    • accept-types supported by msrp-conference-server and user

msrp-conference-server responds with SIP-like request, which is merged into SIP header generated by openser. SDP part of server's response is sent as is without intervention of msrp-conference-focus. BYE and REFER from client are treated the same way.

msrp-conference-server may [on behalf of authorized human] generate BYE using dialog info it has saved from INVITE.

Communication between presence-msrp-conference and msrp-conference-server

When the conference state changed in msrp-conference-server (user added/removed), msrp-conference-server [re]generates conference-info xml (format described in RFC 4575) and sends it [publishes] to presence-msrp-conference module. When openser is restarted, msrp-conference-server resends that info.

Authentification and authorization

Authentification and Autorization is done by an upstream OpenSER Proxy server. Authorization related to conference functionality may be also performed by the msrp-conference-focus.

SIP join/leave

Before responding to the request, msrp-conference-focus consults its policy:

  • on INVITE
    • if the the room is statically defined
    • whether user is allowed to join
    • whether user is allowed to create a conference (when there isn't one)
  • on REFER - whether this user can kick others out
  • on BYE/CANCEL - whether user can leave

MSRP Media

The MSRP URI is considered a shared secret, so no additional auth is done on msrp connections.

Presence

To decide who can SUBSCRIBE to the conference-info Event package, presence-msrp-conference checks XCAP/presence-rules for the given conference SIP URI. For newly created ad-hoc conferences, focus creates a new record in the xcap table (typically with allow-all policy). When the conference is destroyed, focus removes the record from the table.

Workflows

Following scenarios are described in details:

  • INVITE: Joining a conference
  • INVITE: Creating a conference
  • REFER with BYE: Requesting that the focus temove a participant from a conference

Alice is a client that implements SIP/MSRP. It has obtained by external means the SIP URI of a conference focus.

INVITE: Joining a conference

This example is based on

To join a conference, Alice sends INVITE to Conference URI.

  1. Alice -> msrp-conference-focus [SIP]
INVITE sip:conf1@conf.ag-projects.com
From: sip:alice@home.com;tag=887s       # From, To, Call-ID and CSeq
To: sip:conf1@conf.ag-projects.com      # are dialog-related headers
Call-ID: 2366721e-b06febec@home.com     # required for sending BYE later
CSeq: 101 INVITE                        #
..other SIP not shown..

a=accept-types:text/plain
a=path:msrp://alicepc.example.com:7777/iau39soe2843z;tcp # (1)
..other SDP not shown..
  1. msrp-conference-focus forwards the request to msrp-conference-server [SIP-like data over socket]

msrp-conference-server then

  • creates a conference if necessary
  • creates a user and adds her to the conference [with state=expected]
  • attaches dialog info to the user
  • generates SDP answer

Switch generates a response, supplying saved dialog state (From, To, Call-ID and CSeq) and SDP answer.

  1. msrp-conference-server -> msrp-conference-focus [SIP-like data over socket]
200 OK
From: sip:conf1@conf.ag-projects.com;tag=123x    # tag appended by msrp-conference-server
To: sip:alice@home.com;tag=887s
Call-ID: 2366721e-b06febec@home.com
CSeq: 101 INVITE
Contact: sip:conf1@conf.ag-projects.com;isfocus  # "isfocus" appended my msrp-conference-server

a=accept-types:text/plain                                       # SDP offer
a=path:msrp://msrp.ag-projects.com:8888/9di4eae923wzd;tcp # (2) # generated
..other SDP not shown..                                         # by msrp-conference-server

Other SDP fields are not shown, but they're also provided by msrp-conference-server. SIP headers are shown fully, everything else is added by msrp-conference-focus itself.

Focus generates a proper SIP response and sends it to Alice.

  1. msrp-conference-focus -> Alice [SIP]
200 OK
From: sip:conf1@conf.ag-projects.com;tag=123x
To: sip:alice@home.com;tag=887s
Call-ID: 2366721e-b06febec@home.com
CSeq: 101 INVITE
..other SIP not shown..
  
a=accept-types:text/plain
a=path:msrp://msrp.ag-projects.com:8888/9di4eae923wzd;tcp # (2)
..other SDP not shown..
  1. alice -> msrp-conference-focus [SIP]
ACK

msrp-conference-focus forwards the message to msrp-conference-server

  1. msrp-conference-focus -> msrp-conference-server [SIP-like]
  • msrp-conference-server updates user state to 'joined'
  • msrp-conference-server updates and sends conference-info to msrp-conference-focus
  • msrp-conference-focus sends PUBLISH which arrives to presence-msrp-conference
  • if no ACK arrives after 5 seconds the session is dropped
  1. alice -> msrp-conference-server [MSRP]
MSRP d93kswow SEND
To-Path: path:msrp://msrp.ag-projects.com:8888/9di4eae923wzd;tcp # (2)
From-Path: msrp://alicepc.example.com:7777/iau39soe2843z;tcp     # (1)
Message-ID: 12339sdqwer
Byte-Range: 1-16/16
Content-Type: text/plain

Hi, I'm Alice!
-------d93kswow$
  1. msrp-conference-server -> alice [MSRP]
MSRP d93kswow 200 OK
To-Path: ...
From-Path: ...
-------d93kswow$
  1. msrp-conference-server -> bob [MSRP] (bob is also in the same conference)
MSRP dkei38sd SEND
To-Path: ...
From-Path: path:msrp://msrp.ag-projects.com:8888/9di4eae923wzd;tcp

alice@home.com: Hi, I'm Alice!
-------dkei38sd$

INVITE: Creating an ad-hoc conference

From user perspective, creating an ad-hoc conference may be no different from simply joining an existing conference.
However, INVITE that creates a conference may contain _resource-list_. Focus will examine _resource-list_ and send REFER to each user referenced.

Following workflow is adapted from Section 6 of draft-ietf-sip-uri-list-conferencing-02. It's different though as instead of sending INVITE it sends REFER to referenced users. This is because in our design focus is just an openser module and not a fully fledged SIP endpoint, so sending INVITE would be difficult.

Alice requests Focus to create a conference. In addition to the usual SDP offer she puts _resource-list_ in the request.

  1. Alice -> msrp-conference-focus [SIP]
INVITE sip:conf1@conf.ag-projects.com SIP/2.0
To: sip:conf1@conf.ag-projects.com
From: sip:alice@home.com;tag=32331
Call-ID: d432fa84b4c76e66710@home.com
CSeq: 1 INVITE
Accept: application/sdp, message/sipfrag
Require: recipient-list-invite
Content-Type: multipart/mixed;boundary="boundary1"
Content-Length: ...

--boundary1
Content-Type: application/sdp

..SDP is as usual..

--boundary1
Content-Type: application/resource-lists+xml
Content-Disposition: recipient-list

<?xml version="1.0" encoding="UTF-8"?>
<resource-lists xmlns="urn:ietf:params:xml:ns:resource-lists">
  <list>
    <entry uri="sip:bob@example.com"/>
  </list>
</resource-lists>
--boundary1--

Focus exchanges data with the server and then responds with "200 OK" just like in the previous example.
When ACK is received from Alice, it is forwarded to server. server responds with list of REFERs focus needs to send.
Since, in Alice's INVITE there's only one entry, only one REFER will be sent.

  1. focus -> Bob
REFER sip:bob@example.com SIP/2.0
To: sip:bob@example.com
From: sip:conf1@conf.ag-projects.com
Refer-To: sip:conf1@conf.ag-projects.com

When REFER is received by Bob's client, it should display an invitation where Bob can choose to accept the invitation.
If he decides to join, his client will send INVITE to focus URI.

REFER with BYE: Requesting That the Focus Remove a Participant from a Conference

For undisclosed reasons Bob decides to drop Alice from the conference. Since Bob is authorized as owner of the conference, he can use REFER with BYE method as described in section 5.11 of RFC 4579.

  1. Bob -> focus
REFER sip:conf1@conf.ag-projects.com SIP/2.0
Refer-To: <sip:alice@home.com;method=BYE>
  1. focus -> server

focus forwards the message to server, which changes alice's state to 'dropped' (won't accept messages from her anymore) and generates BYE using dialog-related info.

  1. server -> focus [SIP-like]
BYE ...
From: sip:conf1@conf.ag-projects.com;tag=123x
To: sip:alice@home.com;tag=887s
Call-ID:  2366721e-b06febec@home.com
CSeq: 102 BYE
  1. focus -> alice [SIP]

msrp-conference-focus makes real SIP message from the one above (by adding other required fields) and sends it to alice.

  1. alice -> msrp-conference-focus [SIP]
200 OK

Issues

  • handling dialogs outside of openser - doable?
  • Is _resource-list_ allowed in a non-creating INVITE? I think it should be, especially considering that user may not know if he creating an ad-hoc conference or joining an existing one.
Last Author
tijmen
Last Edited
Aug 18 2016, 1:29 PM