diff options
author | Holger Weiss <holger@zedat.fu-berlin.de> | 2014-03-25 23:23:38 +0100 |
---|---|---|
committer | Holger Weiß <holger@zedat.fu-berlin.de> | 2014-03-25 23:23:38 +0100 |
commit | a97c716352c3baec1416f5e0ee303c996bb5900c (patch) | |
tree | 5467e575056ef37863369efaca0fa6384f934419 /src/ejabberd_c2s.erl | |
parent | Remove "fun" element from c2s #state (diff) |
XEP-0198: Bounce unacked stanzas by default
If the new "resend_on_timeout" option is set to false (which it is by
default), bounce any unacknowledged stanzas instead of re-routing them.
Diffstat (limited to 'src/ejabberd_c2s.erl')
-rw-r--r-- | src/ejabberd_c2s.erl | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 4955f6e42..0051266c7 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -115,6 +115,7 @@ max_ack_queue, pending_since, resume_timeout, + resend_on_timeout, n_stanzas_in = 0, n_stanzas_out = 0, lang}). @@ -304,6 +305,7 @@ init([{SockMod, Socket}, Opts]) -> Timeout when is_integer(Timeout), Timeout >= 0 -> Timeout; _ -> 300 end, + ResendOnTimeout = proplists:get_bool(resend_on_timeout, Opts), IP = peerip(SockMod, Socket), %% Check if IP is blacklisted: case is_ip_blacklisted(IP) of @@ -328,7 +330,8 @@ init([{SockMod, Socket}, Opts]) -> access = Access, shaper = Shaper, ip = IP, sm_state = StreamMgmtState, max_ack_queue = MaxAckQueue, - resume_timeout = ResumeTimeout}, + resume_timeout = ResumeTimeout, + resend_on_timeout = ResendOnTimeout}, {ok, wait_for_stream, StateData, ?C2S_OPEN_TIMEOUT} end. @@ -1757,7 +1760,7 @@ terminate(_Reason, StateName, StateData) -> StateData#state.pres_a, Packet), presence_broadcast(StateData, From, StateData#state.pres_i, Packet), - resend_unacked_stanzas(StateData); + handle_unacked_stanzas(StateData); _ -> ?INFO_MSG("(~w) Close session for ~s", [StateData#state.socket, @@ -1787,7 +1790,7 @@ terminate(_Reason, StateName, StateData) -> presence_broadcast(StateData, From, StateData#state.pres_i, Packet) end, - resend_unacked_stanzas(StateData) + handle_unacked_stanzas(StateData) end, bounce_messages(); true -> @@ -2714,7 +2717,7 @@ handle_resume(StateData, Attrs) -> {<<"previd">>, AttrId}], children = []}), SendFun = fun(_F, _T, El) -> send_element(NewState, El) end, - resend_unacked_stanzas(NewState, SendFun), + handle_unacked_stanzas(NewState, SendFun), send_element(NewState, #xmlel{name = <<"r">>, attrs = [{<<"xmlns">>, AttrXmlns}], @@ -2782,33 +2785,40 @@ limit_queue_length(#state{jid = JID, StateData end. -resend_unacked_stanzas(StateData, F) when StateData#state.sm_state == active; +handle_unacked_stanzas(StateData, F) when StateData#state.sm_state == active; StateData#state.sm_state == pending -> Queue = StateData#state.ack_queue, case queue:len(Queue) of 0 -> ok; N -> - ?INFO_MSG("Resending ~B unacknowledged stanzas to ~s", + ?INFO_MSG("~B stanzas were not acknowledged by ~s", [N, jlib:jid_to_string(StateData#state.jid)]), lists:foreach( - fun({Num, #xmlel{attrs = Attrs} = El}) -> + fun({_, #xmlel{attrs = Attrs} = El}) -> From_s = xml:get_attr_s(<<"from">>, Attrs), From = jlib:string_to_jid(From_s), To_s = xml:get_attr_s(<<"to">>, Attrs), To = jlib:string_to_jid(To_s), - ?DEBUG("Resending unacknowledged stanza #~B from ~s to ~s", - [Num, From_s, To_s]), F(From, To, El) end, queue:to_list(Queue)) end; -resend_unacked_stanzas(_StateData, _F) -> +handle_unacked_stanzas(_StateData, _F) -> ok. -resend_unacked_stanzas(StateData) when StateData#state.sm_state == active; +handle_unacked_stanzas(StateData) when StateData#state.sm_state == active; StateData#state.sm_state == pending -> - resend_unacked_stanzas(StateData, fun ejabberd_router:route/3); -resend_unacked_stanzas(_StateData) -> + F = case StateData#state.resend_on_timeout of + true -> + fun ejabberd_router:route/3; + false -> + fun(From, To, El) -> + Err = jlib:make_error_reply(El, ?ERR_SERVICE_UNAVAILABLE), + ejabberd_router:route(To, From, Err) + end + end, + handle_unacked_stanzas(StateData, F); +handle_unacked_stanzas(_StateData) -> ok. inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) -> |