From 6d5bfcfe9bdd210e425d88a8e54e68628c881d85 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Fri, 9 May 2014 18:28:14 +0200 Subject: [PATCH] XEP-0198: Improve handling of too large 'h' values 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. --- src/ejabberd_c2s.erl | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 0897730a5..9ce66d043 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -2686,16 +2686,13 @@ handle_r(StateData) -> send_element(StateData, Res), StateData. -handle_a(#state{jid = JID, mgmt_stanzas_out = NumStanzasOut} = StateData, - Attrs) -> +handle_a(StateData, Attrs) -> case catch jlib:binary_to_integer(xml:get_attr_s(<<"h">>, Attrs)) of H when is_integer(H), H >= 0 -> - ?DEBUG("~s acknowledged ~B of ~B stanzas", - [jlib:jid_to_string(JID), H, NumStanzasOut]), - mgmt_queue_drop(StateData, H); + check_h_attribute(StateData, H); _ -> ?DEBUG("Ignoring invalid ACK element from ~s", - [jlib:jid_to_string(JID)]), + [jlib:jid_to_string(StateData#state.jid)]), StateData end. @@ -2728,7 +2725,7 @@ handle_resume(StateData, Attrs) -> end, case R of {ok, ResumedState, NumHandled} -> - NewState = mgmt_queue_drop(ResumedState, NumHandled), + NewState = check_h_attribute(ResumedState, NumHandled), AttrXmlns = NewState#state.mgmt_xmlns, AttrId = make_resume_id(NewState), AttrH = jlib:integer_to_binary(NewState#state.mgmt_stanzas_in), @@ -2754,6 +2751,16 @@ handle_resume(StateData, Attrs) -> error end. +check_h_attribute(#state{mgmt_stanzas_out = NumStanzasOut} = StateData, H) + when H > NumStanzasOut -> + ?DEBUG("~s acknowledged ~B stanzas, but only ~B were sent", + [jlib:jid_to_string(StateData#state.jid), H, NumStanzasOut]), + mgmt_queue_drop(StateData#state{mgmt_stanzas_out = H}, NumStanzasOut); +check_h_attribute(#state{mgmt_stanzas_out = NumStanzasOut} = StateData, H) -> + ?DEBUG("~s acknowledged ~B of ~B stanzas", + [jlib:jid_to_string(StateData#state.jid), H, NumStanzasOut]), + mgmt_queue_drop(StateData, H). + update_num_stanzas_in(#state{mgmt_state = active} = StateData, El) -> NewNum = case {is_stanza(El), StateData#state.mgmt_stanzas_in} of {true, 4294967295} ->