]> granicus.if.org Git - ejabberd/commitdiff
Don't forget to add invalid XML responses to sending queue
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Thu, 15 Feb 2018 07:18:06 +0000 (10:18 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Thu, 15 Feb 2018 07:18:06 +0000 (10:18 +0300)
src/mod_stream_mgmt.erl

index 48e7ac985fd08dd88c4bf84b91b22e2963e270a2..b6b7e8826d6ccc11d00c890c993a0a953143935d 100644 (file)
@@ -178,20 +178,36 @@ c2s_authenticated_packet(State, Pkt) ->
 
 c2s_handle_recv(#{lang := Lang} = State, El, {error, Why}) ->
     Xmlns = xmpp:get_ns(El),
+    IsStanza = xmpp:is_stanza(El),
     if Xmlns == ?NS_STREAM_MGMT_2; Xmlns == ?NS_STREAM_MGMT_3 ->
            Txt = xmpp:io_format_error(Why),
            Err = #sm_failed{reason = 'bad-request',
                             text = xmpp:mk_text(Txt, Lang),
                             xmlns = Xmlns},
            send(State, Err);
+       IsStanza ->
+           case xmpp:get_type(El) of
+               <<"result">> -> State;
+               <<"error">> -> State;
+               _ ->
+                   Txt = xmpp:io_format_error(Why),
+                   Lang1 = select_lang(Lang, xmpp:get_lang(El)),
+                   Err = xmpp:err_bad_request(Txt, Lang1),
+                   case mgmt_queue_add(State, Err) of
+                       #{mgmt_max_queue := exceeded} = State1 ->
+                           send_policy_violation(State1);
+                       State1 ->
+                           State1
+                   end
+           end;
        true ->
            State
     end;
 c2s_handle_recv(State, _, _) ->
     State.
 
-c2s_handle_send(#{mgmt_state := MgmtState, mod := Mod,
-                 lang := Lang} = State, Pkt, SendResult)
+c2s_handle_send(#{mgmt_state := MgmtState, mod := Mod} = State,
+               Pkt, SendResult)
   when MgmtState == pending; MgmtState == active ->
     case Pkt of
        _ when ?is_stanza(Pkt) ->
@@ -200,10 +216,7 @@ c2s_handle_send(#{mgmt_state := MgmtState, mod := Mod,
                false ->
                    case mgmt_queue_add(State, Pkt) of
                        #{mgmt_max_queue := exceeded} = State1 ->
-                           State2 = State1#{mgmt_resend => false},
-                           Err = xmpp:serr_policy_violation(
-                                   <<"Too many unacked stanzas">>, Lang),
-                           send(State2, Err);
+                           send_policy_violation(State1);
                        State1 when SendResult == ok ->
                            send_rack(State1);
                        State1 ->
@@ -491,7 +504,7 @@ resend_rack(#{mgmt_ack_timer := _,
 resend_rack(State) ->
     State.
 
--spec mgmt_queue_add(state(), xmpp_element()) -> state().
+-spec mgmt_queue_add(state(), xmlel() | xmpp_element()) -> state().
 mgmt_queue_add(#{mgmt_stanzas_out := NumStanzasOut,
                 mgmt_queue := Queue} = State, Pkt) ->
     NewNum = case NumStanzasOut of
@@ -531,8 +544,13 @@ resend_unacked_stanzas(#{mgmt_state := MgmtState,
           [p1_queue:len(Queue), jid:encode(JID)]),
     p1_queue:foldl(
       fun({_, Time, Pkt}, AccState) ->
-             NewPkt = add_resent_delay_info(AccState, Pkt, Time),
-             send(AccState, xmpp:put_meta(NewPkt, mgmt_is_resent, true))
+             Pkt1 = add_resent_delay_info(AccState, Pkt, Time),
+             Pkt2 = if ?is_stanza(Pkt1) ->
+                            xmpp:put_meta(Pkt1, mgmt_is_resent, true);
+                       true ->
+                            Pkt1
+                    end,
+             send(AccState, Pkt2)
       end, State, Queue);
 resend_unacked_stanzas(State) ->
     State.
@@ -669,6 +687,7 @@ add_resent_delay_info(#{lserver := LServer}, El, Time)
   when is_record(El, message); is_record(El, presence) ->
     xmpp_util:add_delay_info(El, jid:make(LServer), Time, <<"Resent">>);
 add_resent_delay_info(_State, El, _Time) ->
+    %% TODO
     El.
 
 -spec send(state(), xmpp_element()) -> state().
@@ -711,6 +730,16 @@ bounce_message_queue() ->
            ok
     end.
 
+-spec send_policy_violation(state()) -> state().
+send_policy_violation(#{lang := Lang} = State) ->
+    State1 = State#{mgmt_resend => false},
+    Err = xmpp:serr_policy_violation(<<"Too many unacked stanzas">>, Lang),
+    send(State1, Err).
+
+-spec select_lang(binary(), binary()) -> binary().
+select_lang(Lang, <<"">>) -> Lang;
+select_lang(_, Lang) -> Lang.
+
 %%%===================================================================
 %%% Configuration processing
 %%%===================================================================