XMPP 2.0
This page summarizes a few ideas on things which could/should/may be in an eventual XMPP 2.0.
This page is a draft written by individuals who may or may not be XSF members. It does not necessarily reflect the view or intention of XSF Board, Council or the XSF as organization as a whole, if that’s a thing.
Issues existing in XMPP 1.0
Routing rules
Current situation
The routing rules for stanzas addressed to the bare JID as defined in RFC 6120 are blurry and don’t really match modern "always-online but not necessarily in the view of the user" multi-device use cases. This is why Message Carbons (XEP-0280) have been invented. They allow a device to tell the server that it wants to receive carbon-copies of all messages received by any resource of an account. This only affects typical chat-related <message/>
stanzas (there are exceptions for certain message types; for presence, there is a well-defined broadcast-to-all-resources mechanism; and IQs can only be addressed to a single resource).
However, throughout the history of XMPP, there have been XEPs which use messages to send data which is really only of interest for a single resource. Prime examples are In-Band Bytestreams (XEP-0047), privacy enhancing protocols such as the (in)famous OTR and (private messages from) Multi-User Chat (XEP-0045). This led to Message Carbon rules being hand-wavy and blurry, some of the behaviour being implementation-defined, depending on co-operating clients which do not speak Message Carbons themselves and other unfortunaties.
Proposed change
To make things simpler, routing rules (for messages) could be re-defined to the following (differences to XMPP 1.0 are highlighted in bold):
- If a message is addressed to a bare account JID, it is delivered to all online resources of the JID.
- If a message is addressed to a full JID:
- if an online resource exists at that full JID, the message is delivered to that resource, and to that resource only (no message carbon copying applies)
- if no online resource exists, an error is returned and the message is not delievered to any resource or stored (NOTE: privacy implications and possible resource scanning need to be thought through)
- these full JID messages are transient, they are never stored in an archive. This affects OTR (which had to use private/no-archive before), MUC-PMs (which are client-specific anyway and should be rather persisted by MUC MAM), IBB messages (works as desgined)
In addition, resource locking as described in RFC 6121 would be discouraged and deprecated, since it interferes with these rules. See below for considerations on resource locking.
Migration path in a hypothetical XMPP 2.0 Session
Since routing rules are inherently different, a definition of what happens to stanzas which transition between XMPP 2.0 and XMPP 1.0 nodes is needed. These rules would normally be implemented by servers. Client libraries which support both XMPP 2.0 and XMPP 1.0 could apply those rules when talking to an XMPP 1.0 server. Relevant definitions:
- XMPP 1.0 Routing Modifiers
- XML elements which modify routing behaviour in XMPP 1.0:
<private/>
(Message Carbons)<no-copy/>
(Message Processing Hints)
Rules for stanzas leaving the XMPP 2.0 realm (to an XMPP 1.0 node):
- If a message is addressed to a full JID, an XMPP 1.0 Routing Modifier to prevent carbon copying MUST be injected.
- The stanza MUST be marked with a to-be-defined
<xmpp-2/>
tag so that XMPP 2.0 nodes further downstream can recognize that the XMPP 2.0 routing semantics shall apply.
Rules for stanzas entering the XMPP 2.0 realm (from an XMPP 1.0 node):
- If the stanza has an
<xmpp-2/>
tag, it MUST be processed as if it came from an XMPP 2.0 node. Any XMPP 1.0 Routing Modifiers MUST be stripped. - If a message to a bare JID has a XMPP 1.0 Routing Modifier which prevents carbon-copying, the routing rules for bare JID messages as defined in RFC 6120 SHOULD be applied.
- The stanza MUST be marked with a to-be-defined
<xmpp-1/>
tag so that XMPP 2.0 nodes further downstream can recognize that the XMPP 1.0 routing semantics shall apply.
Resource locking
Current situation
RFC 6121, Section 5.1 and XEP-0296 describe the process of resource locking for one-on-one chats. In essence, once a response is received from a peer resource, the following messages must be sent to that resource.
The intent was that messages would always arrive at the device currently used by the conversation partner (since Message Carbons were not there), because the routing rules for message stanzas did not enforce that behaviour.
Furthermore, the features offered to a user are often limited by clients based on the capabilities (e.g. Last Message Correction) of the locked-to resource. This introduces race conditions and incompatibility when the chat partner switches devices or reads up the conversation from an offline storage / archive.
Proposed change
Eliminate resource locking in XMPP 2.0 entirely. Instead, always send conversational content to the bare JID. Messages sent to the full JID in XMPP 2.0 are specifically addressed to the resource and will not be carbon-copied, as described in the previous section.
Migration path in a hypothetical XMPP 2.0 Session
None needed. Chat conversations work fine without any resource locking today.
Client Session Setup
Current situation
A client that (re)connects to its server needs to perform these steps:
- Authenticate (actually: establish an XML stream, convert to TLS, establish a new XML stream, perform SCRAM or some other multi-step auth mechanism)
- Attempt Stream Resumption. On success the connection is established, on failure the client needs to continue:
- bind a new session
- Enable Carbons
- Send initial presence
- Obtain offline messages
- (optionally) query the MAM archive and deduplicate with offline messages
- Join MUCs
There is a race condition between enabling Carbons and synchronizing MAM, and the number of steps and round-trips is tremendous.
XMPP 2.0 Session Initiation
The client and server must coordinate the required information for a sync as soon as possible:
- Authenticate
- Client sends a bind2 request containing:
- stream resumption id (optional, to faciliate Stream Resumption)
- last-known MAM message-id (optional, to achieve full synchronization)
- MAM request with a time-delta (optional, alternative to message-id if only the history of the last N time units is needed)
- initial presence (maybe?)
- MUCs to join (maybe?)
- The server automagically figures out whether to do a stream resumption or a MAM sync and provides according data to the client, generates presence broadcast accordingly
The new session automatically feeds the client all stanzas directed at the client's bare JID, resource, and Carbons of sent messages from other resources. This is a change of routing rules in comparison to core rules and Carbons, and it sends all "persistent" messages to the client.
TODO
- The MAM subscription thing?
- Sent carbons