powered by Jive Software

Multiple authenticated logins over one socket

Summary

I would like to use a single shared TCP/IP socket to simultaneously host the authenticated presence of multiple resources with different jids/resourcenames.

For example cefn@cefn.org/agent1 and osss@cefn.org/agent1 and another@cefn.org/agent1 would all share a single client socket connected to the same server, over which auth and presence stanzas for the multiple endpoints would be passed. This socket would be simultaneously able to handle inbound and outbound stanzas on behalf of the multiple authenticated XMPP endpoints it hosts.

Questions

Is this socket reuse technically impossible based on the XMPP protocol? If it’s impossible with XMPP we may have to drop it in favour of AQMP or similar in the architecture I’m specifying.

If it’s possible in XMPP I certainly can’t find a way to do it with Smack, (each XMPPConnection can authenticate against only one JID at a time). Does anyone know how to do this?

Background

I’m looking into this as part of a scalable server built on diet-agents, http://diet-agents.sourceforge.net , which can host hundreds of thousands of individually addressable processes on a single machine with a few threads and a single TCP connection.

I would like to be able to address these individual processes or ‘agents’ as uniquely named XMPP endpoints to make wide area coordination easier from other machines independently of language or platform (diet-agents itself requires Java so isn’t suitable on all machines).

However, requiring one TCP/IP socket per XMPP endpoint/agent is a huge step backwards for our scalability, taking the required server resources from a single socket to potentially hundreds of thousands of sockets to host the same number of addressable endpoints.

It would be better to have a single thread waiting on a single XMPP socket which serves multiple agents, wakes them up to handle incoming messages, and sends outbound messages on their behalf using XMPP stanzas.

So far I’ve using one JID per Socket with multiple anonymous identities in different chatrooms, but these identities are not full-fledged Jabber identities, and hence we lose a lot of the benefits of using Jabber in the first place - no Rosters, no Private XML, no Presence etc.

Also, this approach breaks the security model of individual JIDs mapping to individual ‘user’ entities, meaning the server would be unable to handle privacy issues properly.

Grateful for your thoughts if you have the time to read this message.

Cefn
http://cefn.com

Just to note, after having no replies to my question, I looked into various alternatives in some depth.

The question; how to host large numbers of JIDs on a single client machine without one socket per JID to the XMPP server.

I learned that Whack conforms to the XMPP Component protocol, and can therefore make a single TCP/IP connection to an Openfire Hub and route all inbound and outbound packets across it, but has no XMPP-specific functions defined, and is incompatible with Smack (i.e. Smack can’t use Whack as a transport).

I also learned that other XMPP domains can be federated into an Openfire Hub, so our own implementation of an XMPP server on diet-agents.cefn.org can then connect to cefn.org across just two sockets - one outbound and one inbound. Our server can then be responsible for its internal account creation, login and event management without any extra sockets [thanks to Sean Meiners for this suggestion].

The options seem to be…

  1. Use unmodified Openfire and Smack with a modified server which has its own internal subnet and loopback network drivers and hence no socket limitations (a torture)
  2. Use Whack and patch the Smack API to remove the (unnecessary) architectural limitation of one Socket per JID as built into the implementation of XMPPConnection (a fork)
  3. Use Whack and reimplement the subset of Smack XMPP capabilities we need from the ground up (a pain)
  4. Use a different XMPP server (possibly our own implementation) which doesn’t enforce the ‘one Socket per JID’ limitation, and set it up as a peer to Openfire on a separate domain with separate user records (a shame)

My preferred option currently is either 2 or 3, and probably 2 is what we’ll try first in order to try and benefit from the packet unmarshalling and Java API already defined in Smack. In other words we would use Whack to provide an alternate implementation of XMPPConnection, and have to modify the Smack API to support this.

It does make me wonder why this limitation exists, though. A few specific questions…

  • Why does Smack currently rely on XMPPConnection as a concrete class rather than an interface?
  • [If it was an interface, we could implement our own transport with Whack which shares sockets, and solve the problem with no fork]
  • Why does XMPPConnection and Openfire have assumptions built-in that there should be one JID per socket?
  • [It seems like every XMPP XML packet contains source or session identifiers anyway, so there’s no reason I can see why a single socket shouldn’t be authenticated for multiple JIDs at once for scalability.]

I believe that these minor modifications would help these java XMPP libraries to scale in ways more reminiscent of AMQP and be useful for a lot of other applications as a result.

You might consider looking at Openfire’s Connection Manager. OF uses the CM to allow external servers to handle the client connections, so its doing some multiplexing. If you based your client off that, Openfire would require no modifications.

Thanks for the suggestion, Jay.

Given a client library which doesn’t initiate one socket per JID then it would definitely be worth examining the Openfire CM to address the complementary issue on the server side.

However, as a client library, Smack is currently busted in this respect in ways deeply embedded in the XMPPConnection and PacketReader/PacketWriter implementations - a thicket of package-protected cross references and indistinct roles and responsibilities. Until this modularity problem is fixed, the server-side behaviour will be continue to be a symptom of the requests forced on it by the client side implementation.

I’ll have a go at fixing Smack and separating out some of the classes into more self-contained and modular units, but I’m fearful of modding the low level interactions between client and server sockets. One of the advantages of considering Openfire is to be able to rely on a robust XMPP server implementation - if I go throwing my own code into the server-side socket handling then there’s a good chance it’ll go phut, even where we’re using others’ conformant XMPP client libraries to connect to the hub (which wouldn’t make me popular, as well as my bespoke code invalidating any premium support contracts we might hope to sign with Jive if our beta is successful).

My current thinking is to rely on the conformance of an unmodified Openfire server to XEP-0114. This should allow us packets into it and out of it via Whack along a single socket. Then we just need to modify Smack to be more modular, supporting the alternative Whack transport instead of the hard-coded one-TCP/IP-per-JID transport built into XMPPConnection.

For now, since I’ll have to re-engineer Smack anyway, I guess using Whack for packet transport is probably easier than fixing assumptions and socket protocols on both sides of the client-server interaction. Am I barking up the wrong tree?