Monday 13 August 2007

XEP33 implementations: separate service or embedded support?

The current version of XEP-0033: Extended Stanza Addressing says:

The IM service MAY implement multicast directly, or it MAY delegate that chore to a separate service.
Where must a Jabber entity send message and presence stanzas with XEP33 addresses, if they expect them to be routed as specified in XEP33? They must send them to a Jabber entity that advertises this feature: http://jabber.org/protocol/address.

What entities may support this feature? A Jabber server may have embedded support for XEP33, let's suppose the server JID is jabber.example.org. Or it can delegate that task to a separate service, which JID could be multicast.jabber.example.org.

How can a Jabber entity know if his local server supports XEP33? Asking disco#info to the server (which JID is jabber.example.org). However, this is not enough when the server delegates to a separate service. So, the entity should also ask the first-level services provided by the server: chatrooms.jabber.example.org, pubsub.jabber.example.org, ... and also multicast.jabber.example.org.

During my GSoC project, I implemented the server-part of XEP33 in an ejabberd module called mod_multicast. This module provides a separate service just for multicast. This means that an ejabberd server with JID jabber.example.org, with my work installed and enabled, will provide XEP33 support in a service with JID multicast.jabber.example.org.

I implemented it as a separate service service for efficiency reasons. I consider that listening in the main server JID for XEP33-enabled stanzas would need more code (well, no more than 30 lines of code) and more computations than listening in a specific JID.

This is not a big problem with message and presence stanzas since the main server JID is not expected to receive message or presence stanzas at all. But think about iq stanzas. The server receives a lot of iq requests, and sends iq replies. Remember that a XEP33 server will send iq queries, and receive replies from remote servers. I thought that using the main JID both for typical IQ tasks and also for multicasting would be a little mess. So I preferred to keep all multicasting separate in a specific JID.

As XEP33 gets more widely adopted, maybe it makes sense to move all the XEP33 code from mod_multicast to an internal core file, and serve it embedded instead of a separate service. But right now, I think the current solution is clean, efficient, and respects the protocol.

What about clients, and remote servers? Obviously, it isn't efficient to query all the first-level items in the server just to know if one of them supports XEP33. It would be faster to just ask the server. This translates in three aspects: more code, more CPU consumption and more bandwidth consumption.

However, they are not much a problem. Probably 20 or 30 lines of code are enough to program the loop to check all server items. And this check is done only the very first time a server queries other server. Once a server/client knows that jabber.example.org supports XEP33 in multicast.jabber.example.org, this knowledge is stored in cache. When the cache item is obsolete (maybe in 12 or 24 hours), there is no need to perform another full disco traversal! The client only needs to revalidate the cache item, asking features directly to multicast.jabber.example.org.

I'm aware of only three programs that implement XEP33, or a part of it:
  • Openfire server has basic support of XEP33. It provides the feature embedded. It only queries the server, not the services.
  • Psi client has very basic support for sending XEP33 message stanzas. It only queries the server, not the services.
  • Tkabber client has very basic support for showing extended information included in XEP33 message stanzas. Since it does not send XEP33 stanzas, it does not need to query for XEP33 support.
This means that ejabberd's mod_multicast can send to Openfire. But Openfire and Psi can't send to ejabberd because they are unaware that the ejabberd server has XEP33 support in a separate service. Note that all three programs implement XEP33 correctly. And even then, they are incompatible in practice.

Yesterday I chatted about this issue with Gaston Dombiak (Gato from Openfire) and Kevin Smith (Kev from Psi). They are interested in implementing the rest of the XEP, including the part that I explained previously. Of course, this interest is conditioned to the success of the protocol: it must be implemented also by other software, and be widely used.

So, once a new and updated version of XEP33 is published with the improvements that I proposed to Peter Saint-Andre, I'll file a bug report in the Psi and Openfire bug trackers.

Until then, I still need to do some cleaning and profiling in mod_multicast.

2 comments:

Unknown said...

Yes, this is problem for more things. I think some generic protocol for getting special namespace services name from our server. As i can remember, pubsub had big problem in this part also. You dont know where to publish items. Well, pubsub is much more complicated, as there are also receivers who need to get place of published items. Ok, PEP is here for that.

But we may need some other services. In client matter, we may need information about proxy65 service for example. It is not problem of server but client, still we need enumerate all services of our server, or in worse case use predefined proxy's from client settings. There is no other automagic way to get jid of service. XEP33 has similar problem, but it needs save more resources as it is server's job.

Maybe some hint from server would be good. Some thing like iq:get to="myserver"; give me preffered service jid for xmlns="xep33";

server: iq:result from="myserver" jid="multicast.myserver" prio="1" ...

I cannot remeber any other protocol using this, but i believe some might use something like it.

Anyway, is there way to connect your service to another xmpp server? I thought about making similar service in gloox for generic use, so you can connect to ejabberd, jabberd2, jabberd1.4 or any other with component protocol compatible enough.

It used to be all services for jabberd1.4, now everything is only for ejabberd. There are not much external services, i think it should not be too dependent on one implementation.

badlop said...

Maybe mod_multicast can be used with other Jabber servers using Epeios. It is worth investigating.

I add this to my TODO list, and will write a blog post with the results of the tests.

If I succeed, I'll also write a tutorial in how to get it working with jabberd1 (or the server that I try).