aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_receiver.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejabberd_receiver.erl')
-rw-r--r--src/ejabberd_receiver.erl78
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.
+
+