ejabberd - Comments for "Late unavailable presence can knock a newer session out of a chatroom" https://www.ejabberd.im/node/3261 en Follow up https://www.ejabberd.im/node/3261#comment-53763 <p>As a follow-up for anybody that is interested:</p> <p>First, a quick note on multiple sessions using different resources:<br /> It should be possible for 2 resources on the same basic JID to enter a room and share a nick.<br /> Example scenario:<br /> I connect from home and join a room.<br /> I connect from work and join the same room.<br /> I want to be able to see the messages at home and at work, while at the same time not show up as two separate nicks.</p> <p>This is outlined in XEP-0045 section 7.1.10:<br /> "However, if the bare JID of the present occupant matches the bare JID of the user seeking to enter the room, then the service SHOULD allow entry to the user, so that the user has two (or more) in-room "sessions" with the same roomnick, one for each resource."</p> <p>Unfortunately this is not working in the current release of ejabberd as outlined here: <a href="http://www.ejabberd.im/node/3258" title="http://www.ejabberd.im/node/3258">http://www.ejabberd.im/node/3258</a></p> <p>To accomplish my goal of not having my subsequent session kicked out, I used a combination of unique resources and unique room nicknames. When the first session is replaced, the second session is not affected.<br /> If you are trying to maintain 1 session per username, then it is also vital to set max_user_sessions to 1.</p> Thu, 13 Nov 2008 09:51:57 +0000 yellowdog comment 53763 at https://www.ejabberd.im Still being knocked out of chatrooms https://www.ejabberd.im/node/3261#comment-53717 <p>I thought I would be able to get around this problem if I made sure that I used unique nicknames in the chatroom for the new ejabberd session.</p> <p>I was however mistaken. It seems that ALL chatroom entries for an ejabberd user JID are signed out, rather than just the ones for the particular ejabberd session that has terminated.</p> <p>I thought about using unique resources for the subsequent logins but that won't work for 2 reasons:<br /> 1) I have explicitly set max_user_sessions to 1.<br /> 2) My business logic requires that a user can have only 1 session. I really had hoped that as soon as the new session is created the old session can no longer affect anything.</p> <p>This seems to be a problem for long lived sessions... I imagine that lots of other applications must maintain connectivity after network downtime...</p> <p>I think that this situation can be remedied if ejabberd sends the unavailable presence to the chatrooms before trying to send the unavailable presence to the users JID and not after.</p> Tue, 04 Nov 2008 09:16:32 +0000 yellowdog comment 53717 at https://www.ejabberd.im I've been able to replicate https://www.ejabberd.im/node/3261#comment-53709 <p>I've been able to replicate this using pidgin. I think the reason I don't get a conflict is because the control-server sents the invite...</p> <p>I'm still not sure what is happening with the mixed case usernames in some of the messages... I did see that when I use Psi it tries to change any username I type in to lowercase. I'm using a case-sensitive external auth script.</p> Fri, 31 Oct 2008 16:47:23 +0000 yellowdog comment 53709 at https://www.ejabberd.im I've modified the Lisp xmpp https://www.ejabberd.im/node/3261#comment-53708 <p>I've modified the Lisp xmpp client that I'm using to be more verbose.</p> <p>When my client connects/authorizes/creates a session, it starts out by sending presence to the server:</p> <div class="codeblock"><code>&lt;presence&gt;&lt;/presence&gt;</code></div> <p>It gets a strange response, as if its username were in lower case from the same username in uppercase:</p> <div class="codeblock"><code>&lt;presence from=&quot;3232235945.3434453863.G3448@ejabberd-service/cl-xmpp&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to=&quot;3232235945.3434453863.g3448@ejabberd-service/cl-xmpp&quot;/&gt;</code></div> <p>And vice versa:</p> <div class="codeblock"><code>&lt;presence from=&quot;3232235945.3434453863.g3448@ejabberd-service/cl-xmpp&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to=&quot;3232235945.3434453863.G3448@ejabberd-service/cl-xmpp&quot;/&gt;</code></div> <p>It then sends a message to a server that controls room access via xmpp messages. This server is just another xmpp-client, but is an administrator on the ejabberd server.<br /> The message my client sends asks to be invited to the chatroom. The server does the following:</p> <div class="codeblock"><code>&lt;message from=&quot;myroom@conference.ejabberd-service&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to=&quot;3232235945.3434453863.G3448@ejabberd-service&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type=&quot;normal&quot;&gt;<br />&nbsp; &lt;x xmlns=&quot;http://jabber.org/protocol/muc#user&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;invite from=&quot;control-server@ejabberd-service/cl-xmpp&quot;&gt;&lt;reason&gt;invitation&lt;/reason&gt;&lt;/invite&gt;<br />&nbsp; &lt;/x&gt;<br />&nbsp; &lt;x xmlns=&quot;jabber:x:conference&quot; jid=&quot;myroom@conference.ejabberd-service&quot;&gt;invitation&lt;/x&gt;<br />&nbsp; &lt;body&gt;<br />&nbsp;&nbsp;&nbsp; control-server@ejabberd-service/cl-xmpp invites you to the room myroom@conference.ejabberd-service (invitation)<br />&nbsp; &lt;/body&gt;<br />&lt;/message&gt;</code></div> <p>Next my client joins the room:</p> <div class="codeblock"><code>&lt;presence from=&quot;3232235945.3434453863.G3448@ejabberd-service&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to=&quot;myroom@conference.ejabberd-service/myusername&quot;&gt;<br />&nbsp; &lt;x xmlns=&quot;http://jabber.org/protocol/muc&quot;&gt;&lt;/x&gt;<br />&lt;/presence&gt;</code></div> <p>And receives the confirmation:</p> <div class="codeblock"><code>&lt;presence from=&quot;myroom@conference.ejabberd-service/3232235945.3434453863.G3448&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to=&quot;3232235945.3434453863.G3448@ejabberd-service/cl-xmpp&quot;&gt;<br />&nbsp; &lt;x xmlns=&quot;http://jabber.org/protocol/muc#user&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;item affiliation=&quot;member&quot; role=&quot;visitor&quot;/&gt;<br />&nbsp; &lt;/x&gt;<br />&lt;/presence&gt;</code></div> <p>At some point later, the "Replaced session for" message is logged for the old session and my new session receives the 2 messages:</p> <div class="codeblock"><code>&lt;presence from=&quot;3232235945.3434453863.G3448@ejabberd-service/cl-xmpp&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to=&quot;3232235945.3434453863.g3448@ejabberd-service/cl-xmpp&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type=&quot;unavailable&quot;&gt;<br />&nbsp; &lt;status&gt;Replaced by new connection&lt;/status&gt;<br />&lt;/presence&gt;</code></div> <div class="codeblock"><code>&lt;presence from=&quot;myroom@conference.ejabberd-service/3232235945.3434453863.G3448&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to=&quot;3232235945.3434453863.G3448@ejabberd-service/cl-xmpp&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type=&quot;unavailable&quot;&gt;<br />&nbsp; &lt;status&gt;Replaced by new connection&lt;/status&gt;<br />&nbsp; &lt;x xmlns=&quot;http://jabber.org/protocol/muc#user&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;item affiliation=&quot;member&quot; role=&quot;none&quot;/&gt;<br />&nbsp; &lt;/x&gt;<br />&lt;/presence&gt;</code></div> <p>It seems strange the mixed case messages I'm getting. My usernames are always in uppercase, never in lowercase.<br /> I'll try and look into that aspect a little more as it seems confusing.</p> Fri, 31 Oct 2008 16:00:08 +0000 yellowdog comment 53708 at https://www.ejabberd.im Badlop and I had the https://www.ejabberd.im/node/3261#comment-53707 <p>Badlop and I had the following conversation:</p> <div class="codeblock"><code>[11:42:07] &lt;yellowdog&gt; If you would like to use the proxy server I&#039;m using to simulate a network outage for this problem then I can send you on the details and drop the connection for you.<br />[11:43:40] &lt;badlop&gt; i don&#039;t know how much debugging and how much drops i&#039;ll need to find the lines of code to change, and how much to test the new code :)<br />[11:43:54] &lt;badlop&gt; so i&#039;ll find a cable to drop myself<br />[11:44:23] &lt;badlop&gt; if i can write a patch, i&#039;ll ping you to test<br />[11:44:29] &lt;yellowdog&gt; No worries.&nbsp;&nbsp; Can you reproduce this?<br />[11:45:13] &lt;badlop&gt; when i get a laptop with ethernet connection, probably :)<br />[11:45:48] &lt;yellowdog&gt; Well if you want to verify it with my proxy you can... <br />[11:46:39] &lt;yellowdog&gt; My Erlang isn&#039;t great, but perhaps in ejabberd_c2s.erl:handle_info(replaced, _StateName, StateData) the state needs to change before calling send_text... or send_text needs a tighter timeout...<br />[11:58:52] &lt;badlop&gt; &quot;up to 20 minutes after the second session has been opened and acknowledged&quot;<br />[12:00:32] &lt;badlop&gt; so:<br />1. user@server/res joins room@conference.localhost<br />2. the client crashes in such way that ejabberd doesn&#039;t notice<br />3. user joins again<br />4. ejabberd &#039;disconnects&#039; the old connection<br />5. 20 minutes after 3., the second connection is kicked of the room<br />right?<br />[12:01:08] &lt;yellowdog&gt; correct<br />[12:01:53] &lt;yellowdog&gt; One point I didn&#039;t mention, I have {max_user_sessions, 1}. in my ejabberd.cfg<br />[12:02:00] &lt;badlop&gt; did you find where those &#039;20 minutes&#039; are specified?<br />[12:02:07] &lt;badlop&gt; maybe that timeout is of TCP, not ejabberd<br />[12:02:41] &lt;yellowdog&gt; Could be... it&#039;s just the time that I observed in the log which I posted to the forum.<br />[12:03:21] &lt;yellowdog&gt; I don&#039;t think having a different timeout is a sufficient solution anyway.&nbsp;&nbsp; You&#039;d just be lowering the possibility of a race condition.<br />[12:04:15] &lt;badlop&gt; what i wanted is to make experiments shorter to run :)<br />[12:04:35] &lt;yellowdog&gt; Ah :)<br />[12:06:37] &lt;yellowdog&gt; I imagine that the socket timeout would be specified when the socket is created, that would allow the OS to take care of it in a thread-safe way.&nbsp;&nbsp; I guess 20 minutes could be a default, since it seems rather long, so it would then depend on the library that you&#039;re interfacing with.<br />[12:11:27] &lt;badlop&gt; in 3. room doesn&#039;t allow second client to login, because first client is already using the nick<br />[12:12:43] &lt;badlop&gt; you have this, right?<br />{access, max_user_sessions, [{1, all}]}.<br />[12:14:36] &lt;yellowdog&gt; I don&#039;t have it defined like that<br />[12:14:47] &lt;yellowdog&gt; It&#039;s defined as I mentioned above.<br />[12:15:20] &lt;yellowdog&gt; Hmmm.&nbsp;&nbsp; I&#039;ll need to check into what you just said about the room not allowing the second client to join... maybe I&#039;m missing a message from the server.<br />[12:15:39] &lt;yellowdog&gt; (i.e. my client cl-xmpp is ignoring it)<br />[12:17:39] &lt;badlop&gt; the option max_user_sessions is mean to be defined like i said:<br /><noindex><a href="http://svn.process-one.net/ejabberd/trunk/doc/guide.html#configmaxsessions" title="http://svn.process-one.net/ejabberd/trunk/doc/guide.html#configmaxsessions" rel="nofollow" >http://svn.process-one.net/ejabberd/trunk/doc/guide.html#configmaxsessions</a></noindex><br />[12:18:10] &lt;yellowdog&gt; I see... perhaps it&#039;s something that was leftover from our old 1.1.2 installation.&nbsp;&nbsp; I&#039;ll change this and try my test again.<br />[12:21:27] &lt;badlop&gt; in 3., my client sends: <p>&lt;presence to=&#039;room@conference.localhost/participant&#039;<br />&nbsp; xml:lang=&#039;es&#039;&gt;<br />&nbsp; &lt;show&gt;dnd&lt;/show&gt;<br />&nbsp; &lt;status&gt;No molestar&lt;/status&gt;<br />&nbsp; &lt;x xmlns=&#039;http://jabber.org/protocol/muc&#039;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;password/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;history maxchars=&#039;10000&#039;<br />&nbsp; maxstanzas=&#039;20&#039;/&gt;<br />&nbsp; &lt;/x&gt;<br />&lt;/presence&gt;</p> <p>and it receives:<br />&lt;presence from=&#039;room@conference.localhost/participant&#039;<br />&nbsp; xml:lang=&#039;es&#039;<br />&nbsp; type=&#039;error&#039;<br />&nbsp; to=&#039;testt@localhost/tka&#039;&gt;<br />&nbsp; &lt;show&gt;dnd&lt;/show&gt;<br />&nbsp; &lt;status&gt;No molestar&lt;/status&gt;<br />&nbsp; &lt;x xmlns=&#039;http://jabber.org/protocol/muc&#039;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;password/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;history maxstanzas=&#039;20&#039;<br />&nbsp; maxchars=&#039;10000&#039;/&gt;<br />&nbsp; &lt;/x&gt;<br />&nbsp; &lt;error type=&#039;cancel&#039;<br />&nbsp; code=&#039;409&#039;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;conflict xmlns=&#039;urn:ietf:params:xml:ns:xmpp-stanzas&#039;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;text xmlns=&#039;urn:ietf:params:xml:ns:xmpp-stanzas&#039;&gt;El apodo ya está siendo usado por otro ocupante&lt;/text&gt;<br />&nbsp; &lt;/error&gt;<br />&lt;/presence&gt;<br />[12:21:42] &lt;badlop&gt; &quot;the nickname is already used by other participant&quot;<br />[12:28:37] &lt;yellowdog&gt; Hmmm... I&#039;ll look into this... I don&#039;t think I get that.&nbsp;&nbsp; It does make sense though.</p></code></div> Fri, 31 Oct 2008 15:55:36 +0000 yellowdog comment 53707 at https://www.ejabberd.im Here are the appropriate log messages https://www.ejabberd.im/node/3261#comment-53706 <p>Here are the appropriate log messages for this with the port numbers highlighted.<br /> At around 2008-10-31 10:00:00 I simulated a disconnect by dropping the network connection of the first session.<br /> At 2008-10-31 10:21:17 my most recent session was knocked out of the chatroom it had joined:</p> <p>=INFO REPORT==== 2008-10-31 09:57:54 ===<br /> I(&lt;0.233.0&gt;:ejabberd_listener:112) : (<strong>#Port&lt;0.446&gt;</strong>) Accepted connection {{proxyipaddress},3756} -&gt; {{serveripaddress},5222}</p> <p>=INFO REPORT==== 2008-10-31 09:57:58 ===<br /> I(&lt;0.236.0&gt;:extauth:73) : extauth call '["auth", "myusername", "ejabberd-service",<br /> "mypassword"]' received data response: [0,1]</p> <p>=INFO REPORT==== 2008-10-31 09:57:58 ===<br /> I(&lt;0.402.0&gt;:ejabberd_c2s:560) : ({socket_state,tls,{tlssock,<strong>#Port&lt;0.446&gt;</strong>,#Port&lt;0<br /> .448&gt;},&lt;0.401.0&gt;}) Accepted authentication for myusername</p> <p>=INFO REPORT==== 2008-10-31 09:57:59 ===<br /> I(&lt;0.402.0&gt;:ejabberd_c2s:805) : ({socket_state,tls,{tlssock,<strong>#Port&lt;0.446&gt;</strong>,#Port&lt;0<br /> .448&gt;},&lt;0.401.0&gt;}) Opened session for myusername@ejabberd-service/cl-xmpp</p> <p>=INFO REPORT==== 2008-10-31 10:01:38 ===<br /> I(&lt;0.233.0&gt;:ejabberd_listener:112) : (<strong>#Port&lt;0.459&gt;</strong>) Accepted connection {{proxyipaddress},3834} -&gt; {{serveripaddress},5222}</p> <p>=INFO REPORT==== 2008-10-31 10:01:42 ===<br /> I(&lt;0.236.0&gt;:extauth:73) : extauth call '["auth", "myusername", "ejabberd-service",<br /> "mypassword"]' received data response: [0,1]</p> <p>=INFO REPORT==== 2008-10-31 10:01:42 ===<br /> I(&lt;0.409.0&gt;:ejabberd_c2s:560) : ({socket_state,tls,{tlssock,<strong>#Port&lt;0.459&gt;</strong>,#Port&lt;0<br /> .461&gt;},&lt;0.408.0&gt;}) Accepted authentication for myusername</p> <p>=INFO REPORT==== 2008-10-31 10:01:45 ===<br /> I(&lt;0.409.0&gt;:ejabberd_c2s:805) : ({socket_state,tls,{tlssock,<strong>#Port&lt;0.459&gt;</strong>,#Port&lt;0<br /> .461&gt;},&lt;0.408.0&gt;}) Opened session for myusername@ejabberd-service/cl-xmpp</p> <p>=INFO REPORT==== 2008-10-31 10:21:17 ===<br /> I(&lt;0.402.0&gt;:ejabberd_c2s:1297) : ({socket_state,tls,{tlssock,<strong>#Port&lt;0.446&gt;</strong>,#Port&lt;<br /> 0.448&gt;},&lt;0.401.0&gt;}) Replaced session for myusername@ejabberd-service/cl-xmpp</p> Fri, 31 Oct 2008 10:40:28 +0000 yellowdog comment 53706 at https://www.ejabberd.im