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:
parent
392d64ee8b
commit
a704f9760d
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() ->
|
||||||
|
|
|
@ -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() ->
|
||||||
|
|
Loading…
Reference in New Issue
Block a user