On stanza queue overflow, pass a message to self() using the exclamation
mark operator instead of send_all_state_event/2. This allows for
reusing the existing handler for 'kick' events.
On queue overflow, terminate the c2s session instead of just dropping
items from the queue. This makes sure all stanzas are either delivered
or bounced.
When the FSM goes into the 'wait_for_resume' state, let fsm_next_state/2
take care of updating #state.mgmt_state and of writing the log line.
This doesn't change the behavior, but simplifies the code.
The 'previd' value provided by the client during a session resume
request includes the client's JID and ejabberd's session ID. If there
is a session for the requested JID but with a different session ID,
resumption should fail, but that session shouldn't be closed. This
commit makes sure the latter won't happen.
In practice, this will only make a difference in odd corner cases.
If stream management is enabled, don't exit the c2s process when
ejabberd_socket:send/2 fails, but close the socket instead. This gives
the client a chance to resume the session.
Thanks go to Matthias Rieber for reporting the issue, providing detailed
logs, and testing the fix.
Only the child elements of <iq/> stanzas are qualified by the namespaces
in question, not the <iq/> stanzas themselves.
This change just clarifies the code. It doesn't alter the behaviour, as
those <iq/> stanzas are handed over to jlib:iq_to_xml/1, and that
function ignores the 'xmlns' attribute anyway.
Only stanzas are subject to stream management, so when XEP-0198 support
is enabled, we must distinguish them from non-stanza elements. This
commit adds a send_packet/2 function that can be used in place of
send_stanza/2 or send_element/2 whenever a packet is delivered that
might or might not be a stanza.
If the client says that it handled more stanzas than we sent (due to a
bug in the client's or in our code), increase our outgoing stanza count
accordingly. There's no point in sticking to the old value even if it
was correct, as the client surely won't fix its count during the current
session.
Do not log a warning (but only a debug message) if the client sends an
invalid </a> packet. Some clients do that occasionally, and there's
nothing server admininistrators could do about that.
There are corner cases where certain clients acknowledge more stanzas
than they received. Nothing really bad will happen in those cases, and
server administrators can't do anything about such issues anyway.
Due to timing issues, ejabberd_c2s might receive stream elements from
the client while the session is waiting for stream resumption. Those
elements are now accepted.
Log an informational message when a session goes into the pending state
(waiting for resumption) after the connection was lost. Administrators
may well be interested in this state change when looking into issues.
On connection timeout, drop any messages that were forwarded by some
encapsulating protocol, such as XEP-0280 carbon copies or XEP-0313
archive messages. Bouncing or resending them could easily lead to
unexpected results.
Implement the optional session resumption feature described in XEP-0198.
A client that supports this feature may now resume the previous session
(within a configurable number of seconds) if the connection was lost.
During resumption, ejabberd will retransmit any stanzas that hadn't been
acknowledged by the client.
Implement partial support for XEP-0198: Stream Management. After
successful negotiation of this feature, the server requests an ACK for
each stanza transmitted to the client and responds to ACK requests
issued by the client. On session termination, the server re-routes any
unacknowledged stanzas. The length of the pending queue can be limited
by setting the "max_ack_queue" option to some integer value (default:
500). XEP-0198 support can be disabled entirely by setting the
"stream_management" option to false (default: true).
So far, stream management is implemented only for c2s connections, and
the optional stream resumption feature also described in XEP-0198 is not
(yet) supported.
This addition was originally based on a patch provided by Magnus Henoch
and updated by Grzegorz Grasza. Their code implements an early draft of
XEP-0198 for some previous version of ejabberd. It has since been
rewritten almost entirely.