aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolger Weiss <holger@zedat.fu-berlin.de>2014-05-09 18:28:14 +0200
committerHolger Weiss <holger@zedat.fu-berlin.de>2014-05-09 18:28:14 +0200
commit6d5bfcfe9bdd210e425d88a8e54e68628c881d85 (patch)
treea338956b5b47ce830f905812fb3cd0efd354eb1a
parentXEP-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.erl21
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} ->