aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_frontend_socket.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejabberd_frontend_socket.erl')
-rw-r--r--src/ejabberd_frontend_socket.erl279
1 files changed, 99 insertions, 180 deletions
diff --git a/src/ejabberd_frontend_socket.erl b/src/ejabberd_frontend_socket.erl
index 9b4e44b07..180f2676c 100644
--- a/src/ejabberd_frontend_socket.erl
+++ b/src/ejabberd_frontend_socket.erl
@@ -25,75 +25,59 @@
%%%----------------------------------------------------------------------
-module(ejabberd_frontend_socket).
+
-author('alexey@process-one.net').
-behaviour(gen_server).
%% API
--export([start/4,
- start_link/5,
- %connect/3,
- starttls/2,
- starttls/3,
- compress/1,
- compress/2,
- reset_stream/1,
- send/2,
- change_shaper/2,
- monitor/1,
- get_sockmod/1,
- get_peer_certificate/1,
- get_verify_result/1,
- close/1,
- setopts/2,
- change_controller/2,
- sockname/1, peername/1]).
+-export([start/4, start_link/5, starttls/2, starttls/3,
+ compress/1, compress/2, reset_stream/1, send/2,
+ change_shaper/2, monitor/1, get_sockmod/1,
+ get_peer_certificate/1, get_verify_result/1, close/1,
+ setopts/2, change_controller/2, sockname/1,
+ peername/1]).
+
+ %connect/3,
%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
+-export([init/1, handle_call/3, handle_cast/2,
+ handle_info/2, terminate/2, code_change/3]).
--record(state, {sockmod, socket, receiver}).
+-record(socket_state, {sockmod, socket, receiver}).
-define(HIBERNATE_TIMEOUT, 90000).
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
start_link(Module, SockMod, Socket, Opts, Receiver) ->
gen_server:start_link(?MODULE,
[Module, SockMod, Socket, Opts, Receiver], []).
start(Module, SockMod, Socket, Opts) ->
case Module:socket_type() of
- xml_stream ->
- MaxStanzaSize =
- case lists:keysearch(max_stanza_size, 1, Opts) of
- {value, {_, Size}} -> Size;
- _ -> infinity
- end,
- Receiver = ejabberd_receiver:start(Socket, SockMod, none, MaxStanzaSize),
- case SockMod:controlling_process(Socket, Receiver) of
- ok ->
- ok;
- {error, _Reason} ->
- SockMod:close(Socket)
- end,
- supervisor:start_child(ejabberd_frontend_socket_sup,
- [Module, SockMod, Socket, Opts, Receiver]);
- raw ->
- %{ok, Pid} = Module:start({SockMod, Socket}, Opts),
- %case SockMod:controlling_process(Socket, Pid) of
- % ok ->
- % ok;
- % {error, _Reason} ->
- % SockMod:close(Socket)
- %end
- todo
+ xml_stream ->
+ MaxStanzaSize = case lists:keysearch(max_stanza_size, 1,
+ Opts)
+ of
+ {value, {_, Size}} -> Size;
+ _ -> infinity
+ end,
+ Receiver = ejabberd_receiver:start(Socket, SockMod,
+ none, MaxStanzaSize),
+ case SockMod:controlling_process(Socket, Receiver) of
+ ok -> ok;
+ {error, _Reason} -> SockMod:close(Socket)
+ end,
+ supervisor:start_child(ejabberd_frontend_socket_sup,
+ [Module, SockMod, Socket, Opts, Receiver]);
+ raw ->
+ %{ok, Pid} = Module:start({SockMod, Socket}, Opts),
+ %case SockMod:controlling_process(Socket, Pid) of
+ % ok ->
+ % ok;
+ % {error, _Reason} ->
+ % SockMod:close(Socket)
+ %end
+ todo
end.
starttls(FsmRef, TLSOpts) ->
@@ -103,12 +87,10 @@ starttls(FsmRef, TLSOpts, Data) ->
gen_server:call(FsmRef, {starttls, TLSOpts, Data}),
FsmRef.
-compress(FsmRef) ->
- compress(FsmRef, undefined).
+compress(FsmRef) -> compress(FsmRef, undefined).
compress(FsmRef, Data) ->
- gen_server:call(FsmRef, {compress, Data}),
- FsmRef.
+ gen_server:call(FsmRef, {compress, Data}), FsmRef.
reset_stream(FsmRef) ->
gen_server:call(FsmRef, reset_stream).
@@ -119,8 +101,7 @@ send(FsmRef, Data) ->
change_shaper(FsmRef, Shaper) ->
gen_server:call(FsmRef, {change_shaper, Shaper}).
-monitor(FsmRef) ->
- erlang:monitor(process, FsmRef).
+monitor(FsmRef) -> erlang:monitor(process, FsmRef).
get_sockmod(FsmRef) ->
gen_server:call(FsmRef, get_sockmod).
@@ -131,11 +112,9 @@ get_peer_certificate(FsmRef) ->
get_verify_result(FsmRef) ->
gen_server:call(FsmRef, get_verify_result).
-close(FsmRef) ->
- gen_server:call(FsmRef, close).
+close(FsmRef) -> gen_server:call(FsmRef, close).
-sockname(FsmRef) ->
- gen_server:call(FsmRef, sockname).
+sockname(FsmRef) -> gen_server:call(FsmRef, sockname).
setopts(FsmRef, Opts) ->
gen_server:call(FsmRef, {setopts, Opts}).
@@ -143,180 +122,120 @@ setopts(FsmRef, Opts) ->
change_controller(FsmRef, C2SPid) ->
gen_server:call(FsmRef, {change_controller, C2SPid}).
-peername(FsmRef) ->
- gen_server:call(FsmRef, peername).
+peername(FsmRef) -> gen_server:call(FsmRef, peername).
%%====================================================================
%% gen_server callbacks
%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
init([Module, SockMod, Socket, Opts, Receiver]) ->
- %% TODO: monitor the receiver
Node = ejabberd_node_groups:get_closest_node(backend),
IP = case peername(SockMod, Socket) of
- {ok, IP1} ->
- IP1;
- _ ->
- undefined
+ {ok, IP1} -> IP1;
+ _ -> undefined
end,
- {SockMod2, Socket2} = check_starttls(SockMod, Socket, Receiver, Opts),
- {ok, Pid} =
- rpc:call(Node, Module, start,
- [{?MODULE, self()}, [{frontend_ip, IP} | Opts]]),
+ {SockMod2, Socket2} = check_starttls(SockMod, Socket,
+ Receiver, Opts),
+ {ok, Pid} = rpc:call(Node, Module, start,
+ [{?MODULE, self()}, [{frontend_ip, IP} | Opts]]),
ejabberd_receiver:become_controller(Receiver, Pid),
- {ok, #state{sockmod = SockMod2,
- socket = Socket2,
- receiver = Receiver}}.
-
-%%--------------------------------------------------------------------
-%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} |
-%% {stop, Reason, State}
-%% Description: Handling call messages
-%%--------------------------------------------------------------------
+ {ok,
+ #socket_state{sockmod = SockMod2, socket = Socket2,
+ receiver = Receiver}}.
+
handle_call({starttls, TLSOpts, Data}, _From, State) ->
- {ok, TLSSocket} = ejabberd_receiver:starttls(
- State#state.receiver, TLSOpts, Data),
+ {ok, TLSSocket} =
+ ejabberd_receiver:starttls(State#socket_state.receiver,
+ TLSOpts, Data),
Reply = ok,
- {reply, Reply, State#state{socket = TLSSocket, sockmod = tls},
+ {reply, Reply,
+ State#socket_state{socket = TLSSocket, sockmod = tls},
?HIBERNATE_TIMEOUT};
-
handle_call({compress, Data}, _From, State) ->
- {ok, ZlibSocket} = ejabberd_receiver:compress(
- State#state.receiver, Data),
+ {ok, ZlibSocket} =
+ ejabberd_receiver:compress(State#socket_state.receiver, Data),
Reply = ok,
- {reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib},
+ {reply, Reply,
+ State#socket_state{socket = ZlibSocket,
+ sockmod = ejabberd_zlib},
?HIBERNATE_TIMEOUT};
-
handle_call(reset_stream, _From, State) ->
- ejabberd_receiver:reset_stream(State#state.receiver),
+ ejabberd_receiver:reset_stream(State#socket_state.receiver),
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
-
handle_call({send, Data}, _From, State) ->
- catch (State#state.sockmod):send(
- State#state.socket, Data),
+ catch (State#socket_state.sockmod):send(State#socket_state.socket,
+ Data),
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
-
handle_call({change_shaper, Shaper}, _From, State) ->
- ejabberd_receiver:change_shaper(State#state.receiver, Shaper),
+ ejabberd_receiver:change_shaper(State#socket_state.receiver,
+ Shaper),
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
-
handle_call(get_sockmod, _From, State) ->
- Reply = State#state.sockmod,
+ Reply = State#socket_state.sockmod,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
-
handle_call(get_peer_certificate, _From, State) ->
- Reply = tls:get_peer_certificate(State#state.socket),
+ Reply = tls:get_peer_certificate(State#socket_state.socket),
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
-
handle_call(get_verify_result, _From, State) ->
- Reply = tls:get_verify_result(State#state.socket),
+ Reply = tls:get_verify_result(State#socket_state.socket),
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
-
handle_call(close, _From, State) ->
- ejabberd_receiver:close(State#state.receiver),
+ ejabberd_receiver:close(State#socket_state.receiver),
Reply = ok,
{stop, normal, Reply, State};
-
handle_call(sockname, _From, State) ->
- #state{sockmod = SockMod, socket = Socket} = State,
+ #socket_state{sockmod = SockMod, socket = Socket} = State,
Reply = peername(SockMod, Socket),
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
-
handle_call(peername, _From, State) ->
- #state{sockmod = SockMod, socket = Socket} = State,
- Reply =
- case SockMod of
- gen_tcp ->
- inet:peername(Socket);
- _ ->
- SockMod:peername(Socket)
- end,
+ #socket_state{sockmod = SockMod, socket = Socket} = State,
+ Reply = case SockMod of
+ gen_tcp -> inet:peername(Socket);
+ _ -> SockMod:peername(Socket)
+ end,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
-
handle_call({setopts, Opts}, _From, State) ->
- ejabberd_receiver:setopts(State#state.receiver, Opts),
+ ejabberd_receiver:setopts(State#socket_state.receiver, Opts),
{reply, ok, State, ?HIBERNATE_TIMEOUT};
-
handle_call({change_controller, Pid}, _From, State) ->
- ejabberd_receiver:change_controller(State#state.receiver, Pid),
+ ejabberd_receiver:change_controller(State#socket_state.receiver,
+ Pid),
{reply, ok, State, ?HIBERNATE_TIMEOUT};
-
handle_call(_Request, _From, State) ->
- Reply = ok,
- {reply, Reply, State, ?HIBERNATE_TIMEOUT}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_cast(Msg, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling cast messages
-%%--------------------------------------------------------------------
+ Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}.
+
handle_cast(_Msg, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
-%%--------------------------------------------------------------------
-%% Function: handle_info(Info, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling all non call/cast messages
-%%--------------------------------------------------------------------
handle_info(timeout, State) ->
- proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]),
+ proc_lib:hibernate(gen_server, enter_loop,
+ [?MODULE, [], State]),
{noreply, State, ?HIBERNATE_TIMEOUT};
handle_info(_Info, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
-%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> void()
-%% Description: This function is called by a gen_server when it is about to
-%% terminate. It should be the opposite of Module:init/1 and do any necessary
-%% cleaning up. When it returns, the gen_server terminates with Reason.
-%% The return value is ignored.
-%%--------------------------------------------------------------------
-terminate(_Reason, _State) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
-%% Description: Convert process state when code is changed
-%%--------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
+terminate(_Reason, _State) -> ok.
+
+code_change(_OldVsn, State, _Extra) -> {ok, State}.
+
check_starttls(SockMod, Socket, Receiver, Opts) ->
TLSEnabled = lists:member(tls, Opts),
- TLSOpts = lists:filter(fun({certfile, _}) -> true;
- (_) -> false
- end, Opts),
- if
- TLSEnabled ->
- {ok, TLSSocket} = ejabberd_receiver:starttls(Receiver, TLSOpts),
- {tls, TLSSocket};
- true ->
- {SockMod, Socket}
+ TLSOpts = lists:filter(fun ({certfile, _}) -> true;
+ (_) -> false
+ end,
+ Opts),
+ if TLSEnabled ->
+ {ok, TLSSocket} = ejabberd_receiver:starttls(Receiver,
+ TLSOpts),
+ {tls, TLSSocket};
+ true -> {SockMod, Socket}
end.
peername(SockMod, Socket) ->
case SockMod of
- gen_tcp ->
- inet:peername(Socket);
- _ ->
- SockMod:peername(Socket)
+ gen_tcp -> inet:peername(Socket);
+ _ -> SockMod:peername(Socket)
end.