24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-06-14 22:00:16 +02:00

* src/ejabberd_service.erl: Added supports for multiple hosts per

service

* src/Makefile.in: Minor fix

SVN Revision: 153
This commit is contained in:
Alexey Shchepin 2003-10-18 19:15:12 +00:00
parent 392d64ee8b
commit a704f9760d
4 changed files with 78 additions and 51 deletions

View File

@ -1,3 +1,10 @@
2003-10-18 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_service.erl: Added supports for multiple hosts per
service
* src/Makefile.in: Minor fix
2003-10-17 Alexey Shchepin <alexey@sevcom.net> 2003-10-17 Alexey Shchepin <alexey@sevcom.net>
* src/configure.ac: Build system now done using autoconf (thanks * src/configure.ac: Build system now done using autoconf (thanks

View File

@ -30,9 +30,10 @@ mostlyclean-recursive maintainer-clean-recursive:
done done
$(ERLSHLIBS): ../%.so: %.c $(ERLSHLIBS): %.so: %.c
gcc -Wall $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LIBDIRS) \ gcc -Wall $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LIBDIRS) \
$(subst ../,,$(subst .so,.c,$@)) \ $(subst ../,,$(subst .so,.c,$@)) \
-lexpat \
-lerl_interface \ -lerl_interface \
-lei \ -lei \
-o $@ -fpic -shared \ -o $@ -fpic -shared \
@ -44,4 +45,3 @@ TAGS:
etags *.erl etags *.erl
Makefile: Makefile.in Makefile: Makefile.in

View File

@ -18,7 +18,7 @@
-include("ejabberd.hrl"). -include("ejabberd.hrl").
start(normal, Args) -> start(normal, _Args) ->
application:start(sasl), application:start(sasl),
randoms:start(), randoms:start(),
db_init(), db_init(),
@ -33,6 +33,7 @@ start(normal, Args) ->
% Profiling % Profiling
%eprof:start(), %eprof:start(),
%eprof:profile([self()]), %eprof:profile([self()]),
%fprof:trace(start, "/tmp/fprof"),
Sup = ejabberd_sup:start_link(), Sup = ejabberd_sup:start_link(),
start(), start(),
load_modules(), load_modules(),
@ -40,7 +41,7 @@ start(normal, Args) ->
start(_, _) -> start(_, _) ->
{error, badarg}. {error, badarg}.
stop(StartArgs) -> stop(_StartArgs) ->
ok. ok.
start() -> start() ->

View File

@ -13,7 +13,7 @@
-behaviour(gen_fsm). -behaviour(gen_fsm).
%% External exports %% External exports
-export([start/2, start_link/2, receiver/2, send_text/2, send_element/2]). -export([start/2, start_link/2, receiver/3, send_text/2, send_element/2]).
%% gen_fsm callbacks %% gen_fsm callbacks
-export([init/1, -export([init/1,
@ -29,8 +29,8 @@
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("jlib.hrl"). -include("jlib.hrl").
-record(state, {socket, receiver, streamid, -record(state, {socket, receiver, streamid, sockmod,
host, password}). hosts, password}).
%-define(DBGFSM, true). %-define(DBGFSM, true).
@ -87,25 +87,37 @@ start_link(SockData, Opts) ->
%% {stop, StopReason} %% {stop, StopReason}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
init([{SockMod, Socket}, Opts]) -> init([{SockMod, Socket}, Opts]) ->
{Host, Password} = {Hosts, Password} =
case lists:keysearch(host, 1, Opts) of case lists:keysearch(hosts, 1, Opts) of
{value, {_, H, HOpts}} -> {value, {_, Hs, HOpts}} ->
case lists:keysearch(password, 1, HOpts) of case lists:keysearch(password, 1, HOpts) of
{value, {_, P}} -> {value, {_, P}} ->
{H, P}; {Hs, P};
_ -> _ ->
% TODO: generate error % TODO: generate error
false false
end; end;
_ -> _ ->
% TODO: generate error case lists:keysearch(host, 1, Opts) of
false {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, end,
ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]), ReceiverPid = spawn(?MODULE, receiver, [Socket, SockMod, self()]),
{ok, wait_for_stream, #state{socket = Socket, {ok, wait_for_stream, #state{socket = Socket,
receiver = ReceiverPid, receiver = ReceiverPid,
streamid = new_id(), streamid = new_id(),
host = Host, sockmod = SockMod,
hosts = Hosts,
password = Password password = Password
}}. }}.
@ -118,23 +130,23 @@ init([{SockMod, Socket}, Opts]) ->
%state_name(Event, StateData) -> %state_name(Event, StateData) ->
% {next_state, state_name, StateData}. % {next_state, state_name, StateData}.
wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
% TODO % TODO
case xml:get_attr_s("xmlns", Attrs) of case xml:get_attr_s("xmlns", Attrs) of
"jabber:component:accept" -> "jabber:component:accept" ->
Header = io_lib:format(?STREAM_HEADER, Header = io_lib:format(?STREAM_HEADER,
[StateData#state.streamid, ?MYNAME]), [StateData#state.streamid, ?MYNAME]),
send_text(StateData#state.socket, Header), send_text(StateData, Header),
{next_state, wait_for_handshake, StateData}; {next_state, wait_for_handshake, StateData};
_ -> _ ->
send_text(StateData#state.socket, ?INVALID_HEADER_ERR), send_text(StateData, ?INVALID_HEADER_ERR),
{stop, normal, StateData} {stop, normal, StateData}
end; end;
wait_for_stream({xmlstreamerror, _}, StateData) -> wait_for_stream({xmlstreamerror, _}, StateData) ->
Header = io_lib:format(?STREAM_HEADER, Header = io_lib:format(?STREAM_HEADER,
["none", ?MYNAME]), ["none", ?MYNAME]),
send_text(StateData#state.socket, send_text(StateData,
Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER), Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
@ -143,28 +155,31 @@ wait_for_stream(closed, StateData) ->
wait_for_handshake({xmlstreamelement, El}, StateData) -> wait_for_handshake({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El, {xmlelement, Name, _Attrs, Els} = El,
case {Name, xml:get_cdata(Els)} of case {Name, xml:get_cdata(Els)} of
{"handshake", Digest} -> {"handshake", Digest} ->
case sha:sha(StateData#state.streamid ++ case sha:sha(StateData#state.streamid ++
StateData#state.password) of StateData#state.password) of
Digest -> Digest ->
send_text(StateData#state.socket, "<handshake/>"), send_text(StateData, "<handshake/>"),
ejabberd_router:register_local_route(StateData#state.host), lists:foreach(
fun(H) ->
ejabberd_router:register_local_route(H)
end, StateData#state.hosts),
{next_state, stream_established, StateData}; {next_state, stream_established, StateData};
_ -> _ ->
send_text(StateData#state.socket, ?INVALID_HEADER_ERR), send_text(StateData, ?INVALID_HEADER_ERR),
{stop, normal, StateData} {stop, normal, StateData}
end; end;
_ -> _ ->
{next_state, wait_for_key, StateData} {next_state, wait_for_key, StateData}
end; end;
wait_for_handshake({xmlstreamend, Name}, StateData) -> wait_for_handshake({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_handshake({xmlstreamerror, _}, StateData) -> wait_for_handshake({xmlstreamerror, _}, StateData) ->
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_handshake(closed, StateData) -> wait_for_handshake(closed, StateData) ->
@ -172,13 +187,14 @@ wait_for_handshake(closed, StateData) ->
stream_established({xmlstreamelement, El}, StateData) -> stream_established({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El, {xmlelement, Name, Attrs, _Els} = El,
From = xml:get_attr_s("from", Attrs), From = xml:get_attr_s("from", Attrs),
FromJID1 = jlib:string_to_jid(From), FromJID1 = jlib:string_to_jid(From),
FromJID = case FromJID1 of FromJID = case FromJID1 of
{Node, Server, Resource} -> #jid{lserver = Server} ->
if Server == StateData#state.host -> FromJID1; case lists:member(Server, StateData#state.hosts) of
true -> error true -> FromJID1;
false -> error
end; end;
_ -> error _ -> error
end, end,
@ -194,17 +210,17 @@ stream_established({xmlstreamelement, El}, StateData) ->
ejabberd_router:route(FromJID, ToJID, El); ejabberd_router:route(FromJID, ToJID, El);
true -> true ->
Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST), Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
error error
end, end,
{next_state, stream_established, StateData}; {next_state, stream_established, StateData};
stream_established({xmlstreamend, Name}, StateData) -> stream_established({xmlstreamend, _Name}, StateData) ->
% TODO % TODO
{stop, normal, StateData}; {stop, normal, StateData};
stream_established({xmlstreamerror, _}, StateData) -> stream_established({xmlstreamerror, _}, StateData) ->
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
stream_established(closed, StateData) -> stream_established(closed, StateData) ->
@ -232,7 +248,7 @@ stream_established(closed, StateData) ->
%% {next_state, NextStateName, NextStateData, Timeout} | %% {next_state, NextStateName, NextStateData, Timeout} |
%% {stop, Reason, NewStateData} %% {stop, Reason, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_event(Event, StateName, StateData) -> handle_event(_Event, StateName, StateData) ->
{next_state, StateName, StateData}. {next_state, StateName, StateData}.
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
@ -244,11 +260,11 @@ handle_event(Event, StateName, StateData) ->
%% {stop, Reason, NewStateData} | %% {stop, Reason, NewStateData} |
%% {stop, Reason, Reply, NewStateData} %% {stop, Reason, Reply, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_sync_event(Event, From, StateName, StateData) -> handle_sync_event(_Event, _From, StateName, StateData) ->
Reply = ok, Reply = ok,
{reply, Reply, StateName, StateData}. {reply, Reply, StateName, StateData}.
code_change(OldVsn, StateName, StateData, Extra) -> code_change(_OldVsn, StateName, StateData, _Extra) ->
{ok, StateName, StateData}. {ok, StateName, StateData}.
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
@ -258,10 +274,10 @@ code_change(OldVsn, StateName, StateData, Extra) ->
%% {stop, Reason, NewStateData} %% {stop, Reason, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_info({send_text, Text}, StateName, StateData) -> handle_info({send_text, Text}, StateName, StateData) ->
send_text(StateData#state.socket, Text), send_text(StateData, Text),
{next_state, StateName, StateData}; {next_state, StateName, StateData};
handle_info({send_element, El}, StateName, StateData) -> handle_info({send_element, El}, StateName, StateData) ->
send_element(StateData#state.socket, El), send_element(StateData, El),
{next_state, StateName, StateData}; {next_state, StateName, StateData};
handle_info({route, From, To, Packet}, StateName, StateData) -> handle_info({route, From, To, Packet}, StateName, StateData) ->
{xmlelement, Name, Attrs, Els} = Packet, {xmlelement, Name, Attrs, Els} = Packet,
@ -269,7 +285,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
jlib:jid_to_string(To), jlib:jid_to_string(To),
Attrs), Attrs),
Text = xml:element_to_string({xmlelement, Name, Attrs2, Els}), Text = xml:element_to_string({xmlelement, Name, Attrs2, Els}),
send_text(StateData#state.socket, Text), send_text(StateData, Text),
{next_state, StateName, StateData}. {next_state, StateName, StateData}.
@ -278,40 +294,43 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
%% Purpose: Shutdown the fsm %% Purpose: Shutdown the fsm
%% Returns: any %% Returns: any
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
terminate(Reason, StateName, StateData) -> terminate(_Reason, StateName, StateData) ->
case StateName of case StateName of
stream_established -> stream_established ->
ejabberd_router:unregister_local_route(StateData#state.host); lists:foreach(
fun(H) ->
ejabberd_router:unregister_local_route(H)
end, StateData#state.hosts);
_ -> _ ->
ok ok
end, end,
gen_tcp:close(StateData#state.socket), (StateData#state.sockmod):close(StateData#state.socket),
ok. ok.
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% Internal functions %%% Internal functions
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
receiver(Socket, C2SPid) -> receiver(Socket, SockMod, C2SPid) ->
XMLStreamPid = xml_stream:start(C2SPid), XMLStreamPid = xml_stream:start(C2SPid),
receiver(Socket, C2SPid, XMLStreamPid). receiver(Socket, SockMod, C2SPid, XMLStreamPid).
receiver(Socket, C2SPid, XMLStreamPid) -> receiver(Socket, SockMod, C2SPid, XMLStreamPid) ->
case gen_tcp:recv(Socket, 0) of case SockMod:recv(Socket, 0) of
{ok, Text} -> {ok, Text} ->
xml_stream:send_text(XMLStreamPid, Text), xml_stream:send_text(XMLStreamPid, Text),
receiver(Socket, C2SPid, XMLStreamPid); receiver(Socket, SockMod, C2SPid, XMLStreamPid);
{error, Reason} -> {error, _Reason} ->
exit(XMLStreamPid, closed), exit(XMLStreamPid, closed),
gen_fsm:send_event(C2SPid, closed), gen_fsm:send_event(C2SPid, closed),
ok ok
end. end.
send_text(Socket, Text) -> send_text(StateData, Text) ->
gen_tcp:send(Socket,Text). (StateData#state.sockmod):send(StateData#state.socket,Text).
send_element(Socket, El) -> send_element(StateData, El) ->
send_text(Socket, xml:element_to_string(El)). send_text(StateData, xml:element_to_string(El)).
new_id() -> new_id() ->