Network Working Group | P. Saint-Andre |
Internet-Draft | Cisco Systems, Inc. |
Intended status: Standards Track | S. Ibarra |
Expires: January 03, 2014 | AG Projects |
S. Loreto | |
Ericsson | |
July 02, 2013 |
Interworking between the Session Initiation Protocol (SIP) and the Extensible Messaging and Presence Protocol (XMPP): Groupchat
draft-ietf-stox-groupchat-00
This document defines a bidirectional protocol mapping for the exchange of instant messages in the context of a multiparty chat session among users of the Session Initiation Protocol (SIP) and users of the Extensible Messaging and Presence Protocol (XMPP). Specifically, this document defines a mapping between the SIP-based Message Session Relay Protocol (MSRP) and the XMPP Multi-User Chat (MUC) extension.
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."
This Internet-Draft will expire on January 03, 2014.
Copyright (c) 2013 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
Both the Session Initiation Protocol (SIP) [RFC3261] and the Extensible Messaging and Presence Protocol (XMPP) [RFC6120] can be used for the purpose of multiparty text chat over the Internet. To ensure interworking between these technologies, it is important to define bidirectional protocol mappings.
The architectural assumptions underlying such protocol mappings are provided in [I-D.ietf-stox-core], including mapping of addresses and error conditions. This document specifies mappings for multiparty text chat sessions (often called "groupchat"); specifically, this document defines a mapping between the XMPP Multi-User Chat (MUC) extension [XEP-0045] and SIP-based multiparty chat using Message Session Relay Protocol [RFC4975] as specified in [I-D.ietf-simple-chat].
Both MUC and MSRP contain a large set of features, such as the ability to administer rooms, kick and ban users, reserve a nickname within a room, change room subject, enable room moderation, and destroy the room. This document covers only a basic subset of groupchat features: joining the room, establishing or changing a room nickname, inviting another user to the room, modifying presence information within the room, sending a message to all participants, sending a private message to a single participant, and leaving the room. Future documents might define mappings for additional features beyond this set.
The discussion venue for this document is the mailing list of the STOX WG; visit https://www.ietf.org/mailman/listinfo/stox for subscription information and discussion archives.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].
A number of technical terms used here are defined in [RFC3261], [RFC4975], [RFC6120], and [XEP-0045]. The term "JID" is short for "Jabber Identifier".
This section describes how to map an XMPP MUC session to an MSRP Multi-party Messaging session. The following diagram outlines the overall protocol flow.
XMPP User Gateway MSRP Conference | | | |(F1) (XMPP) Enter room | | |------------------------->| | | |(F2) (SIP) INVITE | | |------------------------->| | |(F3) (SIP) 200 OK | | |<-------------------------| | |(F4) (SIP) ACK | | |------------------------->| | |(F5) (MSRP) NICKNAME | | |------------------------->| | |(F6) (MSRP) 200 OK | | |<-------------------------| | |(F7) (SIP)SUBSCRIBE | | |------------------------->| | | Event:conference | | | | | |(F8) (SIP) 200 OK | | |<-------------------------| | |(F9) (SIP) NOTIFY | | |<-------------------------| | |(F10) (SIP) 200 OK | | |------------------------->| |(F11) (XMPP) Presence | | |<-------------------------| | |(F12) (XMPP) Subject | | |<-------------------------| | | | | |(F13) (XMPP) Chat message | | |------------------------->| | | |(F14) (MSRP) SEND | | |------------------------->| | |(F15) (MSRP) 200 OK | | |<-------------------------| | | | |(F16) (XMPP) Chat message | | |<-------------------------| | . . . . . . |(F17) (XMPP) Exit room | | |------------------------->| | | |(F18) (SIP) BYE | | |------------------------->| | |(F19) (SIP) 200 OK | | |<-------------------------|
Detailed protocol flows and mappings are provided in the following sections.
As defined in the XMPP Multi-User Chat (MUC) extensions [XEP-0045], when an XMPP user (say, juliet@example.com) wants to join a groupchat room (say, "verona@chat.example.org"), she sends a <presence/> stanza to that chat room. In her request she also specifies the nickname she wants to use within the room (say, "JuliC"); in XMPP this Room Nickname is the resourcepart of an Occupant JID (thus "verona@chat.example.org/JuliC"). The joining client signals its ability to speak the multi-user chat protocol by including in the initial presence stanza an empty <x/> element qualified by the 'http://jabber.org/protocol/muc' namespace.
Example: (F1) Juliet enters room
<presence from='juliet@example.com/balcony' to='verona@chat.example.org/JuliC'> <x xmlns='http='http://jabber.org/protocol/muc'/> </presence>
Upon receiving such a presence stanza, the XMPP server to which Juliet has authenticated attempts to (a) deliver the stanza to a local domain or (b) route the presence stanza to the remote domain that services the hostname in the 'to' attribute. In this document we assume that the hostname in the 'to' attribute is a groupchat-aware SIP/MSRP service hosted by a separate server.
As specified in [RFC6121], the XMPP server needs to determine the identity of the remote domain, which it does by performing one or more DNS SRV lookups [RFC2782]. For presence stanzas, the order of lookups recommended by [RFC6121] is to first try the "_xmpp-server" service as specified in [RFC6120] and to then try the "_pres" service as specified in [RFC3861]. Here we assume that the first lookup will fail but that the second lookup will succeed and return a resolution "_pres._s2x.example.org", since we have already assumed that the example.org hostname is running a SIP instant messaging service. (Note: The XMPP server might have previously determined that the remote domain is a SIMPLE server, in which case it would not need to perform the SRV lookups; the caching of such information is a matter of implementation and local service policy, and is therefore out of scope for this document.)
Once the XMPP server (example.com) has determined that the remote domain is serviced by a SIMPLE server, it hands the XMPP presence stanza off to its local XMPP-to-SIP gateway code (this might be a specialized connection manager within the example.com service or might be a dedicated component at, say, x2s.example.com), which transforms the presence stanza into SIP syntax and routes it to the remote conference server (chat.example.org).
Because a multi-user chat service accepts the presence stanza shown above as a request to enter a room, the XMPP-to-SIP gateway transforms it in a SIP INVITE request.
Example: (F2) Juliet enters room (SIP conversion)
INVITE sip:verona@chat.example.org SIP/2.0 To: <sip:verona@chat.example.org> From: "Juliet" <sip:juliet@example.com> Contact: <sip:juliet@example.com>;gr=balcony Call-ID: 711609sa Content-Type: application/sdp Content-Length: [length] c=IN IP4 x2s.example.org m=message 7654 TCP/MSRP * a=accept-types:text/cpim a=accept-wrapped-types:text/plain text/html a=path:msrp://x2s.example.com:7654/jshA7weztas;tcp a=chatroom
Here the Session Description Protocol offer specifies the MSRP-aware XMPP-to-SIP gateway on the XMPP side as well as other particulars of the session.
As specified in [I-D.ietf-stox-core], the mapping of XMPP syntax elements to SIP and [RFC4566] syntax elements is as shown in the following table.
Table 1: Message syntax mapping from XMPP to SIP/SDP
+-----------------------------+-----------------------------+ | XMPP Element or Attribute | SIP Header or SDP Contents | +-----------------------------+-----------------------------+ | from | From | | to (without the /nick) | To | +-----------------------------+-----------------------------+
Here we assume that the MSRP conference server accepts the session establishment. It includes the 'isfocus' and other relevant feature tags in the Contact header field of the response. The MSRP confernece server also includes an answer session description that acknowledges the choice of media and contains the extensions specified in [I-D.ietf-simple-chat].
Example: (F3) Chat room accepts session establishment
SIP/2.0 200 OK From: <sip:verona@chat.example.org> To: "Juliet" <sip:juliet@example.com>;tag=786 Call-ID: 711609sa Contact: <sip:verona@chat.example.org;transport=tcp>\ ;methods="INVITE,BYE,OPTIONS,ACK,CANCEL,SUBSCRIBE,NOTIFY"\ ;automata;isfocus;message;event="conference" Content-Type: application/sdp Content-Length: [length] c=IN IP4 example.org m=message 12763 TCP/MSRP * a=chatroom:nickname private-messages a=accept-types:message/cpim a=accept-wrapped-types:text/plain text/html * a=path:msrp://s2x.example.org:12763/kjhd37s2s20w2a;tcp
Upon receiving such a response, the SIMPLE server or associated SIP-to-XMPP gateway sends a SIP ACK to the MSRP conference server on behalf of the joining user.
Example: (F4) Gateway sends ACK to MSRP conference server
ACK sip:verona@chat.example.org SIP/2.0 To: <sip:verona@chat.example.org>;tag=087js From: "Juliet" <sip:juliet@example.com>;tag=786 Call-ID: 711609sa
If the chat room server accepted the session, the SIMPLE server or associated SIP-to-XMPP gateway MUST set up the nickname as received in the presence stanza (i.e., the resourcepart of the 'to' address, such "JuliC" in "verona@chat.example.org/JuliC"). The nickname is set up using the extension specified in [I-D.ietf-simple-chat].
Example: (F5) Gateway sets up nickname
MSRP a786hjs2 NICKNAME To-Path: msrp://s2x.example.org:12763/kjhd37s2s20w2a;tcp From-Path: msrp://x2s.example.com:7654/jshA7weztas;tcp Use-Nickname: "JuliC" -------a786hjs2
The MSRP conference server analyzes the existing allocation of nicknames, accepts the nickname proposal and answers with a 200 response.
Example: (F6) MSRP conference accepts nickname proposal
MSRP a786hjs2 200 OK To-Path: msrp://x2s.example.com:7654/jshA7weztas;tcp From-Path: msrp://s2x.example.org:12763/kjhd37s2s20w2a;tcp -------a786hjs2
So far we have assumed that the requested nickname did not conflict with any existing nicknames. The following text describes the handling of a nickname conflict.
MSRP conference XMPP User Gateway server | | | |(F1) (XMPP) Enter room | | |------------------------->| | | |(F2) (SIP) INVITE | | |------------------------->| | |(F3) (SIP) 200 OK | | |<-------------------------| | |(F4) (SIP) ACK | | |------------------------->| | |(F5) (MSRP) NICKNAME | | |------------------------->| | |(F6) (MSRP) 425 Error | | |<-------------------------| | | | |(F7) (XMPP) Presence Error |<-------------------------| | . . . | |(F8) (SIP) BYE | | |------------------------->| | |(F9) (SIP) 200 OK | | |<-------------------------|
The MSRP conference server analyzes the existing allocation of nicknames, and detects that the nickname proposal is already provided to another participant. In this case the MSRP conference server answers with a 425 response.
Example: (F6) MSRP conference does not accept nickname proposal
MSRP a786hjs2 425 Nickname usage failed To-Path: msrp://x2s.example.com:7654/jshA7weztas;tcp From-Path: msrp://s2x.example.org:12763/kjhd37s2s20w2a;tcp -------a786hjs2
Upon receiving such a response, the SIP-to-XMPP gateway SHOULD translate it into an XMPP presence stanza of type "error" specifying a <conflict/> error condition (which implies that the XMPP client will then need to choose another nickname and repeat the process of joining).
Example: (F7) Conflict error for nickname
<presence from='verona@chat.example.org' to='juliet@example.com/balcony' type='error'> <x xmlns='http='http://jabber.org/protocol/muc'/> <error type='cancel'> <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
Alternatively, the gateway might generate a new nickname request on behalf of the XMPP user, thus shielding the XMPP client from handling the conflict error.
The XMPP user might want to change her nickname. She can do so by sending an updated presence stanza to the room, containing a new nickname.
MSRP conference XMPP User Gateway server | | | |(F1) (XMPP) Presence to change Nickname | |------------------------->| | | |(F2) (MSRP) NICKNAME | | |------------------------->| | |(F3) (MSRP) 200 OK | | |<-------------------------|
Example: (F1) Juliet changes her nickname
<presence from='juliet@example.com/balcony' to='verona@chat.example.org/Juliet'/>
The nickname change is handled as described above.
In XMPP there are two methods for inviting another user to a room: direct invitations [XEP-0249] (sent directly from the user's real JID outside the room to the invitee's real JID) and mediated invitations (sent through the room from the user's Occupant JID to the invitee's JID). In this document we cover mediated invitations only.
XMPP User Gateway MSRP Conference | | | |(F1) (XMPP) Message stanza to invite participant | |------------------------->| | | |(F2) (SIP) REFER | | |------------------------->| | |(F3) (SIP) 200 OK | | |<-------------------------| . . . | |(F4) (SIP) NOTIFY | | |<-------------------------|
For example, if Juliet decides to invite Benvolio to the room, she sends a message stanza with an invite and Benvolio's JID (which could be his real JID or an Occupant JID in another room).
Example: (F1) Juliet invites Hecate to the room
<message from='juliet@example.com/balcony' id='nzd143v8' to='verona@chat.example.org'> <x xmlns='http://jabber.org/protocol/muc#user'> <invite to='benvolio@example.com'/> </x> </message>
The SIP - XMPP gateway then sends a SIP REFER request to the MSRP conference server indicating who needs to be invited in the Refer-To header, as per [RFC4579] (sec 5.5)
Example: (F2) SIP translation of invite
REFER sip:verona@chat.example.com SIP/2.0 Via: SIP/2.0/UDP client.example.com;branch=z9hG4bKg4534 Max-Forwards: 70 To: <sip:verona@chat.example.com> From: "Juliet" <sip:juliet@example.com>;tag=5534562 Call-ID: 849392fklgl43 CSeq: 476 REFER Contact: <sip:juliet@juliet.example.com> Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Accept: message/sipfrag Refer-To: <sip:benvolio@example.com> Supported: replaces Content-Length: 0
The progress of the invitation will be tracked by the reeived NOTIFY requests as per [RFC3515].
Example: (F4) Progress notification for invitation
NOTIFY sip:juliet@example.com SIP/2.0 Via: SIP/2.0/UDP client.example.com;branch=z9hG4bK9922ef992-25 To: <sip:juliet@example.com>;tag=5534562 From: <sip:verona@chat.example.com>;tag=18747389 Call-ID: 849392fklgl43 CSeq: 1993402 NOTIFY Max-Forwards: 70 Event: refer Subscription-State: active;expires=60 Contact: sip:verona@chat.example.com Content-Type: message/sipfrag;version=2.0 Content-Length: ... SIP/2.0 200 OK
If the MSRP conference service accepts the request to enter a room, the XMPP user expects to receive back presence information from all the existing occupants of the room. So the XMPP-to-SIP gateway MUST subscribe to the Conference Event package [RFC4575] on the MSRP conference server. When the subscription is completed the MSRP conference server sends to the XMPP-to-SIP gateway a NOTIFY containing the presence information of all the existing occupants, represented using the [RFC4575] format.
Example: (F9) MSRP conference sends presence information
NOTIFY sip:verona@chat.example.org SIP/2.0 To: "Juliet" <sip:juliet@example.com>;gr=balcony From: <sip:verona@chat.example.org>;tag=a3343df32 Call-ID: k3l43id034ksereree Event: conference Subscription-State: active;expires=3600 Content-Type: application/conference-info+xml Content-Length: ... <conference-info version="0" state="full" entity="sip:3402934234@chat.example.org"> <conference-description> <subject>Today in Verona</subject> <conf-uris> <entry> <uri>tel:+18882934234</uri> </entry> </conf-uris> </conference-description> <users> <user entity="sip:verona@chat.example.org;gr=Romeo" state="full"> <display-text>Romeo</display-text> <roles> <entry>participant</entry> </roles> </user> <user entity="sip:verona@chat.example.org;gr=Ben" state="full"> <display-text>Ben</display-text> <roles> <entry>participant</entry> </roles> </user> </users> </conference-info>
The following table shows the syntax mapping from the RFC 4575 payload to the XMPP participants list. (Mappings for elements not mentioned are undefined.)
Table 2: Participant list mapping
+--------------------------------+-----------------------------+ | RFC 4575 Element | XMPP Element or Attribute | +--------------------------------+-----------------------------+ | conference-info entity | room JID | | conference subject | room subject | | user entity | participant bare JID | | user display-text / nickname | participant nickname | | endpoint entity | participant full JID | +--------------------------------+-----------------------------+
Upon receiving such a response, the SIP-to-XMPP gateway MUST send a 200 OK to the MSRP conference server and translate the participant list into a series of XMPP presence stanzas.
Example: (F11) Chatroom presence information translated into XMPP
<presence from='verona@chat.example.org/Romeo' to='verona@chat.example.org/JuliC'> <x xmlns='http://jabber.org/protocol/muc#user'> <item affiliation='none' role='participant'/> </x> </presence> <presence from='verona@chat.example.org/Ben' to='verona@chat.example.org/JuliC'> <x xmlns='http://jabber.org/protocol/muc#user'> <item affiliation='none' role='participant'/> </x> </presence>
If the NOTIFY included a subject, the gateway SHALL convert it into a separate XMPP message.
Example: (F12) Chatroom subject translated into XMPP
<message from='verona@chat.example.com/mayor' to='juliet@example.com/balcony' id='mbh2vd68'> <subject>Today in Verona</subject> </message>
The mapping of SIP and [RFC4575] payload syntax elements to XMPP syntax elements is as shown in the following table. (Mappings for elements not mentioned are undefined.)
Table 2: Message syntax mapping from SIP to XMPP
+---------------------------------+-----------------------------+ | SIP Header or RFC4575 Contents | XMPP Element or Attribute | +---------------------------------+-----------------------------+ | <user entity=...> | From | | To + / <display-text> | To | | roles | role | | 'none' | affiliation | +---------------------------------+-----------------------------+
Once the user has joined the chatroom, the user can exchange an unbounded number of messages both public and private.
The mapping of XMPP syntax elements to MSRP syntax elements is as shown in the following table. (Mappings for elements not mentioned are undefined.)
Table 3: Message syntax mapping from XMPP Message to MSRP
+-----------------------------+-----------------------------+ | XMPP Element or Attribute | CPIM Header | +-----------------------------+-----------------------------+ | to | To | | from | From | | <body/> | body of the SEND request | +-----------------------------+-----------------------------+
When Juliet wants to sends a message to all other occupants in the room, she sends a message of type "groupchat" to the <room@service> itself (in our example, <verona@chat.example.org>).
The following examples show an exchange of a public message.
Example: (F13) Juliet sends message to all occupants
<message from='juliet@example.com/balcony' to='verona@chat.example.org' type='groupchat' id='lzfed24s'> <body>Who knows where Romeo is?</body> </message>
Upon receiving such a message, the XMPP-to-SIP gateway MUST translate it into an MSRP SEND message.
Example: (F14) Gateway transforms XMPP message to MSRP
MSRP a786hjs2 SEND To-Path: msrp://s2x.example.org:12763/kjhd37s2s20w2a;tcp From-Path: msrp://x2s.example.com:7654/jshA7weztas;tcp Message-ID: 87652491 Byte-Range: 1-*/* Content-Type: message/cpim To: <sip:verona@chat.example.org> From: "Juliet" <sip:juliet@example.com> DateTime: 2008-10-15T15:02:31-03:00 Content-Type: text/plain Who knows where Romeo is? -------a786hjs2$
Upon receiving the SEND request, if the request either contains a Failure-Report header field value of "yes" or does not contain a Failure-Report header at all, the MSRP conference server MUST immediately generate and send a response.
MSRP d93kswow 200 OK To-Path: msrp://x2s.example.com:7654/jshA7weztas;tcp From-Path: msrp://s2x.example.org:12763/kjhd37s2s20w2a;tcp -------d93kswow$
Since an XMPP MUC room could be moderated and an XMPP user cannot be sure whether her message has been accepted or not without receiving it back from the server, [XEP-0045] states that the sender needs to receive the same message it has generated. So in this scenario the XMPP-to-SIP gateway has to reflect the message back to the sender. This prodedure only applies to XMPP endpoints.
Since each occupant has a unique JID, Juliet can send a "private message" to a selected occupant through the service by sending a message to the user's occupant JID. The XMPP message type SHOULD be "chat" and MUST NOT be "groupchat", but MAY be left unspecified.
If the XMPP-to-SIP gateway has support for private messaging it MUST advertise that fact by adding a "private-messages" value to the a=chatroom SDP attribute it sends to the MSRP conference server, as specified in [I-D.ietf-simple-chat].
a=chatroom:nickname private-messages
The following examples show an exchange of a private message.
Example: Juliet sends private message
<message from='juliet@example.com/balcony' to='verona@chat.example.org/Romeo' type='chat' id='6sfln45q'/> <body>O Romeo, Romeo! wherefore art thou Romeo?</body> </message>
Upon receiving such a message, the XMPP-to-SIP gateway MUST translate it into an MSRP SEND message.
Example: Gateway transforms private message from XMPP to MSRP
MSRP a786hjs2 SEND To-Path: msrp://s2x.example.org:12763/kjhd37s2s20w2a;tcp From-Path: msrp://x2s.example.com:7654/jshA7weztas;tcp Message-ID: 87652491 Byte-Range: 1-*/* Content-Type: message/cpim To: <sip:verona@chat.example.org>;gr=Romeo From: <sip:juliet@example.org>;gr=balcony DateTime: 2008-10-15T15:02:31-03:00 Content-Type: text/plain O Romeo, Romeo! wherefore art thou Romeo? -------a786hjs2$
The MSRP conference server is responsible for sending the message to the intended recipient, and when doing so MUST modify the "From" header to the sender's address within the chatroom.
Example: MSRP conference sends private message to SIP user
MSRP a786hjs2 SEND To-Path: msrp://s2x.example.org:12763/kjhd37s2s20w2a;tcp From-Path: msrp://x2s.example.com:7654/jshA7weztas;tcp Message-ID: 87652491 Byte-Range: 1-*/* Content-Type: message/cpim To: <sip:romeo@example.com> From: <sip:verona@chat.example.com>;gr=JuliC DateTime: 2008-10-15T15:02:31-03:00 Content-Type: text/plain O Romeo, Romeo! wherefore art thou Romeo? -------a786hjs2$
If Juliet decides to exit the chatroom, her client sends a presence stanza of type "unavailable" to the occupant JID she is currently using in the room (here <verona@chat.example.org/JuliC>).
Example: (F17) Juliet exits room
<presence from='juliet@example.com/balcony' to='verona@chat.example.org/JuliC' type='unavailable'/>
Upon receiving such a stanza, the XMPP-to-SIP gateway terminates the SIP session by sending a SIP BYE to the MSRP conference server. The MSRP conference server then responds with a 200 OK.
Juliet MAY include a custom exit message in the presence stanza of type "unavailable", in which case it SHOULD be broadcasted to other participants using the methods described above.
Example: (F17) Juliet exits the chatroom
<presence from='juliet@example.com/balcony' to='verona@chat.example.org/JuliC' type='unavailable'> <status>Time to go!</status> </presence>
This section describes how to map a Multi-party Instant Message (IM) MSRP session to an XMPP Multi-User Chat (MUC) session.
SIP User Gateway XMPP MUC | | | |(F1)(SIP) INVITE | | |------------------------>| | |(F2) (SIP) 200 OK | | |<------------------------| | |(F3) (SIP) ACK | | |------------------------>| | |(F4) (MSRP) NICKNAME | | |------------------------>| | | |(F5)(XMPP) Enter room | | |------------------------->| |(F6) (MSRP) 200 OK | | |<------------------------| | | |(F7)(XMPP) (XMPP) Presence| | |<-------------------------| | | | |(F8)(SIP) SUBSCRIBE | | |------------------------>| | | Event:conference | | | | | |(F9) (SIP) 200 OK | | |<------------------------| | |(F10) (SIP) NOTIFY | | |<------------------------| | |(F11) (SIP) 200 OK | | |------------------------>| | | |(F12)(XMPP) (XMPP) Subject| | |<-------------------------| | | | |(F13)(MSRP) SEND | | |------------------------>| | |(F14)(MSRP) SEND | | |------------------------>| | | |(F15)(XMPP) Chat message | |(F16)(MSRP) 200 OK |------------------------->| |<------------------------|(F17)(XMPP) Chat message | | |<-------------------------| |(F18)(MSRP) SEND | | |<------------------------| | |(F19)(MSRP) 200 OK | | |------------------------>| | . . . . . . | | | |(F20)(SIP) BYE | | |------------------------>| | | |(F21)(XMPP) Exiting a room| | |------------------------->| |(F22)(SIP) 200 OK | | |<------------------------| |
Note: If the XMPP presence stanza is received before the SIP SUBSCRIBE dialog is established for the "conference" event, then the server SHOULD cache the participants list until the subscription is established and delivered in a SIP NOTIFY request.
When the SIP user ("Romeo") wants to join a groupchat room ("Verona"), he first has to start the SIP session by sending out a SIP INVITE request containing an offered session description that includes an MSRP media line accompanied by a mandatory "path" and "chatroom" attributes. The MSRP media line is also accompanied by an "accept-types" attribute specifing support for a Message/CPIM top level wrapper for the MSRP message.
Example: (F1) SIP user starts the session
INVITE sip:verona@chat.example.org SIP/2.0 To: <sip:verona@chat.example.org> From: "Romeo" <sip:romeo@example.com>;gr=orchard Call-ID: 742510no Content-Type: application/sdp Content-Length: [length] c=IN IP4 s2x.example.net m=message 7313 TCP/MSRP * a=accept-types:message/cpim text/plain text/html a=path:msrp://s2x.example.net:7313/ansp71weztas;tcp a=chatroom
Upon receiving the INVITE, the SIP-to-XMPP gateway needs to determine the identity of the remote domain, which it does by performing one or more DNS SRV lookups [RFC2782]. The SIP-to-XMPP gateway SHOULD resolve the address present in the To header of the INVITE to an 'im' URI, then follow the rules in [RFC3861] regarding the "_im" SRV service for the target domain contained in the To header. If SRV address resolution fails for the "_im" service, the SIP-to-XMPP gateway MAY attempt a lookup for the "_xmpp-server" service as specified in [RFC6120] or MAY return an error to the sender (i.e., 502 Bad Gateway).
If SRV address resolution succeeds, the SIP-to-XMPP gateway SHOULD answer successfuly with a SIP 200 OK (F2).
Implementations MAY wait until the nickname is set with an MSRP NICKNAME chunk before joining the XMPP MUC or MAY choose a temporary nickname (such as the SIP From header display name) and use it to join the room.
SIP/2.0 200 OK To: <sip:verona@chat.example.org> From: "Romeo" <sip:romeo@example.com>;gr=orchard Contact: <sip:x2s.example.com;transport=tcp> \ ;methods="INVITE,BYE,OPTIONS,ACK,CANCEL,SUBSCRIBE,NOTIFY"\ ;automata;isfocus;message;event="conference" Call-ID: 742510no Content-Type: application/sdp c=IN IP4 x2s.example.com m=message 8763 TCP/MSRP * a=accept-types:message/cpim text/plain text/html a=path:msrp://x2s.example.com:8763/lkjh37s2s20w2a;tcp a=chatroom:nickname private-messages
Example: (F4) MSRP user sets up nickname
MSRP a786hjs2 NICKNAME To-Path: msrp://s2x.example.net:7313/ansp71weztas;tcp From-Path: msrp://x2s.example.com:8763/lkjh37s2s20w2a;tcp Use-Nickname: "Romeo" -------a786hjs2
Upon receiving the MSRP NICKNAME request, the SIP-to-XMPP gateway is responsible for generating an XMPP presence stanza and sending it to the chatroom.
Example: (F5) Romeo enters chatroom
<presence from='romeo@example.com' to='verona@chat.example.org/Romeo'> <x xmlns='http='http://jabber.org/protocol/muc'/> </presence>
If the room does not already contain another user with the requested nickname, the service accepts the access request. Thus if the gateway does not receive any stanza of type "error" specifying a <conflict/> error condition, it MUST answer the MSRP nickname proposal with a 200 OK response (F6).
Example: (F6) Acknowledgement of join
MSRP a786hjs2 200 OK To-Path: msrp://x2s.example.com:8763/lkjh37s2s20w2a;tcp From-Path: msrp://s2x.example.net:7313/ansp71weztas;tcp -------a786hjs2
So far we have assumed that the requested nickname did not conflict with any existing nicknames. The following flow shows the handling of a nickname conflict.
XMPP conference SIP User Gateway server | | | |(F1)(SIP) INVITE | | |------------------------>| | |(F2) (SIP) 200 OK | | |<------------------------| | |(F3) (SIP) ACK | | |------------------------>| | | | | |(F4) (MSRP) NICKNAME | | |------------------------>| | | |(F5)(XMPP) Entering a room| | |------------------------->| | |(F7) (XMPP) Presence Error| | |<-------------------------| |(F6) (MSRP) 425 Error | | |<------------------------| | | | |
If Romeo decides to change his nickname within the room, he MUST send a new MSRP NICKNAME request. In fact modification of the nickname in MSRP is not different from the initial reservation and usage of a nickname.
XMPP conference SIP User Gateway server | | | |(F1) (MSRP) NICKNAME | | |------------------------->| | | |(F2) (XMPP) Presence w/ Nickname | |------------------------->| |(F3) (MSRP) 200 OK | | |<-------------------------| |
Example: (F1) MSRP user changes nickname
MSRP a786hjs2 NICKNAME To-Path: msrp://s2x.example.net:7313/ansp71weztas;tcp From-Path: msrp://x2s.example.com:8763/lkjh37s2s20w2a;tcp Use-Nickname: "montecchi" -------a786hjs2
Upon receiving such a message, the SIP-to-XMPP gateway MUST translate it into an XMPP presence stanza.
Example: (F2) XMPP translation of nickname change
<presence from='romeo@example.com' to='verona@chat.example.org/montecchi'/>
To follow.
If the multi-user chat service is able to add the SIP user to the room, it sends presence from all the existing occupants' room JIDs to the new occupant's full JID, including extended presence information about roles in an <x/> element.
Example: (F7) Chatroom presence information translated into XMPP
<presence from='verona@chat.example.org/Romeo' to='romeo@example.com'> <x xmlns='http://jabber.org/protocol/muc#user'> <item affiliation='none' role='participant'/> </x> </presence> <presence from='verona@chat.example.org/Ben' to='romeo@example.com'> <x xmlns='http://jabber.org/protocol/muc#user'> <item affiliation='none' role='participant'/> </x> </presence>
Upon receiving these presence stanzas, if the MSRP conference server has already completed the subscription to the Conference Event package [RFC4575], the XMPP-to-SIP gateway MUST translate them in a SIP NOTIFY request containing the participant list (represented in the [RFC4575] format).
Example: (F10) MSRP translation of XMPP participant presence
NOTIFY sip:romeo@example.com SIP/2.0 To: <sip:romeo@example.com>;tag=43524545 From: <sip:verona@chat.example.org>;tag=a3343df32 Call-ID: k3l43id034ksererff Event: conference Subscription-State: active;expires=3600 Content-Type: application/conference-info+xml Content-Length: ... <conference-info version="0" state="full" entity="sip:verona@chat.example.org"> <conference-description> <subject>Today in Verona</subject> <conf-uris> <entry> <uri>tel:+18882934234</uri> <uri>sip:verona@chat.example.org</uri> </entry> </conf-uris> </conference-description> <users> <user entity="sip:verona@chat.example.org/JuliC" state="full"> <display-text>JuliC</display-text> <roles> <entry>participant</entry> </roles> </user> <user entity="sip:verona@chat.example.org/Ben" state="full"> <display-text>Ben</display-text> <roles> <entry>participant</entry> </roles> </users> </conference-info>
Once the user has joined the chat room, the user can exchange an unbounded number of messages both public and private.
The mapping of MSRP syntax elements to XMPP syntax elements SHOULD be as shown in the following table. (Mappings for elements not mentioned are undefined.)
Table 4: Message syntax mapping from MSRP Message to XMPP
+-----------------------------+-----------------------------+ | CPIM Header |XMPP Element or Attribute | +-----------------------------+-----------------------------+ | To | to | | From | from | | body of the SEND request | <body/> | +-----------------------------+-----------------------------+
When Romeo wants to send a message to all other occupants in the room, he sends an MSRP SEND request to <room@service> itself (i.e., <verona@chat.example.org> in our example).
The following examples show an exchange of a public message.
Example: (F12) Romeo sends a message to the chat room
MSRP a786hjs2 SEND To-Path: msrp://s2x.example.net:7313/ansp71weztas;tcp From-Path: msrp://x2s.example.com:8763/lkjh37s2s20w2a;tcp Message-ID: 87652492 Byte-Range: 1-*/* Content-Type: message/cpim To: <sip:verona@chat.example.org> From: "Romeo" <sip:romeo@example.com>;gr=orchard DateTime: 2008-10-15T15:02:31-03:00 Content-Type: text/plain Romeo is here! -------a786hjs2$
Upon receiving the SEND request, if the request either contains a Failure-Report header field value of "yes" or does not contain a Failure-Report header at all, the SIP-to-XMPP gateway MUST immediately translate it into an XMPP message stanza (F13) and then generate and send an MSRP response (F14).
Example: (F13) XMPP translation of message
<message from='romeo@example.com/orchard' to='verona@chat.example.org' type='groupchat' id='8gbx1g4p'> <body>Romeo is here!</body> </message>
Example: (F14) MSRP response to public message
MSRP d93kswow 200 OK To-Path: msrp://x2s.example.com:8763/lkjh37s2s20w2a;tcp From-Path: msrp://s2x.example.net:7313/ansp71weztas;tcp -------d93kswow$
Note well that the XMPP MUC room will reflect the sender's message back to all users, including the sender. In MSRP this reflected message is unnecessary. Therefore gateways are advised to maintain a cache and if the same stanza is received within a reasonable amount of time, assume is the reflected message and ignore it.
Romeo can send a "private message" to a selected occupant via the chat room service by sending a message to the occupant's room nickname.
The following examples show an exchange of a private message.
Example: (F12) Romeo sends a private message
MSRP a786hjs2 SEND To-Path: msrp://s2x.example.net:7313/ansp71weztas;tcp From-Path: msrp://x2s.example.com:8763/lkjh37s2s20w2a;tcp Message-ID: 87652492 Byte-Range: 1-*/* Content-Type: message/cpim To: <sip:verona@chat.example.org>;gr=JuliC From: "Romeo" <sip:romeo@example.com>;gr=orchard DateTime: 2008-10-15T15:02:31-03:00 Content-Type: text/plain I am here!!! -------a786hjs2$
The MSRP conference is responsible for transforming the "From" address into an in-room address.
Example: MSRP handling of private message
MSRP a786hjs2 SEND To-Path: msrp://s2x.example.net:7313/ansp71weztas;tcp From-Path: msrp://x2s.example.com:8763/lkjh37s2s20w2a;tcp Message-ID: 87652492 Byte-Range: 1-*/* Content-Type: message/cpim To: <sip:verona@chat.example.org>;gr=JuliC From: <sip:verona@chat.example.org>;gr=Romeo DateTime: 2008-10-15T15:02:31-03:00 Content-Type: text/plain I am here!!! -------a786hjs2$
Once the MSRP conference sends that message to the gateway, the gateway is responsible for translating it into XMPP syntax.
Example: (F13) XMPP translation of private message
<message from='verona@chat.example.org/Romeo' to='verona@chat.example.org/JuliC' type='chat' id='rg2ca9k7'/> <body>I am here!!!</body> </message>
If Romeo decides to exit the chat room, his client sends a SIP BYE to the <verona@chat.example.org> chat room.
Example: (F11) Romeo terminates the session
BYE sip:verona@chat.example.org SIP/2.0 Max-Forwards: 70 From: "Romeo" <sip:romeo@example.net>;tag=786 To: <sip:verona@chat.example.org>;tag=534 Call-ID: 742510no Cseq: 1 BYE Content-Length: 0
Upon receiving the SIP BYE, the SIP-to-XMPP gateway translates it in a presence stanza (F19) and sends it to the XMPP MUC room service. Then the SIP-to-XMPP gateway responds with a 200 OK to the MSRP user.
Example: (F19) Romeo exits the chatroom
<presence from='romeo@example.com' to='verona@chat.example.org/Romeo' type='unavailable'> </presence>
Fundamental rules for mapping addresses between XMPP and SIP are provided in [I-D.ietf-stox-core]. However, chatrooms include a more specialized, unique identifier for each participant in a room, called a nickname. Implementations are strongly encouraged to apply the rules for preparation and comparison of nicknames specified in [I-D.ietf-precis-nickname].
In addition to nicknames, some groupchat implementations also include display names (which might or might not be different from users' nicknames). A display name need not be unique within the context of a room but instead simply provides a user-friendly name for a participant.
In SIP, the nickname is the value of the XCON 'nickname' attribute of the <user/> element [RFC6501] and the display name is the XML character data of the conference-info <display-text/> element [RFC4575]. In XMPP, the nickname is the value of the resourcepart of the Occupant JID [XEP-0045] and the display name is the XML character data of the <nick/> element [XEP-0172].
In practice, the <display-text/> element is treated as canonical in SIP implementations, and the <nick/> element is rarely used in XMPP implementations. Therefore, for display purposes SIP implementations ought to use the <display-text/> element (not the XCON 'nickname' attribute) and XMPP implementations ought to use the resourcepart of the Occupant JID (not the character data of the <nick/> element).
If there is a conflict between the SIP nickname and the XMPP nickname, the SIP-to-XMPP or XMPP-to-SIP gateway is responsible for adjusting the nickname to avoid the conflict and for informing the SIP or XMPP client of the unique nickname used to join the chatroom.
The security considerations of [RFC3261], [RFC4975], [RFC6120], [I-D.ietf-stox-core], [I-D.ietf-simple-chat], and [XEP-0045] apply.
Additional security considerations will be provided in a future version of this specification.
This document requests no actions of the IANA.
[RFC2782] | Gulbrandsen, A., Vixie, P. and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, February 2000. |
[RFC3515] | Sparks, R., "The Session Initiation Protocol (SIP) Refer Method", RFC 3515, April 2003. |
[RFC4566] | Handley, M., Jacobson, V. and C. Perkins, "SDP: Session Description Protocol", RFC 4566, July 2006. |
[RFC4575] | Rosenberg, J., Schulzrinne, H. and O. Levin, "A Session Initiation Protocol (SIP) Event Package for Conference State", RFC 4575, August 2006. |
[RFC6501] | Novo, O., Camarillo, G., Morgan, D. and J. Urpalainen, "Conference Information Data Model for Centralized Conferencing (XCON)", RFC 6501, March 2012. |
[XEP-0172] | Saint-Andre, P. and V. Mercier, "User Nickname", XSF XEP 0172, March 2012. |
[XEP-0249] | Saint-Andre, P., "Direct MUC Invitations", XSF XEP 0249, September 2011. |
Special thanks to Fabio Forno for his co-authorship of an early version of this document.
Some text in this document was borrowed from [I-D.ietf-stox-core] and from [XEP-0045].