%ents; ]>
Redirect and Connection Transfer This document describes redirection of Jabber queries, and a method to replace the current (non standard) use of 302 to redirect connections. This document has been placed in the public domain. 0051 Deferred Standards Track Standards Klaus Wolf wolf@bluehands.de klaus@jabber.bluehands.de Richard Dobson richard@dobson-i.net richard@dobson-i.net 0.1 2002-10-08 psa Initial version. 0.0.2 2002-09-14 rd Added the server transfer section. 0.0.1 2002-07-31 hw Initial version.

To be written.

This document describes a general request redirection mechanism for Jabber queries.

There are cases where only the receiver of a query, e.g. the receiver of <iq type='get'/> requests, knows the real location of the targeted data object. Reasons might be load balancing, changes in the protocol and/or usage patterns, or an additional level of indirection for improved flexibility. The possible reasons are very similar to reasons for (temporary) HTTP redirection.

Redirection adds an additional feature to the protocol. But it also adds also a small amount of complexity to implementations. The mechanism has been designed in a way such that it affects implementations only minimally while providing maximum flexibility.

For security reasons the redirection mechanism is only valid for <iq type='get'/> packets.

A client sends a query to a server. The server may well be an other client acting as a server for this transaction. The server decides that it can not serve the original request. It redirects the request to an other server. In order to do so, it sends a redirection query to the client. The redirection query informs the client about the modified query including the new destination. The client then repeats the request by sending the redirected query to other server.

The meaning of <iq/> queries is specified by multiple parameters, i.e. JID, <query/> namespace, and namespace specific tags and attributes. Many of these parameters may change during the redirection. To allow for maximum flexibility, the redirection query contains the complete redirected query.

The redirection query is identified by the "type" attribute and by the code of an embedded <error/> tag. The code is "302". The redirection is meant to be temporary, not permanent.

The original query is returned as a child of the <iq type='error'/>.

The redirected query sent from the server back to the client is embedded into the <error/> tag.

The envelope of the redirected query must preserve all attributes of the initial query except for the destination JID ("to" attribute). In particular, it must preserve the "id" attribute.

The must not redirect any query other than <iq type='get'/>.

The redirected query may target a different entity than the original query and it may have different parameters. But the redirected query must be manufactured in such a way that the result returned from the redirected query is compatible with the original query.

<iq type='get' from='jid-A' to='jid-B'> original query </iq> <iq type='error' from='jid-B' to='jid-A'> original query <error code='302'>redirection message</error> </iq> <iq type='get' from='jid-A' to='jid-C'> redirected query </iq> A: <iq id='5' type='get' from='user@server-A' to='user@server-B> A: <query xmlns='jabber:iq:browse'/> A: </iq> B: <iq type='error' from='user@server-B' to='user@server-A'> B: <query xmlns='jabber:iq:browse'/> B: <error code='302'> B: <iq id='5' type='get' to='user@server-C'> B: <query xmlns='jabber:iq:browse'/> B: </iq> B: </error> B: </iq> A: <iq id='5' type='get' from='user@server-A' to='user@server-C'> A: <query xmlns='jabber:iq:browse'/> A: </iq> A: <iq id='5' type='get' from='user@server-A' to='user@server-B/work'> A: <query xmlns='jabber:iq:app-specific'/> A: </iq> B: <iq type='error' from='user@server-B/work' to='user@server-A'> B: <query xmlns='jabber:iq:app-specific'/> B: <error code='302'> B: <iq id='5' type='get' to='user@server-B'> B: <query xmlns='storage:client:app-specific'/> B: </iq> B: </error> B: </iq> A: <iq id='5' type='get' from='user@server-A' to='user@server-B'> A: <query xmlns='storage:client:app-specific'/> A: </iq>

The client must check the redirected query. The redirected query is valid only if all three of the following conditions are met:

  1. the original query is <iq type='get'/>
  2. the redirected query is <iq type='get'/>
  3. the <iq/> envelope of the redirected query has all attributes of the original query except for the "to" attribute

If redirections are cascaded then the client should stop the sequence after a reasonable number of redirections. Three consecutive redirects, which make a total of four trials, should be enough.

Applications must not rely on more than three consecutive redirections for a single query.

The redirection mechanism can be implemented transparently for the protocol engine. The client should unwrap the redirected query, check for validity, and send the data to the connection.

Protocol implementations do not have to create a new request context. The request context of the original query will still be valid since the redirector must preserve the query id.

The query id is often used by the protocol engine to relate queries sent and queries received in order to form request-response pairs. Using the query id the client can find the related original query when the result of the redirected query returns.

However, the client must check the validity before re-sending the redirected query.

This document describes a connection transfer mechanism for telling clients (or others) to reconnect to a different address.

This is useful for transfering people to a different server in a cluster if it is going down for maintenance or during login to transfer the person to a certain server in a cluster.

A server needs to be shutdown for maintenance by an administrator but there are other servers available in the cluster and the administrator wants to cause the least disruption possible by having the users automatically reconnect to one of the other available servers. Users of a Jabber cluster are hosted on particular servers, the server the user has connected to is not their server in the cluster, so the server redirects the user to connect to the correct server. A new server is brought online in the cluster. To reduce the load on the other servers and to balance out the load, the other servers direct some of their users to connect to the new server.

The transfer packet is addressed to the user from the domain they are logged into, it contains the server address to connect to which can be domain name or ip address, it can also contain an optional port number. There is also the domain specified just in case they have to use a different domain name when they log in or to maintain the original domain.

<iq type='set' from='jabber.org' to='user@jabber.org'> <query xmlns='jabber:iq:srvxfr'> <domain>jabber.org</domain> <server>123.123.123.122</server> </query> </iq> <iq type='set' from='jabber.org' to='user@jabber.org'> <query xmlns='jabber:iq:srvxfr'> <domain>jabber.org</domain> <server>server2.jabber.org</server> </query> </iq> <iq type='set' from='jabber.org' to='user@jabber.org'> <query xmlns='jabber:iq:srvxfr'> <domain>jabber.org</domain> <server>server3.jabber.org:6222</server> </query> </iq> <iq type='set' from='jabber.org' to='user@jabber.org'> <query xmlns='jabber:iq:srvxfr'> <domain>jabber.org</domain> <server>jabber.org</server> </query> </iq>