diff options
author | Holger Weiss <holger@zedat.fu-berlin.de> | 2014-05-09 18:28:14 +0200 |
---|---|---|
committer | Holger Weiss <holger@zedat.fu-berlin.de> | 2014-05-09 18:28:14 +0200 |
commit | 6d5bfcfe9bdd210e425d88a8e54e68628c881d85 (patch) | |
tree | a338956b5b47ce830f905812fb3cd0efd354eb1a | |
parent | XEP-0198: Reject <resume/> with negative 'h' value (diff) |
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.
-rw-r--r-- | src/ejabberd_c2s.erl | 21 |
1 files 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} -> |