DesignXMPP im
Version 4 (Adrian Georgescu, 05/31/2012 04:13 pm)
1 | 3 | Adrian Georgescu | h1. SIP-XMPP Instant Messaging (IM) |
---|---|---|---|
2 | 1 | Tijmen de Mes | |
3 | 1 | Tijmen de Mes | In XMPP there are several types of messages which lead to different semantics when exchanging XMPP _message stanzas_ between 2 endpoints. This section focuses only on message types that allow 2 endpoints to send instant messages to each other. |
4 | 1 | Tijmen de Mes | |
5 | 1 | Tijmen de Mes | h3. XMPP IM types |
6 | 1 | Tijmen de Mes | |
7 | 4 | Adrian Georgescu | In XMPP there are three ways of doing Instant Messaging: |
8 | 4 | Adrian Georgescu | |
9 | 3 | Adrian Georgescu | * Normal: the default message type. A reply is not expected from the recipient. This is further referred as 'Single Message' mode. |
10 | 3 | Adrian Georgescu | * Chat: This message type implies both parties have engaged a conversation. This is further referred as 'Chat Session' mode. |
11 | 1 | Tijmen de Mes | |
12 | 3 | Adrian Georgescu | The first one is session-less and the latter is session based. |
13 | 3 | Adrian Georgescu | |
14 | 1 | Tijmen de Mes | * Headline: An endpoint receiving this type of message should never reply, since it's meant to be used by servers or other entities to deliver announcements. |
15 | 1 | Tijmen de Mes | |
16 | 1 | Tijmen de Mes | h3. SIP IM types |
17 | 1 | Tijmen de Mes | |
18 | 4 | Adrian Georgescu | In SIP there are two ways of doing Instant Messaging: |
19 | 1 | Tijmen de Mes | |
20 | 3 | Adrian Georgescu | * SIP MESSAGE (RFC 3428). This is further referred as 'Single Message' mode. |
21 | 3 | Adrian Georgescu | * MSRP sessions (RFC 4975). This is further referred as 'Chat Session' mode. |
22 | 1 | Tijmen de Mes | |
23 | 1 | Tijmen de Mes | The first one is session-less and the latter is session based. |
24 | 1 | Tijmen de Mes | |
25 | 3 | Adrian Georgescu | h2. Single Message Translation |
26 | 1 | Tijmen de Mes | |
27 | 3 | Adrian Georgescu | The mechanism described here follow the currently available specifications for SIP-XMPP interoperability: |
28 | 3 | Adrian Georgescu | |
29 | 1 | Tijmen de Mes | * http://xmpp.org/internet-drafts/draft-saintandre-sip-xmpp-im-01.html |
30 | 1 | Tijmen de Mes | |
31 | 1 | Tijmen de Mes | XMPP single messages are mapped directly to SIP MESSAGE requests and _vice versa_. |
32 | 1 | Tijmen de Mes | |
33 | 1 | Tijmen de Mes | !{ 700px, center}xmppgw_im_normal.png! |
34 | 1 | Tijmen de Mes | |
35 | 1 | Tijmen de Mes | |
36 | 1 | Tijmen de Mes | h3. Overview |
37 | 1 | Tijmen de Mes | |
38 | 1 | Tijmen de Mes | |
39 | 1 | Tijmen de Mes | The mechanism for translating XMPP normal message stanzas and SIP MESSAGE requests is straightforward, they map one to one as stated in http://xmpp.org/internet-drafts/draft-saintandre-sip-xmpp-im-01.html. However, since SIP is used mainly with UDP as a transport, if a XMPP stanza is bigger than 1500 bytes it will be chunked into smaller pieces to avoid ethernet fragmentation related issues. |
40 | 1 | Tijmen de Mes | |
41 | 1 | Tijmen de Mes | Since SIP MESSAGE is a non INVITE transaction, it has to be replied immediately, because there is no way to avoid retransmissions. This means that the SIP-XMPP gateway will reply on the SIP side before knowing if the message was actually delivered to the XMPP side. In order to express this a "202 Accepted" reply will be sent to the SIP request instead of a "200 OK". |
42 | 1 | Tijmen de Mes | |
43 | 1 | Tijmen de Mes | On the other hand, when an XMPP stanza is translated into a SIP MESSAGE request the SIP-XMPP gateway is able to report back the result (in case of error) by using a message stanza of type _error_. This is possible because of the asynchronous nature of stanza processing in the XMPP protocol. |
44 | 1 | Tijmen de Mes | |
45 | 1 | Tijmen de Mes | |
46 | 1 | Tijmen de Mes | h3. Error reporting |
47 | 1 | Tijmen de Mes | |
48 | 1 | Tijmen de Mes | |
49 | 1 | Tijmen de Mes | No error reporting mechanism can be used at the SIP level to notify about SIP MESSAGE delivery success or failure, since the request has to be replied to immediately (because it's a non INVITE transaction). |
50 | 1 | Tijmen de Mes | |
51 | 3 | Adrian Georgescu | h2. Chat Session Translation |
52 | 1 | Tijmen de Mes | |
53 | 3 | Adrian Georgescu | The mechanism described here follow the currently available specifications for SIP-XMPP interoperability: |
54 | 3 | Adrian Georgescu | * http://xmpp.org/internet-drafts/draft-saintandre-sip-xmpp-chat-03.html |
55 | 1 | Tijmen de Mes | |
56 | 1 | Tijmen de Mes | In XMPP there are 2 different types of _chat sessions_: |
57 | 1 | Tijmen de Mes | |
58 | 1 | Tijmen de Mes | * Formal sessions: those negotiated with XEP-0155 |
59 | 1 | Tijmen de Mes | * Informal sessions: any exchange of message stanzas of type chat |
60 | 1 | Tijmen de Mes | |
61 | 1 | Tijmen de Mes | Formal sessions map directly to SIP sessions but since support for that XEP doesn't seem to be widely deployed it will not be implemented. |
62 | 1 | Tijmen de Mes | |
63 | 1 | Tijmen de Mes | Informal sessions can be mapped to SIP sessions with MSRP media or to SIP MESSAGE requests. Both mechanisms will be implemented and selecting which one to use will be decided with a configuration option. |
64 | 1 | Tijmen de Mes | |
65 | 1 | Tijmen de Mes | *The use of SIP MESSAGE is highly discouraged* due to the following reasons: |
66 | 1 | Tijmen de Mes | |
67 | 1 | Tijmen de Mes | * There is no unique message identification mechanism |
68 | 1 | Tijmen de Mes | * The most used transport in SIP is UDP, which is unreliable, thus making delivery of SIP MESSAGE requests unreliable |
69 | 1 | Tijmen de Mes | * Lack of an end to end delivery confirmation mechanism |
70 | 1 | Tijmen de Mes | * Message order is not guaranteed if an unreliable transport like UDP is used |
71 | 1 | Tijmen de Mes | * Messages could get duplicated due to retransmissions if an unreliable transport is used |
72 | 1 | Tijmen de Mes | * The majority of deployed endpoints lack support for CPIM, which is required for conferencing scenarios |
73 | 1 | Tijmen de Mes | |
74 | 1 | Tijmen de Mes | |
75 | 1 | Tijmen de Mes | h3. Defining an XMPP chat session |
76 | 1 | Tijmen de Mes | |
77 | 1 | Tijmen de Mes | h4. Problem analysis |
78 | 1 | Tijmen de Mes | |
79 | 1 | Tijmen de Mes | |
80 | 1 | Tijmen de Mes | In SIP a _session_ is started by creating a dialog with the INVITE method and it's ended by terminating the dialog with a BYE request. In XMPP there is no universal mechanism to indicate that a chat session has started or ended. Because of this, the SIP-XMPP gateway will try its best to correlate the state on the SIP side with the one on the XMPP side. |
81 | 1 | Tijmen de Mes | |
82 | 1 | Tijmen de Mes | There are different mechanisms by which the start and end of an XMPP chat session can be stated, but unfortunately none of them seem to be implemented in the most widely used XMPP clients, so relaying on them would lead to trouble. |
83 | 1 | Tijmen de Mes | |
84 | 1 | Tijmen de Mes | * _XEP-0155: Stanza Session Negotiation_. This XEP has been in draft form since 2008 and even if implementation is encouraged none of the widely used XMPP clients implements it. |
85 | 1 | Tijmen de Mes | * _XEP-0201: Best Practices for Message Threads_. This XEP is more recent and some many clients implement it. Unfortunately, the concept of a "chat session" according to this XEP doesn't match the one on SIP because message threads last far longer, they can be resumed even after being offline for a while. |
86 | 1 | Tijmen de Mes | * _XEP-0085: Chat State Notifications_. This XEP defines a set of states in which use can be while on a chat session. Many clients implement it and it can be used to signal composing indication on the SIP side and also to decide when a session should be ended on the SIP side (the _gone_ state). |
87 | 1 | Tijmen de Mes | |
88 | 1 | Tijmen de Mes | h4. Proposed solution |
89 | 1 | Tijmen de Mes | |
90 | 1 | Tijmen de Mes | |
91 | 1 | Tijmen de Mes | Since no reliable way has been found to map SIP sessions to XMPP chat sessions and vice versa, the SIP-XMPP gateway will try to use all the available information to act as accurately as possible. |
92 | 1 | Tijmen de Mes | |
93 | 1 | Tijmen de Mes | |
94 | 1 | Tijmen de Mes | h5. Addressing |
95 | 1 | Tijmen de Mes | |
96 | 1 | Tijmen de Mes | |
97 | 1 | Tijmen de Mes | The first thing that needs to be solved is addressing: XMPP JIDs have a resource, which uniquely identifies a given XMPP client instance, for example @saul@ag-projects.com/foobar@. A similar mechanism needs to be implemented on the SIP side so that individual devices and thus session endpoints are properly matched. This is solved by using _GRUU_ (RFC 5627). With GRUU each device will have a unique identifier, like the XMPP JID resource. For example, these could be the 2 endpoints of a given session: user1 @sip:saul@ag-projects.com;gr=89y89y4hr489j98jf4@ <--> user2 @ag@ag-projects.com/foobar@. |
98 | 1 | Tijmen de Mes | |
99 | 1 | Tijmen de Mes | If a SIP endpoint doesn't have a GRUU support a single fixed identifier will be assigned. This fixed value MUST never change while the application is running. The lack of support of GRUU imposes a limitation, though: only a single concurrent session can be carried out with the same destination XMPP JID, because otherwise it would be impossible to match the destination of the incoming XMPP stanzas (the recipient would always be the same). |
100 | 1 | Tijmen de Mes | |
101 | 1 | Tijmen de Mes | |
102 | 1 | Tijmen de Mes | h5. Starting a session (SIP) |
103 | 1 | Tijmen de Mes | |
104 | 1 | Tijmen de Mes | |
105 | 1 | Tijmen de Mes | In order to start a session from the SIP side, an INVITE will be used, as usual. When building the request URI, the caller may specify the callee instance he wants to talk to by sing the GRUU semantics, that is: @sip:user@gmail.com;gr=foobar@ would be translated to @user@gmail.com/foobar@. |
106 | 1 | Tijmen de Mes | |
107 | 1 | Tijmen de Mes | If there is no session established between the caller and the callee the SIP-XMPP gateway will accept the session and will start translating SIP chat messages to XMPP chat message stanzas. If there is already an ongoing session between the two given endpoints, the SIP-XMPP gateway will reject the session with 488 code. |
108 | 1 | Tijmen de Mes | |
109 | 1 | Tijmen de Mes | Note that if the SIP request URI doesn't contain the resource identifier (gr parameter) the translated JID is a _bare_ JID (a JID with no resource specified) so the real recipient is unknown until a response is received from any XMPP client with that JID. |
110 | 1 | Tijmen de Mes | |
111 | 1 | Tijmen de Mes | |
112 | 1 | Tijmen de Mes | h5. Starting a session (XMPP) |
113 | 1 | Tijmen de Mes | |
114 | 1 | Tijmen de Mes | |
115 | 1 | Tijmen de Mes | As aforementioned, XMPP doesn't have a mechanism to indicate the start of a chat session, so the XMPP client will just send a message stanza. If there is no session whose endpoints map those specified in the stanza a new outbound SIP session will be created. |
116 | 1 | Tijmen de Mes | |
117 | 1 | Tijmen de Mes | The outbound SIP request will always have a GRUU in the From header, as a result of the translation from a full JID. |
118 | 1 | Tijmen de Mes | |
119 | 1 | Tijmen de Mes | Note that if the recipient JID is a bare JID the real recipient is unknown until a reply is received on the SIP side (the request may fork and the session will be bound to the endpoint that answers). |
120 | 1 | Tijmen de Mes | |
121 | 1 | Tijmen de Mes | |
122 | 1 | Tijmen de Mes | h5. Ending a session (SIP) |
123 | 1 | Tijmen de Mes | |
124 | 1 | Tijmen de Mes | |
125 | 1 | Tijmen de Mes | If a SIP endpoint sends a BYE request to the SIP-XMPP gateway, the SIP session will be terminated and a body-less chat message stanza will be sent to the XMPP endpoint with the _gone_ chat state (XEP-0085). |
126 | 1 | Tijmen de Mes | |
127 | 1 | Tijmen de Mes | |
128 | 1 | Tijmen de Mes | h5. Ending a session (XMPP) |
129 | 1 | Tijmen de Mes | |
130 | 1 | Tijmen de Mes | |
131 | 1 | Tijmen de Mes | If a XMPP endpoint sends a chat message stanza with the _gone_ chat state the SIP-XMPP gateway will terminate the session on the SIP side by sending a BYE request. Since not all XMPP clients send the _gone_ chat state the SIP-XMPP gateway will keep a timer which will terminate the session on the SIP side if no chat messages were exchanged in that amount of time. The default value (it's configurable) is 10 minutes, as recommended by XEP-0085. |
132 | 1 | Tijmen de Mes | |
133 | 1 | Tijmen de Mes | |
134 | 1 | Tijmen de Mes | |
135 | 1 | Tijmen de Mes | h3. XMPP chat session <-> SIP MESSAGE |
136 | 1 | Tijmen de Mes | |
137 | 1 | Tijmen de Mes | |
138 | 1 | Tijmen de Mes | !{ 700px, center}xmppgw_im_chat_sipmessage.png! |
139 | 1 | Tijmen de Mes | |
140 | 1 | Tijmen de Mes | |
141 | 1 | Tijmen de Mes | h4. Error reporting |
142 | 1 | Tijmen de Mes | |
143 | 1 | Tijmen de Mes | |
144 | 1 | Tijmen de Mes | No error reporting mechanism can be used at the SIP level to notify about SIP MESSAGE delivery success or failure, since the request has to be replied to immediately (because it's a non INVITE transaction). |
145 | 1 | Tijmen de Mes | |
146 | 1 | Tijmen de Mes | |
147 | 1 | Tijmen de Mes | h3. XMPP chat session <-> MSRP |
148 | 1 | Tijmen de Mes | |
149 | 1 | Tijmen de Mes | |
150 | 1 | Tijmen de Mes | !{ 700px, center}xmppgw_im_chat_msrp.png! |
151 | 1 | Tijmen de Mes | |
152 | 1 | Tijmen de Mes | !{ 700px, center}xmppgw_im_chat_msrp2.png! |
153 | 1 | Tijmen de Mes | |
154 | 1 | Tijmen de Mes | |
155 | 1 | Tijmen de Mes | h4. Error reporting |
156 | 1 | Tijmen de Mes | |
157 | 1 | Tijmen de Mes | |
158 | 1 | Tijmen de Mes | None of the XMPP - SIP interoperability specs mention how error reporting should be done for chat messages. Since XMPP supports receipts (XEP-0184) they are correlated with the MSRP REPORT requests by the SIP-XMPP gateway in order to have message delivery assurance on both SIP and XMPP. |