Sunday, November 14, 2010

Re-scoping experiment 2 - openfire to ejabberd


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.


In continuation of the re-scoping experiment series, the next attempt was to send stanza's from openfire to ejabberd and look at the behavior of how they are handled.

For the experiment, the versions used are :

ejabberd, Version: 2.1.5
Openfire, Version: 3.6.4

  • The control stanza.
As with previous experiment, the control stanza is a simple message with a body from a user connected to openfire server to a recipient in ejabberd server.

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


This was received as expected by the user connected to ejabberd.
So our basic setup is working fine !


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


If you recall, ejabberd DOES NOT allow this to be transmitted, but openfire does !
On the S2S connection, openfire sends following to ejabberd.




<message xmlns:ns="jabber:client" xml:lang="en" to="mridul@ejabberd.daigoro.net" from="mridul@openfire.daigoro.net/daigoro">
<body>Test 1</body>
</message>

Interestingly, openfire re-scopes not just the top-level message stanza, but also the children !
There is a redundent namespace declaration - which is not used, we can ignore that for now.

At the client connected to ejabberd, we recieve

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


which is essentially what was sent across to begin with.

So final received stanza is same as initially transmitted stanza : but the re-scoping done over s2s if quite interesting.
To further investigate this, we try our second stanza : explicit namespaces all the way to the children.

  • Explicit namespace all over.

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




Over S2S, we have the following sent from openfire to ejabberd :

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


We observe that openfire tries to rescope all elements corresponding to "jabber:client" to "jabber:server".

  • Explicit namespace all over, with custom attributes and child element.
This is an additional test corresponding to previous experiment - to see what happens to attributes and 'unknown' child elements.


<ns:message  xml:lang="en" xmlns:ns="jabber:client" to="mridul@ejabberd.daigoro.net" ns:test_attr_1="test_val1" >
<ns1:body xmlns:ns1="jabber:client" ns1:test_attr2="test_val2">Test 2.1</ns1:body>
<ns1:custom_elem xmlns:ns1="jabber:client" ns1:test_attr2="test_val2">Test 2.2</ns1:custom_elem>
</ns:message>




So here we have two additional attributes : one at the stanza level and one at the child level qualified by ns1 and ns2 for the "jabber:client" namespace.
We also have a additional child element qualified to "jabber:client" namespace.

What gets transmitted from openfire to ejabberd is :


<message xmlns:ns="jabber:client" xml:lang="en" to="mridul@ejabberd.daigoro.net" ns:test_attr_1="test_val1" from="mridul@openfire.daigoro.net/daigoro">
<body xmlns:ns1="jabber:client" ns1:test_attr2="test_val2">Test 2.1</body>
<custom_elem xmlns:ns1="jabber:client" ns1:test_attr2="test_val2">Test 2.2</custom_elem>
</message>



What is received by client in the end is :

<message from="mridul@openfire.daigoro.net/daigoro" ns:test_attr_1="test_val1" xmlns:ns="jabber:client" xml:lang="en" to="mridul@ejabberd.daigoro.net">
<body ns1:test_attr2="test_val2" xmlns:ns1="jabber:client">Test 2.1</body>
<custom_elem ns1:test_attr2="test_val2" xmlns:ns1="jabber:client">Test 2.2</custom_elem>
</message>


So essentially, while re-scoping, openfire seems to be attempting to re-scope all elements while leaving attributes as-is.
This is definitely DIFFERENT from what is done by ejabberd, so we have a definite incompatibility in terms of how re-scoping is handled.


  • Explicit namespace only for child elements.
<message  xml:lang="en" to="mridul@ejabberd.daigoro.net" >
<ns1:body xmlns:ns1="jabber:client" >Test 3</ns1:body>
</message>



What gets sent over S2S from openfire to ejabberd is :

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



So re-scoping is attempted for not just the stanza but also for all child elements.
So essentially, re-scoping rule for openfire seems to be : for any element in "jabber:client" namespace, change namespace to "jabber:server" namespace. This is applicable ONLY to elements, for attributes, openfire does not do any rescoping.

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

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



What gets sent over S2S is:

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



And what is received by the client is :

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


So again, we have an incompatibility - what is sent is NOT what is received.




From these two experiments, we can clearly see that there is incompatibility in terms of how re-scoping is handled by ejabberd and openfire : and so the expectation of what gets received by clients/components compared to what gets sent.

Please note that this was just a simple set of examples targeted at how re-scoping is to be handled, and not contrived cases ! I am sure there are a lot of usecases and variants I am missing !

Hopefully, this issue might get addressed in this or next version of the bis XMPP spec.

No comments:

Post a Comment