Sunday, November 14, 2010

Re-scoping experiment 1 - ejabberd to openfire

Update: I re-ran the exact same experiment using nc to simulate a client which does prefix free canonicalization and got exact same result.
To do so, initial stream is opened with xmlns="jabber:client", but subsequent (post-auth) stream does not have xmlns set to jabber:client. Here is an example of how to do it.


As mentioned in a previous post, I was wondering how rescoping was supposed to be handled in a general case. That is, server gets an xml stanza from client meant for a (user on) remote server and has to, as robustly possible, re-scope it to ensure successful delivery.


ASCII magic :-P

user1 -- c2s --> server1 --- s2s ---> server2 -- c2s --> user2

Re-scoping is required since the stanza namespace expected over s2s is "jabber:server" while over c2s is "jabber:client".

Please note: server1 and server2 here will be on different domains, most probably different implementations : ditto for the clients. So we are touching atleast 4 different XMPP codebases.



Now that intro is done, let us move on.

As a first experiment I tried a simple one - I set up ejabberd and openfile servers on my box, tapped their s2s communication, used psi as both transmitting and receiving client and then started sending stanza's of interest to see the behavior.
I will, time permitting ofcourse, try other servers later on !

My assumption was, these are fairly popular servers, and so would be instructive to see how they currently handle this.



From ejabberd to openfire.

Openfire, Version: 3.6.4
ejabberd, Version: 2.1.5



  • The control stanza.

<message  to="mridul@openfire.daigoro.net" xml:lang="en">
<body>Test 0</body>
</message>

This made it all the way through, the only (expected) change was the addition of a "from" attribute by ejabberd server before sending stanza to openfire.

So our basic setup is sound and works fine.



  • Top level stanza with explicit namespace.
<ns:message xml:lang="en" xmlns:ns="jabber:client" to="mridul@openfire.daigoro.net" ><ns:body>Test 1</ns:body>
</ns:message>

This DOES NOT make it through.
It reaches the ejabberd server, but nothing over the S2S connection to openfire.

On the other hand, the bis spec does discourage this practice - I will need to hack up my own xmpp client (suggestions anyone ?) to try out prefix-free canonicalization to see if it works.
I hope this did not work 'cos of ejabberd conforming to this restriction from the spec !



  • Explicit namespace all over.
<ns:message  xml:lang="en" xmlns:ns="jabber:client" to="mridul@openfire.daigoro.net" >
<ns1:body xmlns:ns1="jabber:client" >Test 2</ns1:body>
</ns:message>


Since the previous stanza had issues, I did not really expect this one to go through, and it did not.



  • Explicit namespace only for child elements.

<message xml:lang="en" to="mridul@openfire.daigoro.net" >
<ns1:body xmlns:ns1="jabber:client" >Test 3</ns1:body>
</message>



This was interesting case - the stanza did not have any explicit namespace, while the child (body) was explicitly qualified to "jabber:client".
The observations were :
  1. ejabberd DID NOT re-scope the child element. So, the body continued to be in the explicitly declared "jabber:client" namespace.
  2. openfire stripped the explicit "jabber:client" namespace before forwarding to user2.
Interesting result this.



  • Variant of above - with explicit "jabber:server" namespace.

The body sub-element is explicitly qualified with "jabber:server" namespace by the client.
<message xml:lang="en" to="mridul@openfire.daigoro.net" >
<ns1:body xmlns:ns1="jabber:server" >Test 4</ns1:body>
</message>


And there-in lay the surprise, ejabberd exhibited a behavior consistent with the previous case : it seems to check only namespace at the stanza level and pretty much treats everything else inside as 'opaque'.
So it transmitted the body with the explicit "jabber:server" namespace to openfire.

<message from='mridul@ejabberd.daigoro.net/daigoro' to='mridul@openfire.daigoro.net' xml:lang='en'>
<ns1:body xmlns:ns1='jabber:server'>Test 4</ns1:body>
</message>

But openfire's behavior was unexpected (atleast compared to how ejabberd worked).
It rescoped the body to "jabber:client" namespace !
So user 2 received :

<message from="mridul@ejabberd.daigoro.net/daigoro" xml:lang="en" to="mridul@openfire.daigoro.net">
<body>Test 4</body>
</message>

which is definitely NOT what was sent !

Ah, so we have our first 'breakage'.
What was sent was NOT what was received.



  • Variant of above - with explicit custom namespace.

The breakage above could be either due to
  1. re-scoping error by openfire
  2. a general namespace handling error.
In order to validate which one it was, I sent another stanza : this time, body was explicitly namespaced with a custom namespace.

<message  xml:lang="en" to="mridul@openfire.daigoro.net" >
<ns1:body xmlns:ns1="dummy:custom:ns" >Test 5</ns1:body>
</message>

We received this as-is at the recipient client : so what we observed in the previous case was definitely a re-scoping error : and NOT a general namespace handling issue with openfire.

So we have our first case of re-scoping incompatibility.
Sure, it can be argued that this is contrived since client's dont use "jabber:server" namespace. My point would essentially be, I would rather prevent this from happening to begin with than to see breakages in the wild.



In next post, we will try to see how the openfire to ejabberd communication works.


No comments:

Post a Comment