jabberd project

JEP-01XX: jabberd 2.0 Component Protocol

Informational documentation of the component protocol used by jabberd 2.0.

WARNING: This Informational JEP is Experimental. Publication as a Jabber Enhancement Proposal DOES NOT imply acceptance or approval of this proposal. Implementation of the protocol described herein is NOT RECOMMENDED except in an exploratory fashion (e.g., in a proof of concept). Production systems SHOULD NOT deploy implementations of this protocol until it advances to a status of Active.

Author Information

Robert Norris

Email: rob@cataclysm.cx
JID: rob@cataclysm.cx

JEP Information

Number: 01XX
Status: Experimental
Type: Informational
JIG: Standards JIG
Dependencies: None
Supersedes: None
Superseded By: None
Short Name: N/A

Legal Notice

This Jabber Enhancement Proposal is copyright 1999 - 2003 by the Jabber Software Foundation (JSF) and is in full conformance with the JSF's Intellectual Property Rights Policy <http://jabber.org/jsf/ipr-policy.php>. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at <http://www.opencontent.org/openpub/>).

Revision History

Version 0.1 (2003-09-11)

Initial version. (rn)


Table of Contents:
1. Introduction
2. Overview
3. Protocol
3.1. Stream negotiation
3.2. Authentication
3.3. Binding a domain
3.4. Unbinding a domain
3.5. Sending packets
3.6. Broadcast packets
3.7. Domain advertisements
3.8. Packet throttling


1. Introduction

The jabberd 2.0 server branch supports an enhanced version of the protocol defined in Existing Component Protocol [1] for communication between the router and components. This JEP documents that protocol.

This document is current as of jabberd version 2.0 stable 1.

2. Overview

The jabberd 2.0 component protocol is considerably more complex than its predecessor, but allows much greater flexibility. The protocol supports the following:

The namespace URI for elements in this protocol is 'http://jabberd.jabberstudio.org/ns/component/1.0'.

3. Protocol

3.1 Stream negotiation

As with all Jabber connections, the first thing a component does is connect and initialise a stream. Since this protocol requires XMPP features, the component must send the "version" attribute:

Example 1. Stream Negotiation

C: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
S: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' id='12345678'>

Somewhat unusually, the default namespace does not need to be declared on the stream header. Due to the way jabberd 2.0 works with namespaces (ie anything and everything allowed by XML goes), its perfectly acceptable, and often preferable, to define the namespace on the packets themselves rather than on the stream header. Its up to the component author to decide what works best for their environment.

Similarly, a "to" or "from" attribute is not necessary, as it doesn't really make sense in the context of joining the network.

3.2 Authentication

The component should now do any stream setup it requires (such as using STARTTLS to establish a secure connection). When it has completed this, it should authenticate using SASL. The authorisation ID for the authentication must be present, but does not have to be a JID, necessarily. In jabberd 2.0, the authorisation ID is used to determine which component features they may access. This is determined by the administrator.

3.3 Binding a domain

Once authenticated, the component must bind a domain to itself in order to send and receive packets for that domain. A component may bind more than one domain if it wishes (though in jabberd 2.0, a component may only bind if the domain it requests is the same as its authorisation ID, unless the administrator allows otherwise).

Example 2. Binding a domain

C: <bind name='conference.jabber.org'/>
S: <bind/>

Once bound, domain is considered to be an active entity on the network, and the component may start send and receiving packets for the domain.

The component may optionally specify options to the bind request. In jabberd 2.0, the availability of bind options to a component is dependent on the authorisation ID of the component, and the access controls specified by the administrator.

The following options are available:

  • <default/> - sets this component as the default route; ie, if a component sends a route to a domain that has not been bound, then it will be delivered to this component rather than bounced back to the sender. (This is used by the "s2s" component of jabberd 2.0).
  • <log/> - if specified, this component will receive a copy of each and every packet that is sent through the router. This could be used to provide a message logging service.

Example 3. Binding a domain with options

C: <bind name='s2s'/>
     <default/>
   </bind>
S: <bind/>

If the bind fails, the server will return a numeric error code that corresponds to the cause of the failure:

Example 4. Bind failure

C: <bind name='conference.jabber.org'/>
S: <bind error='409'/>

Table 1: Error codes

Code Meaning
400 The "name" attribute is missing or invalid
403 The component is not authorised to bind using this name and/or options
409 The name that is already bound

3.4 Unbinding a domain

A component may unbind a domain is has previously bound by sending a packet like the following:

Example 5. Unbinding a domain

C: <unbind name='conference.jabber.org'/>
S: <unbind/>

Once unbound, the component may no longer send or receive packets for the domain.

If the unbind fails, the server will return a numeric error code that corresponds to the cause of the failure:

Example 6. Unbind failure

C: <unbind name='conference.jabber.org'/>
S: <unbind error='403'/>

Table 2: Error codes

Code Meaning
400 The "name" attribute is missing or invalid
404 The name is not bound to this component

If the component disconnects or closes the stream, any domains bound to it will be automatically unbound.

3.5 Sending packets

Packets are sent and received using the <route/> element:

Example 7. A simple packet

<route from='s2s' to='conference.jabber.org'>
  <message xmlns='jabber:client' to='jdev@conference.jabber.org/rob' from='rob@cataclysm.cx/laptop' type='groupchat'>
    <body>oh, how I wish we could kick people</body>
  </message>
</route>

The "to" and "from" attributes on the <route/> are required, and may not be spoofed. With jabberd 2.0, the router will bounce or drop packets that do not have both of these attributes, or has a from address that does not match one of the domains bound to the sending component. Route addresses are always domains; there are no nodes or resources.

The router will treat the payload as an opaque XML chunk. All routing decisions are based solely on the route "to" attribute.

If a route packet is invalid or undeliverable for some reason, it will be returned to the sender. The "to" and "from" attributes will be swapped, and an "error" attribute will be added, containing a numeric error code that corresponds to the cause of the failure:

Example 8. Error packet

<route from='conference.jabber.org' to='s2s' error='404'>
  <message xmlns='jabber:client' to='jdev@conference.jabber.org/rob' from='rob@cataclysm.cx/laptop' type='groupchat'>
    <body>oh, how I wish we could kick people</body>
  </message>
</route>

Table 3: Error codes

Code Meaning
400 The route is a unicast and the "to" or "from" attributes are missing or invalid, or the route is a broadcast and the "to" attribute is missing or invalid.
401 The "from" attribute is not set to a name that is bound to the sending component
404 The destination name is not bound, and there is no default route

3.6 Broadcast packets

A component may send a broadcast packet by sending a <route/>

Example 9. A broadcast packet

<route from='c2s' type='broadcast'>
  <payload xmlns='payload-namespace'/>
</route>

(Although this is implemented by the jabberd 2.0 router, its not actually used anywhere, and so a working example is hard to provide).

The router will then distribute this packet to every other component currently connected.

3.7 Domain advertisements

When a component binds a domain, all the other components currently attached will receive notice of the fact via a <presence/> packet from the router:

Example 10. Domain advertisement

<presence from='conference.jabber.org'/>

(The jabberd 2.0 session manager uses this to good effect to probe new components for service information in order to populate the disco, browse and agents lists).

Similarly, when a component unbinds a domain, all the other components are informed:

Example 11. Domain "unadvertisement"

<presence from='conference.jabber.org' type='unavailable'/>

3.8 Packet throttling

A component can ask the router to throttle its packets. When the throttle is active, packets destined for the component will be queued inside the router. When the throttle is released, the queued packets are delivered. This is useful if a component has time-consuming tasks to perform and is unable to handle packets at the same time.

The <throttle/> element is a toggle - its up to the component to remember if it is currently throttled or not.

Example 12. Throttling/unthrottling packets

C: <throttle/>
S: <throttle/>


Notes

1. JEP-0114: Existing Component Protocol <http://www.jabber.org/jeps/jep-0114.html>.

2. XMPP Core <http://www.jabber.org/ietf/> (work in progress).