summaryrefslogtreecommitdiff
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-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 0897730a..9ce66d04 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} ->