duplicate login

Hi,

I'm trying to create a jabber client and I have this issue of duplicate logins. For example, I use my client to connect via http polling using a particular account and resource. Next I use another instance of the client and login using the same account and resource. I noticed that the first client is disconnected without any notices or error messages coming from ejabberd. So it appears that both clients are logged in, when in reality the first one was disconnected when I logged in at the second client using the same account and resource. I tried using an existing jabber client (tkabber) and tried the same thing: I logged in using a particular account and resource, then logged in again in a second instance of tkabber using the same account and resource: same thing happened, the first one disconnected without any warning. I tried sniffing the http traffic and I found nothing unusual, just that the first login is disconnected when a second login is performed. There was no feedback from ejabberd that I could use for notification that my login was disconnected because of a second login of the same account and resource.

Next I looked into RFC3921, just in case I missed something that I should send to the server, and it says there that I have to send this particular xml so that the server knows that I want to establish a session:

Step 1: Client requests session with server:

<iq to='example.com'
    type='set'
    id='sess_1'>
  <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>

Step 2: Server informs client that session has been created:

<iq from='example.com'
    type='result'
    id='sess_1'/>

It says there that when a session is established, the server can either 1) terminate the first session and allow the second session, or 2) deny the second session from being established. In either case, a should be sent to indicate that a login session conflict has occured. I tried sending the xml in Step 1, but I received a feature-not-implemented stream error from ejabberd instead of the expected xml response in Step 2 above.

Question is: how do I know that ejabberd disconnected my first login when I do a second login?

Thanks for your help!

In case of conflict, the socket is closed

This is the full paragrgraph, with some lines bold:

If there is already an active resource of the same name, the server MUST either (1) terminate the active resource and allow the newly-requested session, or (2) disallow the newly-requested session and maintain the active resource. Which of these the server does is up to the implementation, although it is RECOMMENDED to implement case #1. In case #1, the server SHOULD send a stream error to the active resource, terminate the XML stream and underlying TCP connection for the active resource, and return a IQ stanza of type "result" (indicating success) to the newly-requested session. In case #2, the server SHOULD send a stanza error to the newly-requested session but maintain the XML stream for that connection so that the newly-requested session has an opportunity to negotiate a non-conflicting resource identifier before sending another request for session establishment.

It seems ejabberd prefers case #1. In that case, ejabberd SHOULD:

  1. send a stream error to the active resource,
  2. terminate the XML stream
  3. (terminate the) underlying TCP connection for the active resource,
  4. and return a IQ stanza of type "result" (indicating success) to the newly-requested session.

If you use Tkabber on the first connection and enable debugging, this will be reported by Tkabber:

10/25 16:05:40 jlib         (jlib::inmsg) (1) ''
10/25 16:05:40 jlib         error (jlib::inmsg) Socket is closed by server. Disconnecting..

So the TCP socket connection is closed, but no XMPP or XML message is received. This behaviour is in compliance with the RFC since that report messages are not required, they are recommended.

There was no feedback from ejabberd that I could use for notification that my login was disconnected because of a second login of the same account and resource. [...] how do I know that ejabberd disconnected my first login when I do a second login?

You know that ejabberd disconnected your session because the socket was closed by the server. I guess it would be more client-friendly if the server informs with a 'conflict stream error' message, too.

But anyway, your client must be able to handle inadverted socket closing, not only in this particular case, but others too. Even if ejabberd implements the report message, your client would have the same problem with other Jabber servers that do not follow the 'SHOULD'. And what if the server does a restart, or you loose connection to internet? The Jabber client must know that the connection was lost, and the session was closed.

duplicate login

Thanks for your reply. When you mean that the socket was closed by the server, do you mean that this assumes I'm connected via a persistent connection through port 5222, right? But what if I connect via http polling, what does ejabberd do? Does it send server error(ID=-1:0) or bad request(ID=-2:0) to indicate that my http polling session is discontinued?

You're right! If using http-poll, there's no report

You're right! If using http-poll, the client will not be informed in any way. I tried it with Tkabber, that supports http-poll, and since the first client does not receive any XMPP packet, and is not connected using a TCP socket, he does not know he is disconnected.

I'll ask Aleksey about the subject, and submit it to bugzilla. But even if a patch is available, and included in SVN, and the next ejabberd release is published in some months, it will take more time for public servers already deployed to update to the latest versions.

I'll post here updates on this subject.

http polling issue

Thanks for your prompt reply. I thought that I had missed a critical point with http polling connections in ejabberd. I think there should be a way to inform the client that it has been disconnected due to a login with the same account/resource credentials. If we follow the JEP, I think that either a server error (-1:0) or bad request(-2:0) should be sent; then again it would depend on you guys how and what to send. I think it should be easy enough to check this for the client to determine that its session is already invalid.

Hmm, seems like we found a crucial bug in http polling implementation here. Will be waiting for updates on this thread. Thanks!

Feature request added to Bugzilla

I've formalized this feature request sending this to ejabberd's Bugzilla:
Bug 170: Send a warning when the session is replaced.

Good news: fixed on SVN.

Good news: fixed on SVN.

Syndicate content