| 1 | <html><head><title>jabberd project</title> |
|---|
| 2 | |
|---|
| 3 | <h1 class="title"><a href="http://jabberd2.xiaoka.com/">jabberd project</a></h1> |
|---|
| 4 | |
|---|
| 5 | <div class="content"> |
|---|
| 6 | |
|---|
| 7 | <div class="dev-content"> |
|---|
| 8 | <h1>JEP-01XX: jabberd 2.0 Component Protocol</h1> |
|---|
| 9 | <p>Informational documentation of the component protocol used by jabberd 2.0.</p> |
|---|
| 10 | <p style="color: red;">WARNING: This Informational JEP is Experimental. |
|---|
| 11 | Publication as a Jabber Enhancement Proposal DOES NOT imply acceptance |
|---|
| 12 | or approval of this proposal. Implementation of the protocol described |
|---|
| 13 | herein is NOT RECOMMENDED except in an exploratory fashion (e.g., in a |
|---|
| 14 | proof of concept). Production systems SHOULD NOT deploy implementations |
|---|
| 15 | of this protocol until it advances to a status of Active.</p> |
|---|
| 16 | <h2>Author Information</h2> |
|---|
| 17 | <h3>Robert Norris</h3> |
|---|
| 18 | <blockquote><p> |
|---|
| 19 | Email: rob@cataclysm.cx<br> |
|---|
| 20 | JID: rob@cataclysm.cx</p></blockquote> |
|---|
| 21 | <h2>JEP Information</h2> |
|---|
| 22 | <blockquote><p> |
|---|
| 23 | Number: 01XX<br> |
|---|
| 24 | Status: Experimental<br> |
|---|
| 25 | Type: Informational<br> |
|---|
| 26 | JIG: Standards JIG<br> |
|---|
| 27 | Dependencies: None<br> |
|---|
| 28 | Supersedes: None<br> |
|---|
| 29 | Superseded By: None<br> |
|---|
| 30 | Short Name: N/A<br> |
|---|
| 31 | </p></blockquote> |
|---|
| 32 | <h2>Legal Notice</h2> |
|---|
| 33 | <blockquote><p>This Jabber Enhancement Proposal is copyright 1999 - |
|---|
| 34 | 2003 by the Jabber Software Foundation (JSF) and is in full conformance |
|---|
| 35 | with the JSF's Intellectual Property Rights Policy <<a href="http://jabber.org/jsf/ipr-policy.php">http://jabber.org/jsf/ipr-policy.php</a>>. |
|---|
| 36 | This material may be distributed only subject to the terms and |
|---|
| 37 | conditions set forth in the Open Publication License, v1.0 or later |
|---|
| 38 | (the latest version is presently available at <<a href="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</a>>).</p></blockquote> |
|---|
| 39 | <h2>Revision History</h2> |
|---|
| 40 | <blockquote><p> |
|---|
| 41 | </p><h3>Version 0.1 (2003-09-11)</h3> |
|---|
| 42 | <blockquote><p>Initial version. (rn) |
|---|
| 43 | </p></blockquote> |
|---|
| 44 | <p></p></blockquote> |
|---|
| 45 | <p></p><hr><p></p> |
|---|
| 46 | <strong>Table of Contents:</strong><br><dl> |
|---|
| 47 | <dt>1. <a href="#sect-id2592397">Introduction</a> |
|---|
| 48 | </dt> |
|---|
| 49 | <dt>2. <a href="#sect-id2593000">Overview</a> |
|---|
| 50 | </dt> |
|---|
| 51 | <dt>3. <a href="#sect-id2593145">Protocol</a> |
|---|
| 52 | </dt> |
|---|
| 53 | <dl> |
|---|
| 54 | <dt>3.1. <a href="#sect-id2593029">Stream negotiation</a> |
|---|
| 55 | </dt> |
|---|
| 56 | <dt>3.2. <a href="#sect-id2593075">Authentication</a> |
|---|
| 57 | </dt> |
|---|
| 58 | <dt>3.3. <a href="#sect-id2593096">Binding a domain</a> |
|---|
| 59 | </dt> |
|---|
| 60 | <dt>3.4. <a href="#sect-id2588777">Unbinding a domain</a> |
|---|
| 61 | </dt> |
|---|
| 62 | <dt>3.5. <a href="#sect-id2589010">Sending packets</a> |
|---|
| 63 | </dt> |
|---|
| 64 | <dt>3.6. <a href="#sect-id2589170">Broadcast packets</a> |
|---|
| 65 | </dt> |
|---|
| 66 | <dt>3.7. <a href="#sect-id2589209">Domain advertisements</a> |
|---|
| 67 | </dt> |
|---|
| 68 | <dt>3.8. <a href="#sect-id2589256">Packet throttling</a> |
|---|
| 69 | </dt> |
|---|
| 70 | </dl> |
|---|
| 71 | </dl> |
|---|
| 72 | <p></p><hr><p></p> |
|---|
| 73 | <a name=""></a><h2>1. |
|---|
| 74 | <a name="sect-id2592397">Introduction</a> |
|---|
| 75 | </h2> |
|---|
| 76 | <p>The jabberd 2.0 server branch supports an enhanced version of the protocol defined in <strong>Existing Component Protocol</strong> [<a href="#nt-id2592423">1</a>] for communication between the router and components. This JEP documents that protocol.</p> |
|---|
| 77 | |
|---|
| 78 | <p>This document is current as of jabberd version 2.0 stable 1.</p> |
|---|
| 79 | <a name=""></a><h2>2. |
|---|
| 80 | <a name="sect-id2593000">Overview</a> |
|---|
| 81 | </h2> |
|---|
| 82 | <p>The jabberd 2.0 component protocol is considerably more |
|---|
| 83 | complex than its predecessor, but allows much greater flexibility. The |
|---|
| 84 | protocol supports the following:</p> |
|---|
| 85 | <ul> |
|---|
| 86 | <li>Authentication / authorisation and encryption using SASL and TLS (as defined in <strong>XMPP Core</strong> [<a href="#nt-id2593111">2</a>])</li> |
|---|
| 87 | <li>Binding multiple domains to a single component</li> |
|---|
| 88 | <li>Sending / receiving packets</li> |
|---|
| 89 | <li>Packet broadcasts</li> |
|---|
| 90 | <li>Domain advertisements</li> |
|---|
| 91 | <li>Packet throttling</li> |
|---|
| 92 | </ul> |
|---|
| 93 | <p>The namespace URI for elements in this protocol is 'http://jabberd.jabberstudio.org/ns/component/1.0'.</p> |
|---|
| 94 | <a name=""></a><h2>3. |
|---|
| 95 | <a name="sect-id2593145">Protocol</a> |
|---|
| 96 | </h2> |
|---|
| 97 | |
|---|
| 98 | <blockquote> |
|---|
| 99 | <h3>3.1 <a name="sect-id2593029">Stream negotiation</a> |
|---|
| 100 | </h3> |
|---|
| 101 | <p>As with all Jabber connections, the first thing a |
|---|
| 102 | component does is connect and initialise a stream. Since this protocol |
|---|
| 103 | requires XMPP features, the component must send the "version" attribute:</p> |
|---|
| 104 | |
|---|
| 105 | <p><strong>Example 1. Stream Negotiation</strong></p> |
|---|
| 106 | <blockquote><pre>C: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0'> |
|---|
| 107 | S: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' id='12345678'> |
|---|
| 108 | </pre></blockquote> |
|---|
| 109 | |
|---|
| 110 | <p>Somewhat unusually, the default namespace |
|---|
| 111 | does not need to be declared on the stream header. Due to the way |
|---|
| 112 | jabberd 2.0 works with namespaces (ie anything and everything allowed |
|---|
| 113 | by XML goes), its perfectly acceptable, and often preferable, to define |
|---|
| 114 | the namespace on the packets themselves rather than on the stream |
|---|
| 115 | header. Its up to the component author to decide what works best for |
|---|
| 116 | their environment.</p> |
|---|
| 117 | |
|---|
| 118 | <p>Similarly, a "to" or "from" attribute is not necessary, as it doesn't really make sense in the context of joining the network.</p> |
|---|
| 119 | </blockquote> |
|---|
| 120 | |
|---|
| 121 | <blockquote> |
|---|
| 122 | <h3>3.2 <a name="sect-id2593075">Authentication</a> |
|---|
| 123 | </h3> |
|---|
| 124 | <p>The component should now do any stream setup it requires |
|---|
| 125 | (such as using STARTTLS to establish a secure connection). When it has |
|---|
| 126 | completed this, it should authenticate using SASL. The authorisation ID |
|---|
| 127 | for the authentication must be present, but does not have to be a JID, |
|---|
| 128 | necessarily. In jabberd 2.0, the authorisation ID is used to determine |
|---|
| 129 | which component features they may access. This is determined by the |
|---|
| 130 | administrator.</p> |
|---|
| 131 | </blockquote> |
|---|
| 132 | |
|---|
| 133 | <blockquote> |
|---|
| 134 | <h3>3.3 <a name="sect-id2593096">Binding a domain</a> |
|---|
| 135 | </h3> |
|---|
| 136 | <p>Once authenticated, the component must bind a domain to |
|---|
| 137 | itself in order to send and receive packets for that domain. A |
|---|
| 138 | component may bind more than one domain if it wishes (though in jabberd |
|---|
| 139 | 2.0, a component may only bind if the domain it requests is the same as |
|---|
| 140 | its authorisation ID, unless the administrator allows otherwise).</p> |
|---|
| 141 | |
|---|
| 142 | <p><strong>Example 2. Binding a domain</strong></p> |
|---|
| 143 | <blockquote><pre>C: <bind name='conference.jabber.org'/> |
|---|
| 144 | S: <bind/> |
|---|
| 145 | </pre></blockquote> |
|---|
| 146 | |
|---|
| 147 | <p>Once bound, domain is considered to be an |
|---|
| 148 | active entity on the network, and the component may start send and |
|---|
| 149 | receiving packets for the domain.</p> |
|---|
| 150 | |
|---|
| 151 | <p>The component may |
|---|
| 152 | optionally specify options to the bind request. In jabberd 2.0, the |
|---|
| 153 | availability of bind options to a component is dependent on the |
|---|
| 154 | authorisation ID of the component, and the access controls specified by |
|---|
| 155 | the administrator.</p> |
|---|
| 156 | |
|---|
| 157 | <p>The following options are available:</p> |
|---|
| 158 | |
|---|
| 159 | <ul> |
|---|
| 160 | <li><default/> |
|---|
| 161 | - sets this component as the default route; ie, if a component sends a |
|---|
| 162 | route to a domain that has not been bound, then it will be delivered to |
|---|
| 163 | this component rather than bounced back to the sender. (This is used by |
|---|
| 164 | the "s2s" component of jabberd 2.0).</li> |
|---|
| 165 | <li><log/> - if |
|---|
| 166 | specified, this component will receive a copy of each and every packet |
|---|
| 167 | that is sent through the router. This could be used to provide a |
|---|
| 168 | message logging service.</li> |
|---|
| 169 | </ul> |
|---|
| 170 | |
|---|
| 171 | <p><strong>Example 3. Binding a domain with options</strong></p> |
|---|
| 172 | <blockquote><pre>C: <bind name='s2s'/> |
|---|
| 173 | <default/> |
|---|
| 174 | </bind> |
|---|
| 175 | S: <bind/> |
|---|
| 176 | </pre></blockquote> |
|---|
| 177 | |
|---|
| 178 | <p>If the bind fails, the server will return a numeric error code that corresponds to the cause of the failure:</p> |
|---|
| 179 | |
|---|
| 180 | <p><strong>Example 4. Bind failure</strong></p> |
|---|
| 181 | <blockquote><pre>C: <bind name='conference.jabber.org'/> |
|---|
| 182 | S: <bind error='409'/> |
|---|
| 183 | </pre></blockquote> |
|---|
| 184 | |
|---|
| 185 | <p><strong>Table 1: Error codes</strong></p> |
|---|
| 186 | <table border="1" cellpadding="3" cellspacing="0"> |
|---|
| 187 | <tbody><tr class="body"> |
|---|
| 188 | <th colspan="" rowspan="">Code</th> |
|---|
| 189 | <th colspan="" rowspan="">Meaning</th> |
|---|
| 190 | </tr> |
|---|
| 191 | <tr class="body"> |
|---|
| 192 | <td colspan="" rowspan="">400</td> |
|---|
| 193 | <td colspan="" rowspan="">The "name" attribute is missing or invalid</td> |
|---|
| 194 | </tr> |
|---|
| 195 | <tr class="body"> |
|---|
| 196 | <td colspan="" rowspan="">403</td> |
|---|
| 197 | <td colspan="" rowspan="">The component is not authorised to bind using this name and/or options</td> |
|---|
| 198 | </tr> |
|---|
| 199 | <tr class="body"> |
|---|
| 200 | <td colspan="" rowspan="">409</td> |
|---|
| 201 | <td colspan="" rowspan="">The name that is already bound</td> |
|---|
| 202 | </tr> |
|---|
| 203 | </tbody></table> |
|---|
| 204 | |
|---|
| 205 | </blockquote> |
|---|
| 206 | |
|---|
| 207 | <blockquote> |
|---|
| 208 | <h3>3.4 <a name="sect-id2588777">Unbinding a domain</a> |
|---|
| 209 | </h3> |
|---|
| 210 | <p>A component may unbind a domain is has previously bound by sending a packet like the following:</p> |
|---|
| 211 | |
|---|
| 212 | <p><strong>Example 5. Unbinding a domain</strong></p> |
|---|
| 213 | <blockquote><pre>C: <unbind name='conference.jabber.org'/> |
|---|
| 214 | S: <unbind/> |
|---|
| 215 | </pre></blockquote> |
|---|
| 216 | |
|---|
| 217 | <p>Once unbound, the component may no longer send or receive packets for the domain.</p> |
|---|
| 218 | |
|---|
| 219 | <p>If the unbind fails, the server will return a numeric error code that corresponds to the cause of the failure:</p> |
|---|
| 220 | |
|---|
| 221 | <p><strong>Example 6. Unbind failure</strong></p> |
|---|
| 222 | <blockquote><pre>C: <unbind name='conference.jabber.org'/> |
|---|
| 223 | S: <unbind error='403'/> |
|---|
| 224 | </pre></blockquote> |
|---|
| 225 | |
|---|
| 226 | <p><strong>Table 2: Error codes</strong></p> |
|---|
| 227 | <table border="1" cellpadding="3" cellspacing="0"> |
|---|
| 228 | <tbody><tr class="body"> |
|---|
| 229 | <th colspan="" rowspan="">Code</th> |
|---|
| 230 | <th colspan="" rowspan="">Meaning</th> |
|---|
| 231 | </tr> |
|---|
| 232 | <tr class="body"> |
|---|
| 233 | <td colspan="" rowspan="">400</td> |
|---|
| 234 | <td colspan="" rowspan="">The "name" attribute is missing or invalid</td> |
|---|
| 235 | </tr> |
|---|
| 236 | <tr class="body"> |
|---|
| 237 | <td colspan="" rowspan="">404</td> |
|---|
| 238 | <td colspan="" rowspan="">The name is not bound to this component</td> |
|---|
| 239 | </tr> |
|---|
| 240 | </tbody></table> |
|---|
| 241 | |
|---|
| 242 | <p>If the component disconnects or closes the stream, any domains bound to it will be automatically unbound.</p> |
|---|
| 243 | </blockquote> |
|---|
| 244 | |
|---|
| 245 | <blockquote> |
|---|
| 246 | <h3>3.5 <a name="sect-id2589010">Sending packets</a> |
|---|
| 247 | </h3> |
|---|
| 248 | <p>Packets are sent and received using the <route/> element:</p> |
|---|
| 249 | |
|---|
| 250 | <p><strong>Example 7. A simple packet</strong></p> |
|---|
| 251 | <blockquote><pre><route from='s2s' to='conference.jabber.org'> |
|---|
| 252 | <message xmlns='jabber:client' to='jdev@conference.jabber.org/rob' from='rob@cataclysm.cx/laptop' type='groupchat'> |
|---|
| 253 | <body>oh, how I wish we could kick people</body> |
|---|
| 254 | </message> |
|---|
| 255 | </route> |
|---|
| 256 | </pre></blockquote> |
|---|
| 257 | |
|---|
| 258 | <p>The "to" and "from" attributes on the |
|---|
| 259 | <route/> are required, and may not be spoofed. With jabberd 2.0, |
|---|
| 260 | the router will bounce or drop packets that do not have both of these |
|---|
| 261 | attributes, or has a from address that does not match one of the |
|---|
| 262 | domains bound to the sending component. Route addresses are always |
|---|
| 263 | domains; there are no nodes or resources.</p> |
|---|
| 264 | |
|---|
| 265 | <p>The router will treat the payload as an opaque XML chunk. All routing decisions are based solely on the route "to" attribute.</p> |
|---|
| 266 | |
|---|
| 267 | <p>If |
|---|
| 268 | a route packet is invalid or undeliverable for some reason, it will be |
|---|
| 269 | returned to the sender. The "to" and "from" attributes will be swapped, |
|---|
| 270 | and an "error" attribute will be added, containing a numeric error code |
|---|
| 271 | that corresponds to the cause of the failure:</p> |
|---|
| 272 | |
|---|
| 273 | <p><strong>Example 8. Error packet</strong></p> |
|---|
| 274 | <blockquote><pre><route from='conference.jabber.org' to='s2s' error='404'> |
|---|
| 275 | <message xmlns='jabber:client' to='jdev@conference.jabber.org/rob' from='rob@cataclysm.cx/laptop' type='groupchat'> |
|---|
| 276 | <body>oh, how I wish we could kick people</body> |
|---|
| 277 | </message> |
|---|
| 278 | </route> |
|---|
| 279 | </pre></blockquote> |
|---|
| 280 | |
|---|
| 281 | <p><strong>Table 3: Error codes</strong></p> |
|---|
| 282 | <table border="1" cellpadding="3" cellspacing="0"> |
|---|
| 283 | <tbody><tr class="body"> |
|---|
| 284 | <th colspan="" rowspan="">Code</th> |
|---|
| 285 | <th colspan="" rowspan="">Meaning</th> |
|---|
| 286 | </tr> |
|---|
| 287 | <tr class="body"> |
|---|
| 288 | <td colspan="" rowspan="">400</td> |
|---|
| 289 | <td colspan="" rowspan="">The route is a unicast and the "to" or "from" |
|---|
| 290 | attributes are missing or invalid, or the route is a broadcast and the |
|---|
| 291 | "to" attribute is missing or invalid.</td> |
|---|
| 292 | </tr> |
|---|
| 293 | <tr class="body"> |
|---|
| 294 | <td colspan="" rowspan="">401</td> |
|---|
| 295 | <td colspan="" rowspan="">The "from" attribute is not set to a name that is bound to the sending component</td> |
|---|
| 296 | </tr> |
|---|
| 297 | <tr class="body"> |
|---|
| 298 | <td colspan="" rowspan="">404</td> |
|---|
| 299 | <td colspan="" rowspan="">The destination name is not bound, and there is no default route</td> |
|---|
| 300 | </tr> |
|---|
| 301 | </tbody></table> |
|---|
| 302 | |
|---|
| 303 | </blockquote> |
|---|
| 304 | |
|---|
| 305 | <blockquote> |
|---|
| 306 | <h3>3.6 <a name="sect-id2589170">Broadcast packets</a> |
|---|
| 307 | </h3> |
|---|
| 308 | <p>A component may send a broadcast packet by sending a <route/></p> |
|---|
| 309 | |
|---|
| 310 | <p><strong>Example 9. A broadcast packet</strong></p> |
|---|
| 311 | <blockquote><pre><route from='c2s' type='broadcast'> |
|---|
| 312 | <payload xmlns='payload-namespace'/> |
|---|
| 313 | </route> |
|---|
| 314 | </pre></blockquote> |
|---|
| 315 | |
|---|
| 316 | <p>(Although this is implemented by the |
|---|
| 317 | jabberd 2.0 router, its not actually used anywhere, and so a working |
|---|
| 318 | example is hard to provide).</p> |
|---|
| 319 | |
|---|
| 320 | <p>The router will then distribute this packet to every other component currently connected.</p> |
|---|
| 321 | </blockquote> |
|---|
| 322 | |
|---|
| 323 | <blockquote> |
|---|
| 324 | <h3>3.7 <a name="sect-id2589209">Domain advertisements</a> |
|---|
| 325 | </h3> |
|---|
| 326 | <p>When a component binds a domain, all the other components |
|---|
| 327 | currently attached will receive notice of the fact via a |
|---|
| 328 | <presence/> packet from the router:</p> |
|---|
| 329 | |
|---|
| 330 | <p><strong>Example 10. Domain advertisement</strong></p> |
|---|
| 331 | <blockquote><pre><presence from='conference.jabber.org'/> |
|---|
| 332 | </pre></blockquote> |
|---|
| 333 | |
|---|
| 334 | <p>(The jabberd 2.0 session manager uses this |
|---|
| 335 | to good effect to probe new components for service information in order |
|---|
| 336 | to populate the disco, browse and agents lists).</p> |
|---|
| 337 | |
|---|
| 338 | <p>Similarly, when a component unbinds a domain, all the other components are informed:</p> |
|---|
| 339 | |
|---|
| 340 | <p><strong>Example 11. Domain "unadvertisement"</strong></p> |
|---|
| 341 | <blockquote><pre><presence from='conference.jabber.org' type='unavailable'/> |
|---|
| 342 | </pre></blockquote> |
|---|
| 343 | </blockquote> |
|---|
| 344 | |
|---|
| 345 | <blockquote> |
|---|
| 346 | <h3>3.8 <a name="sect-id2589256">Packet throttling</a> |
|---|
| 347 | </h3> |
|---|
| 348 | <p>A component can ask the router to throttle its packets. |
|---|
| 349 | When the throttle is active, packets destined for the component will be |
|---|
| 350 | queued inside the router. When the throttle is released, the queued |
|---|
| 351 | packets are delivered. This is useful if a component has time-consuming |
|---|
| 352 | tasks to perform and is unable to handle packets at the same time.</p> |
|---|
| 353 | |
|---|
| 354 | <p>The <throttle/> element is a toggle - its up to the component to remember if it is currently throttled or not.</p> |
|---|
| 355 | |
|---|
| 356 | <p><strong>Example 12. Throttling/unthrottling packets</strong></p> |
|---|
| 357 | <blockquote><pre>C: <throttle/> |
|---|
| 358 | S: <throttle/> |
|---|
| 359 | </pre></blockquote> |
|---|
| 360 | </blockquote> |
|---|
| 361 | |
|---|
| 362 | <p></p><hr><p></p> |
|---|
| 363 | <h3>Notes</h3> |
|---|
| 364 | <p> |
|---|
| 365 | <a name="nt-id2592423">1</a>. JEP-0114: Existing Component Protocol <<a href="http://www.jabber.org/jeps/jep-0114.html">http://www.jabber.org/jeps/jep-0114.html</a>>.</p> |
|---|
| 366 | <p> |
|---|
| 367 | <a name="nt-id2593111">2</a>. XMPP Core <<a href="http://www.jabber.org/ietf/">http://www.jabber.org/ietf/</a>> (work in progress).</p> |
|---|
| 368 | </div> |
|---|
| 369 | |
|---|
| 370 | </div></body></html> |
|---|