Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2013-03-14 13:33:02 +0400
committerBadlop <badlop@process-one.net>2013-03-14 13:33:02 +0400
commit9deb294328bb3f9eb6bd2c0e7cd500732e9b5830 (patch)
tree7e1066c130250627ee0abab44a135f583a28d07f /src/ejabberd_service.erl
parent9c41abde101395111efcda16aa2fd9625f4c6207 (diff)
Accumulated patch to binarize and indent code
Diffstat (limited to 'src/ejabberd_service.erl')
-rw-r--r--src/ejabberd_service.erl390
1 files changed, 187 insertions, 203 deletions
diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl
index 449cba68c..5a80fcd90 100644
--- a/src/ejabberd_service.erl
+++ b/src/ejabberd_service.erl
@@ -25,6 +25,7 @@
%%%----------------------------------------------------------------------
-module(ejabberd_service).
+
-author('alexey@process-one.net').
-define(GEN_FSM, p1_fsm).
@@ -32,82 +33,78 @@
-behaviour(?GEN_FSM).
%% External exports
--export([start/2,
- start_link/2,
- send_text/2,
- send_element/2,
- socket_type/0]).
+-export([start/2, start_link/2, send_text/2,
+ send_element/2, socket_type/0]).
%% gen_fsm callbacks
--export([init/1,
- wait_for_stream/2,
- wait_for_handshake/2,
- stream_established/2,
- handle_event/3,
- handle_sync_event/4,
- code_change/4,
- handle_info/3,
- terminate/3,
- print_state/1]).
+-export([init/1, wait_for_stream/2,
+ wait_for_handshake/2, stream_established/2,
+ handle_event/3, handle_sync_event/4, code_change/4,
+ handle_info/3, terminate/3, print_state/1]).
-include("ejabberd.hrl").
+
-include("jlib.hrl").
--record(state, {socket, sockmod, streamid,
- hosts, password, access,
- check_from}).
+-record(state,
+ {socket :: ejabberd_socket:socket_state(),
+ sockmod = ejabberd_socket :: ejabberd_socket | ejabberd_frontend_socket,
+ streamid = <<"">> :: binary(),
+ hosts = [] :: [binary()],
+ password = <<"">> :: binary(),
+ access :: atom(),
+ check_from = true :: boolean()}).
%-define(DBGFSM, true).
-ifdef(DBGFSM).
+
-define(FSMOPTS, [{debug, [trace]}]).
+
-else.
+
-define(FSMOPTS, []).
+
-endif.
-define(STREAM_HEADER,
- "<?xml version='1.0'?>"
- "<stream:stream "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "xmlns='jabber:component:accept' "
- "id='~s' from='~s'>"
- ).
+ <<"<?xml version='1.0'?><stream:stream "
+ "xmlns:stream='http://etherx.jabber.org/stream"
+ "s' xmlns='jabber:component:accept' id='~s' "
+ "from='~s'>">>).
--define(STREAM_TRAILER, "</stream:stream>").
+-define(STREAM_TRAILER, <<"</stream:stream>">>).
-define(INVALID_HEADER_ERR,
- "<stream:stream "
- "xmlns:stream='http://etherx.jabber.org/streams'>"
- "<stream:error>Invalid Stream Header</stream:error>"
- "</stream:stream>"
- ).
+ <<"<stream:stream xmlns:stream='http://etherx.ja"
+ "bber.org/streams'><stream:error>Invalid "
+ "Stream Header</stream:error></stream:stream>">>).
-define(INVALID_HANDSHAKE_ERR,
- "<stream:error>"
- "<not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>"
- "<text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>"
- "Invalid Handshake</text>"
- "</stream:error>"
- "</stream:stream>"
- ).
+ <<"<stream:error><not-authorized xmlns='urn:ietf"
+ ":params:xml:ns:xmpp-streams'/><text "
+ "xmlns='urn:ietf:params:xml:ns:xmpp-streams' "
+ "xml:lang='en'>Invalid Handshake</text></strea"
+ "m:error></stream:stream>">>).
-define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
+ xml:element_to_binary(?SERR_XML_NOT_WELL_FORMED)).
+
-define(INVALID_NS_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
+ xml:element_to_binary(?SERR_INVALID_NAMESPACE)).
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start(SockData, Opts) ->
- supervisor:start_child(ejabberd_service_sup, [SockData, Opts]).
+ supervisor:start_child(ejabberd_service_sup,
+ [SockData, Opts]).
start_link(SockData, Opts) ->
- ?GEN_FSM:start_link(ejabberd_service, [SockData, Opts],
- fsm_limit_opts(Opts) ++ ?FSMOPTS).
+ (?GEN_FSM):start_link(ejabberd_service,
+ [SockData, Opts], fsm_limit_opts(Opts) ++ (?FSMOPTS)).
-socket_type() ->
- xml_stream.
+socket_type() -> xml_stream.
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
@@ -123,51 +120,47 @@ socket_type() ->
init([{SockMod, Socket}, Opts]) ->
?INFO_MSG("(~w) External service connected", [Socket]),
Access = case lists:keysearch(access, 1, Opts) of
- {value, {_, A}} -> A;
- _ -> all
+ {value, {_, A}} -> A;
+ _ -> all
end,
- {Hosts, Password} =
- case lists:keysearch(hosts, 1, Opts) of
- {value, {_, Hs, HOpts}} ->
- case lists:keysearch(password, 1, HOpts) of
- {value, {_, P}} ->
- {Hs, P};
- _ ->
- % TODO: generate error
- false
- end;
- _ ->
- case lists:keysearch(host, 1, Opts) of
- {value, {_, H, HOpts}} ->
- case lists:keysearch(password, 1, HOpts) of
- {value, {_, P}} ->
- {[H], P};
- _ ->
- % TODO: generate error
- false
- end;
- _ ->
- % TODO: generate error
- false
- end
- end,
+ {Hosts, Password} = case lists:keysearch(hosts, 1, Opts)
+ of
+ {value, {_, Hs, HOpts}} ->
+ case lists:keysearch(password, 1, HOpts) of
+ {value, {_, P}} -> {Hs, P};
+ _ ->
+ % TODO: generate error
+ false
+ end;
+ _ ->
+ case lists:keysearch(host, 1, Opts) of
+ {value, {_, H, HOpts}} ->
+ case lists:keysearch(password, 1, HOpts) of
+ {value, {_, P}} -> {[H], P};
+ _ ->
+ % TODO: generate error
+ false
+ end;
+ _ ->
+ % TODO: generate error
+ false
+ end
+ end,
Shaper = case lists:keysearch(shaper_rule, 1, Opts) of
- {value, {_, S}} -> S;
- _ -> none
- end,
- CheckFrom = case lists:keysearch(service_check_from, 1, Opts) of
- {value, {_, CF}} -> CF;
- _ -> true
+ {value, {_, S}} -> S;
+ _ -> none
end,
+ CheckFrom = case lists:keysearch(service_check_from, 1,
+ Opts)
+ of
+ {value, {_, CF}} -> CF;
+ _ -> true
+ end,
SockMod:change_shaper(Socket, Shaper),
- {ok, wait_for_stream, #state{socket = Socket,
- sockmod = SockMod,
- streamid = new_id(),
- hosts = Hosts,
- password = Password,
- access = Access,
- check_from = CheckFrom
- }}.
+ {ok, wait_for_stream,
+ #state{socket = Socket, sockmod = SockMod,
+ streamid = new_id(), hosts = Hosts, password = Password,
+ access = Access, check_from = CheckFrom}}.
%%----------------------------------------------------------------------
%% Func: StateName/2
@@ -176,120 +169,109 @@ init([{SockMod, Socket}, Opts]) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
-wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
- case xml:get_attr_s("xmlns", Attrs) of
- "jabber:component:accept" ->
- %% Note: XEP-0114 requires to check that destination is a Jabber
- %% component served by this Jabber server.
- %% However several transports don't respect that,
- %% so ejabberd doesn't check 'to' attribute (EJAB-717)
- To = xml:get_attr_s("to", Attrs),
- Header = io_lib:format(?STREAM_HEADER,
- [StateData#state.streamid, xml:crypt(To)]),
- send_text(StateData, Header),
- {next_state, wait_for_handshake, StateData};
- _ ->
- send_text(StateData, ?INVALID_HEADER_ERR),
- {stop, normal, StateData}
+wait_for_stream({xmlstreamstart, _Name, Attrs},
+ StateData) ->
+ case xml:get_attr_s(<<"xmlns">>, Attrs) of
+ <<"jabber:component:accept">> ->
+ To = xml:get_attr_s(<<"to">>, Attrs),
+ Header = io_lib:format(?STREAM_HEADER,
+ [StateData#state.streamid, xml:crypt(To)]),
+ send_text(StateData, Header),
+ {next_state, wait_for_handshake, StateData};
+ _ ->
+ send_text(StateData, ?INVALID_HEADER_ERR),
+ {stop, normal, StateData}
end;
-
wait_for_stream({xmlstreamerror, _}, StateData) ->
Header = io_lib:format(?STREAM_HEADER,
- ["none", ?MYNAME]),
+ [<<"none">>, ?MYNAME]),
send_text(StateData,
- Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ <<(list_to_binary(Header))/binary, (?INVALID_XML_ERR)/binary,
+ (?STREAM_TRAILER)/binary>>),
{stop, normal, StateData};
-
wait_for_stream(closed, StateData) ->
{stop, normal, StateData}.
-
wait_for_handshake({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, _Attrs, Els} = El,
+ #xmlel{name = Name, children = Els} = El,
case {Name, xml:get_cdata(Els)} of
- {"handshake", Digest} ->
- case sha:sha(StateData#state.streamid ++
- StateData#state.password) of
- Digest ->
- send_text(StateData, "<handshake/>"),
- lists:foreach(
- fun(H) ->
- ejabberd_router:register_route(H),
- ?INFO_MSG("Route registered for service ~p~n", [H])
- end, StateData#state.hosts),
- {next_state, stream_established, StateData};
- _ ->
- send_text(StateData, ?INVALID_HANDSHAKE_ERR),
- {stop, normal, StateData}
- end;
- _ ->
- {next_state, wait_for_handshake, StateData}
+ {<<"handshake">>, Digest} ->
+ case sha:sha(<<(StateData#state.streamid)/binary,
+ (StateData#state.password)/binary>>)
+ of
+ Digest ->
+ send_text(StateData, <<"<handshake/>">>),
+ lists:foreach(fun (H) ->
+ ejabberd_router:register_route(H),
+ ?INFO_MSG("Route registered for service ~p~n",
+ [H])
+ end,
+ StateData#state.hosts),
+ {next_state, stream_established, StateData};
+ _ ->
+ send_text(StateData, ?INVALID_HANDSHAKE_ERR),
+ {stop, normal, StateData}
+ end;
+ _ -> {next_state, wait_for_handshake, StateData}
end;
-
wait_for_handshake({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
-
wait_for_handshake({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_text(StateData,
+ <<(?INVALID_XML_ERR)/binary,
+ (?STREAM_TRAILER)/binary>>),
{stop, normal, StateData};
-
wait_for_handshake(closed, StateData) ->
{stop, normal, StateData}.
-
stream_established({xmlstreamelement, El}, StateData) ->
- NewEl = jlib:remove_attr("xmlns", El),
- {xmlelement, Name, Attrs, _Els} = NewEl,
- From = xml:get_attr_s("from", Attrs),
+ NewEl = jlib:remove_attr(<<"xmlns">>, El),
+ #xmlel{name = Name, attrs = Attrs} = NewEl,
+ From = xml:get_attr_s(<<"from">>, Attrs),
FromJID = case StateData#state.check_from of
- %% If the admin does not want to check the from field
- %% when accept packets from any address.
- %% In this case, the component can send packet of
- %% behalf of the server users.
- false -> jlib:string_to_jid(From);
- %% The default is the standard behaviour in XEP-0114
- _ ->
- FromJID1 = jlib:string_to_jid(From),
- case FromJID1 of
- #jid{lserver = Server} ->
- case lists:member(Server, StateData#state.hosts) of
- true -> FromJID1;
- false -> error
- end;
- _ -> error
- end
+ %% If the admin does not want to check the from field
+ %% when accept packets from any address.
+ %% In this case, the component can send packet of
+ %% behalf of the server users.
+ false -> jlib:string_to_jid(From);
+ %% The default is the standard behaviour in XEP-0114
+ _ ->
+ FromJID1 = jlib:string_to_jid(From),
+ case FromJID1 of
+ #jid{lserver = Server} ->
+ case lists:member(Server, StateData#state.hosts) of
+ true -> FromJID1;
+ false -> error
+ end;
+ _ -> error
+ end
end,
- To = xml:get_attr_s("to", Attrs),
+ To = xml:get_attr_s(<<"to">>, Attrs),
ToJID = case To of
- "" -> error;
- _ -> jlib:string_to_jid(To)
+ <<"">> -> error;
+ _ -> jlib:string_to_jid(To)
end,
- if ((Name == "iq") or
- (Name == "message") or
- (Name == "presence")) and
- (ToJID /= error) and (FromJID /= error) ->
- ejabberd_router:route(FromJID, ToJID, NewEl);
+ if ((Name == <<"iq">>) or (Name == <<"message">>) or
+ (Name == <<"presence">>))
+ and (ToJID /= error)
+ and (FromJID /= error) ->
+ ejabberd_router:route(FromJID, ToJID, NewEl);
true ->
- Err = jlib:make_error_reply(NewEl, ?ERR_BAD_REQUEST),
- send_element(StateData, Err),
- error
+ Err = jlib:make_error_reply(NewEl, ?ERR_BAD_REQUEST),
+ send_element(StateData, Err),
+ error
end,
{next_state, stream_established, StateData};
-
stream_established({xmlstreamend, _Name}, StateData) ->
- % TODO
{stop, normal, StateData};
-
stream_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_text(StateData,
+ <<(?INVALID_XML_ERR)/binary,
+ (?STREAM_TRAILER)/binary>>),
{stop, normal, StateData};
-
stream_established(closed, StateData) ->
- % TODO
{stop, normal, StateData}.
-
-
%%----------------------------------------------------------------------
%% Func: StateName/3
%% Returns: {next_state, NextStateName, NextStateData} |
@@ -321,9 +303,9 @@ handle_event(_Event, StateName, StateData) ->
%% {stop, Reason, NewStateData} |
%% {stop, Reason, Reply, NewStateData}
%%----------------------------------------------------------------------
-handle_sync_event(_Event, _From, StateName, StateData) ->
- Reply = ok,
- {reply, Reply, StateName, StateData}.
+handle_sync_event(_Event, _From, StateName,
+ StateData) ->
+ Reply = ok, {reply, Reply, StateName, StateData}.
code_change(_OldVsn, StateName, StateData, _Extra) ->
{ok, StateName, StateData}.
@@ -340,25 +322,29 @@ handle_info({send_text, Text}, StateName, StateData) ->
handle_info({send_element, El}, StateName, StateData) ->
send_element(StateData, El),
{next_state, StateName, StateData};
-handle_info({route, From, To, Packet}, StateName, StateData) ->
- case acl:match_rule(global, StateData#state.access, From) of
- allow ->
- {xmlelement, Name, Attrs, Els} = Packet,
- Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- Text = xml:element_to_binary({xmlelement, Name, Attrs2, Els}),
- send_text(StateData, Text);
- deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route_error(To, From, Err, Packet)
+handle_info({route, From, To, Packet}, StateName,
+ StateData) ->
+ case acl:match_rule(global, StateData#state.access,
+ From)
+ of
+ allow ->
+ #xmlel{name = Name, attrs = Attrs, children = Els} =
+ Packet,
+ Attrs2 =
+ jlib:replace_from_to_attrs(jlib:jid_to_string(From),
+ jlib:jid_to_string(To), Attrs),
+ Text = xml:element_to_binary(#xmlel{name = Name,
+ attrs = Attrs2, children = Els}),
+ send_text(StateData, Text);
+ deny ->
+ Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
+ ejabberd_router:route_error(To, From, Err, Packet)
end,
{next_state, StateName, StateData};
handle_info(Info, StateName, StateData) ->
?ERROR_MSG("Unexpected info: ~p", [Info]),
{next_state, StateName, StateData}.
-
%%----------------------------------------------------------------------
%% Func: terminate/3
%% Purpose: Shutdown the fsm
@@ -367,13 +353,12 @@ handle_info(Info, StateName, StateData) ->
terminate(Reason, StateName, StateData) ->
?INFO_MSG("terminated: ~p", [Reason]),
case StateName of
- stream_established ->
- lists:foreach(
- fun(H) ->
- ejabberd_router:unregister_route(H)
- end, StateData#state.hosts);
- _ ->
- ok
+ stream_established ->
+ lists:foreach(fun (H) ->
+ ejabberd_router:unregister_route(H)
+ end,
+ StateData#state.hosts);
+ _ -> ok
end,
(StateData#state.sockmod):close(StateData#state.socket),
ok.
@@ -383,31 +368,30 @@ terminate(Reason, StateName, StateData) ->
%% Purpose: Prepare the state to be printed on error log
%% Returns: State to print
%%----------------------------------------------------------------------
-print_state(State) ->
- State.
+print_state(State) -> State.
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------
send_text(StateData, Text) ->
- (StateData#state.sockmod):send(StateData#state.socket, Text).
+ (StateData#state.sockmod):send(StateData#state.socket,
+ Text).
send_element(StateData, El) ->
send_text(StateData, xml:element_to_binary(El)).
-new_id() ->
- randoms:get_string().
+new_id() -> randoms:get_string().
fsm_limit_opts(Opts) ->
case lists:keysearch(max_fsm_queue, 1, Opts) of
- {value, {_, N}} when is_integer(N) ->
- [{max_queue, N}];
- _ ->
- case ejabberd_config:get_local_option(max_fsm_queue) of
- N when is_integer(N) ->
- [{max_queue, N}];
- _ ->
- []
- end
+ {value, {_, N}} when is_integer(N) ->
+ [{max_queue, N}];
+ _ ->
+ case ejabberd_config:get_local_option(
+ max_fsm_queue,
+ fun(I) when is_integer(I), I > 0 -> I end) of
+ undefined -> [];
+ N -> [{max_queue, N}]
+ end
end.