diff options
Diffstat (limited to 'src/ejabberd_receiver.erl')
-rw-r--r-- | src/ejabberd_receiver.erl | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl new file mode 100644 index 000000000..6565d042f --- /dev/null +++ b/src/ejabberd_receiver.erl @@ -0,0 +1,78 @@ +%%%---------------------------------------------------------------------- +%%% File : ejabberd_receiver.erl +%%% Author : Alexey Shchepin <alexey@sevcom.net> +%%% Purpose : Socket receiver for C2S and S2S connections +%%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@sevcom.net> +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(ejabberd_receiver). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +-export([start/3, + receiver/4, + change_shaper/2, + reset_stream/1]). + +-include("ejabberd.hrl"). + + +start(Socket, SockMod, Shaper) -> + proc_lib:spawn(?MODULE, receiver, [Socket, SockMod, Shaper, self()]). + + +receiver(Socket, SockMod, Shaper, C2SPid) -> + XMLStreamPid = xml_stream:start(C2SPid), + ShaperState = shaper:new(Shaper), + Timeout = case SockMod of + ssl -> + 20; + _ -> + infinity + end, + receiver(Socket, SockMod, ShaperState, C2SPid, XMLStreamPid, Timeout). + +receiver(Socket, SockMod, ShaperState, C2SPid, XMLStreamPid, Timeout) -> + case catch SockMod:recv(Socket, 0, Timeout) of + {ok, Text} -> + ShaperSt1 = receive + {change_shaper, Shaper} -> + shaper:new(Shaper) + after 0 -> + ShaperState + end, + NewShaperState = shaper:update(ShaperSt1, size(Text)), + XMLStreamPid1 = receive + reset_stream -> + exit(XMLStreamPid, closed), + xml_stream:start(C2SPid) + after 0 -> + XMLStreamPid + end, + xml_stream:send_text(XMLStreamPid1, Text), + receiver(Socket, SockMod, NewShaperState, C2SPid, XMLStreamPid1, + Timeout); + {error, timeout} -> + receiver(Socket, SockMod, ShaperState, C2SPid, XMLStreamPid, + Timeout); + {error, Reason} -> + exit(XMLStreamPid, closed), + gen_fsm:send_event(C2SPid, closed), + ok; + {'EXIT', Reason} -> + ?ERROR_MSG("(~w) abnormal ~w:recv termination:~n\t~p~n", + [Socket, SockMod, Reason]), + exit(XMLStreamPid, closed), + gen_fsm:send_event(C2SPid, closed), + ok + end. + + +change_shaper(Pid, Shaper) -> + Pid ! {change_shaper, Shaper}. + +reset_stream(Pid) -> + Pid ! reset_stream. + + |