mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
* src/ejabberd_socket.erl: All XML socket operations moved here
* src/ejabberd_listener.erl: Updated * src/ejabberd_receiver.erl: Likewise * src/ejabberd_c2s.erl: Likewise * src/ejabberd_s2s_in.erl: Likewise * src/ejabberd_s2s_out.erl: Likewise * src/ejabberd_service.erl: Likewise * src/mod_shared_roster.erl: Bugfix * src/mod_roster_odbc.erl: Bugfix SVN Revision: 599
This commit is contained in:
parent
d0e2ac9ed2
commit
4d7cc9301a
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
||||
2006-09-05 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/ejabberd_socket.erl: All XML socket operations moved here
|
||||
* src/ejabberd_listener.erl: Updated
|
||||
* src/ejabberd_receiver.erl: Likewise
|
||||
* src/ejabberd_c2s.erl: Likewise
|
||||
* src/ejabberd_s2s_in.erl: Likewise
|
||||
* src/ejabberd_s2s_out.erl: Likewise
|
||||
* src/ejabberd_service.erl: Likewise
|
||||
|
||||
* src/mod_shared_roster.erl: Bugfix
|
||||
|
||||
* src/mod_roster_odbc.erl: Bugfix
|
||||
|
||||
2006-09-03 Mickael Remond <mickael.remond@process-one.net>
|
||||
|
||||
* src/odbc/odbc_queries.erl: Support for Microsoft SQL Server as a
|
||||
|
@ -17,7 +17,6 @@
|
||||
start_link/2,
|
||||
send_text/2,
|
||||
send_element/2,
|
||||
become_controller/1,
|
||||
get_presence/1]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
@ -40,8 +39,7 @@
|
||||
|
||||
-define(SETS, gb_sets).
|
||||
|
||||
-record(state, {socket, receiver,
|
||||
sockmod,
|
||||
-record(state, {socket,
|
||||
streamid,
|
||||
sasl_state,
|
||||
access,
|
||||
@ -100,9 +98,6 @@ start(SockData, Opts) ->
|
||||
start_link(SockData, Opts) ->
|
||||
gen_fsm:start_link(ejabberd_c2s, [SockData, Opts], ?FSMOPTS).
|
||||
|
||||
become_controller(Pid) ->
|
||||
gen_fsm:send_all_state_event(Pid, become_controller).
|
||||
|
||||
%% Return Username, Resource and presence information
|
||||
get_presence(FsmRef) ->
|
||||
gen_fsm:sync_send_all_state_event(FsmRef, {get_presence}, 1000).
|
||||
@ -118,7 +113,7 @@ get_presence(FsmRef) ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([{SockMod, Socket}, Opts]) ->
|
||||
init([Socket, Opts]) ->
|
||||
Access = case lists:keysearch(access, 1, Opts) of
|
||||
{value, {_, A}} -> A;
|
||||
_ -> all
|
||||
@ -127,11 +122,6 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
{value, {_, S}} -> S;
|
||||
_ -> none
|
||||
end,
|
||||
MaxStanzaSize =
|
||||
case lists:keysearch(max_stanza_size, 1, Opts) of
|
||||
{value, {_, Size}} -> Size;
|
||||
_ -> infinity
|
||||
end,
|
||||
Zlib = lists:member(zlib, Opts),
|
||||
StartTLS = lists:member(starttls, Opts),
|
||||
StartTLSRequired = lists:member(starttls_required, Opts),
|
||||
@ -140,21 +130,14 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
TLSOpts = lists:filter(fun({certfile, _}) -> true;
|
||||
(_) -> false
|
||||
end, Opts),
|
||||
{SockMod1, Socket1, ReceiverPid} =
|
||||
Socket1 =
|
||||
if
|
||||
TLSEnabled ->
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
|
||||
RecPid = ejabberd_receiver:start(
|
||||
TLSSocket, tls, none, MaxStanzaSize),
|
||||
{tls, TLSSocket, RecPid};
|
||||
ejabberd_socket:starttls(Socket, TLSOpts);
|
||||
true ->
|
||||
RecPid = ejabberd_receiver:start(
|
||||
Socket, SockMod, none, MaxStanzaSize),
|
||||
{SockMod, Socket, RecPid}
|
||||
Socket
|
||||
end,
|
||||
{ok, wait_for_stream, #state{socket = Socket1,
|
||||
sockmod = SockMod1,
|
||||
receiver = ReceiverPid,
|
||||
zlib = Zlib,
|
||||
tls = TLS,
|
||||
tls_required = StartTLSRequired,
|
||||
@ -211,7 +194,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
{xmlelement, "mechanism", [],
|
||||
[{xmlcdata, S}]}
|
||||
end, cyrsasl:listmech(Server)),
|
||||
SockMod = StateData#state.sockmod,
|
||||
SockMod = ejabberd_socket:get_sockmod(
|
||||
StateData#state.socket),
|
||||
Zlib = StateData#state.zlib,
|
||||
CompressFeature =
|
||||
case Zlib andalso
|
||||
@ -465,7 +449,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
TLSRequired = StateData#state.tls_required,
|
||||
SockMod = StateData#state.sockmod,
|
||||
SockMod = ejabberd_socket:get_sockmod(StateData#state.socket),
|
||||
case {xml:get_attr_s("xmlns", Attrs), Name} of
|
||||
{?NS_SASL, "auth"} when not ((SockMod == gen_tcp) and TLSRequired) ->
|
||||
Mech = xml:get_attr_s("mechanism", Attrs),
|
||||
@ -474,7 +458,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
Mech,
|
||||
ClientIn) of
|
||||
{ok, Props} ->
|
||||
ejabberd_receiver:reset_stream(StateData#state.receiver),
|
||||
ejabberd_socket:reset_stream(StateData#state.socket),
|
||||
send_element(StateData,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
@ -504,7 +488,6 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
{?NS_TLS, "starttls"} when TLS == true,
|
||||
TLSEnabled == false,
|
||||
SockMod == gen_tcp ->
|
||||
Socket = StateData#state.socket,
|
||||
TLSOpts = case ejabberd_config:get_local_option(
|
||||
{domain_certfile, StateData#state.server}) of
|
||||
undefined ->
|
||||
@ -514,13 +497,12 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
lists:keydelete(
|
||||
certfile, 1, StateData#state.tls_options)]
|
||||
end,
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
|
||||
ejabberd_receiver:starttls(StateData#state.receiver, TLSSocket),
|
||||
Socket = StateData#state.socket,
|
||||
TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
|
||||
send_element(StateData,
|
||||
{xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{sockmod = tls,
|
||||
socket = TLSSocket,
|
||||
StateData#state{socket = TLSSocket,
|
||||
streamid = new_id(),
|
||||
tls_enabled = true
|
||||
}};
|
||||
@ -537,16 +519,12 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
case xml:get_tag_cdata(Method) of
|
||||
"zlib" ->
|
||||
Socket = StateData#state.socket,
|
||||
{ok, ZlibSocket} = ejabberd_zlib:enable_zlib(SockMod,
|
||||
Socket),
|
||||
ejabberd_receiver:compress(StateData#state.receiver,
|
||||
ZlibSocket),
|
||||
ZlibSocket = ejabberd_socket:compress(Socket),
|
||||
send_element(StateData,
|
||||
{xmlelement, "compressed",
|
||||
[{"xmlns", ?NS_COMPRESS}], []}),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{sockmod = ejabberd_zlib,
|
||||
socket = ZlibSocket,
|
||||
StateData#state{socket = ZlibSocket,
|
||||
streamid = new_id()
|
||||
}};
|
||||
_ ->
|
||||
@ -593,7 +571,7 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
||||
case cyrsasl:server_step(StateData#state.sasl_state,
|
||||
ClientIn) of
|
||||
{ok, Props} ->
|
||||
ejabberd_receiver:reset_stream(StateData#state.receiver),
|
||||
ejabberd_socket:reset_stream(StateData#state.socket),
|
||||
send_element(StateData,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
@ -859,12 +837,6 @@ session_established(closed, StateData) ->
|
||||
%% {next_state, NextStateName, NextStateData, Timeout} |
|
||||
%% {stop, Reason, NewStateData}
|
||||
%%----------------------------------------------------------------------
|
||||
handle_event(become_controller, StateName, StateData) ->
|
||||
ok = (StateData#state.sockmod):controlling_process(
|
||||
StateData#state.socket,
|
||||
StateData#state.receiver),
|
||||
ejabberd_receiver:become_controller(StateData#state.receiver),
|
||||
{next_state, StateName, StateData};
|
||||
handle_event(_Event, StateName, StateData) ->
|
||||
{next_state, StateName, StateData}.
|
||||
|
||||
@ -1191,7 +1163,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ok.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@ -1201,11 +1173,11 @@ terminate(_Reason, StateName, StateData) ->
|
||||
change_shaper(StateData, JID) ->
|
||||
Shaper = acl:match_rule(StateData#state.server,
|
||||
StateData#state.shaper, JID),
|
||||
ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
|
||||
ejabberd_socket:change_shaper(StateData#state.socket, Shaper).
|
||||
|
||||
send_text(StateData, Text) ->
|
||||
?DEBUG("Send XML on stream = ~p", [lists:flatten(Text)]),
|
||||
catch (StateData#state.sockmod):send(StateData#state.socket, Text).
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_string(El)).
|
||||
|
@ -92,14 +92,7 @@ accept(ListenSocket, Module, Opts) ->
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
{ok, Pid} = Module:start({gen_tcp, Socket}, Opts),
|
||||
case gen_tcp:controlling_process(Socket, Pid) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, _Reason} ->
|
||||
gen_tcp:close(Socket)
|
||||
end,
|
||||
Module:become_controller(Pid),
|
||||
ejabberd_socket:start(Module, gen_tcp, Socket, Opts),
|
||||
accept(ListenSocket, Module, Opts);
|
||||
{error, Reason} ->
|
||||
?INFO_MSG("(~w) Failed TCP accept: ~w",
|
||||
|
@ -13,14 +13,14 @@
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% API
|
||||
-export([start_link/5,
|
||||
-export([start_link/4,
|
||||
start/3,
|
||||
start/4,
|
||||
change_shaper/2,
|
||||
reset_stream/1,
|
||||
starttls/2,
|
||||
compress/2,
|
||||
become_controller/1,
|
||||
become_controller/2,
|
||||
close/1]).
|
||||
|
||||
%% gen_server callbacks
|
||||
@ -44,9 +44,9 @@
|
||||
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
|
||||
%% Description: Starts the server
|
||||
%%--------------------------------------------------------------------
|
||||
start_link(Socket, SockMod, Shaper, MaxStanzaSize, C2SPid) ->
|
||||
start_link(Socket, SockMod, Shaper, MaxStanzaSize) ->
|
||||
gen_server:start_link(
|
||||
?MODULE, [Socket, SockMod, Shaper, MaxStanzaSize, C2SPid], []).
|
||||
?MODULE, [Socket, SockMod, Shaper, MaxStanzaSize], []).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function: start() -> {ok,Pid} | ignore | {error,Error}
|
||||
@ -58,7 +58,7 @@ start(Socket, SockMod, Shaper) ->
|
||||
start(Socket, SockMod, Shaper, MaxStanzaSize) ->
|
||||
{ok, Pid} = supervisor:start_child(
|
||||
ejabberd_receiver_sup,
|
||||
[Socket, SockMod, Shaper, MaxStanzaSize, self()]),
|
||||
[Socket, SockMod, Shaper, MaxStanzaSize]),
|
||||
Pid.
|
||||
|
||||
change_shaper(Pid, Shaper) ->
|
||||
@ -73,8 +73,8 @@ starttls(Pid, TLSSocket) ->
|
||||
compress(Pid, ZlibSocket) ->
|
||||
gen_server:call(Pid, {compress, ZlibSocket}).
|
||||
|
||||
become_controller(Pid) ->
|
||||
gen_server:call(Pid, become_controller).
|
||||
become_controller(Pid, C2SPid) ->
|
||||
gen_server:call(Pid, {become_controller, C2SPid}).
|
||||
|
||||
close(Pid) ->
|
||||
gen_server:cast(Pid, close).
|
||||
@ -90,8 +90,7 @@ close(Pid) ->
|
||||
%% {stop, Reason}
|
||||
%% Description: Initiates the server
|
||||
%%--------------------------------------------------------------------
|
||||
init([Socket, SockMod, Shaper, MaxStanzaSize, C2SPid]) ->
|
||||
XMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
|
||||
init([Socket, SockMod, Shaper, MaxStanzaSize]) ->
|
||||
ShaperState = shaper:new(Shaper),
|
||||
Timeout = case SockMod of
|
||||
ssl ->
|
||||
@ -102,9 +101,7 @@ init([Socket, SockMod, Shaper, MaxStanzaSize, C2SPid]) ->
|
||||
{ok, #state{socket = Socket,
|
||||
sock_mod = SockMod,
|
||||
shaper_state = ShaperState,
|
||||
c2s_pid = C2SPid,
|
||||
max_stanza_size = MaxStanzaSize,
|
||||
xml_stream_state = XMLStreamState,
|
||||
timeout = Timeout}}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
@ -154,10 +151,13 @@ handle_call(reset_stream, _From,
|
||||
NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
|
||||
Reply = ok,
|
||||
{reply, Reply, State#state{xml_stream_state = NewXMLStreamState}};
|
||||
handle_call(become_controller, _From, State) ->
|
||||
activate_socket(State),
|
||||
handle_call({become_controller, C2SPid}, _From, State) ->
|
||||
XMLStreamState = xml_stream:new(C2SPid, State#state.max_stanza_size),
|
||||
NewState = State#state{c2s_pid = C2SPid,
|
||||
xml_stream_state = XMLStreamState},
|
||||
activate_socket(NewState),
|
||||
Reply = ok,
|
||||
{reply, Reply, State};
|
||||
{reply, Reply, NewState};
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
@ -14,7 +14,6 @@
|
||||
%% External exports
|
||||
-export([start/2,
|
||||
start_link/2,
|
||||
become_controller/1,
|
||||
match_domain/2]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
@ -37,8 +36,6 @@
|
||||
-define(DICT, dict).
|
||||
|
||||
-record(state, {socket,
|
||||
sockmod,
|
||||
receiver,
|
||||
streamid,
|
||||
shaper,
|
||||
tls = false,
|
||||
@ -87,9 +84,6 @@ start(SockData, Opts) ->
|
||||
start_link(SockData, Opts) ->
|
||||
gen_fsm:start_link(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS).
|
||||
|
||||
become_controller(Pid) ->
|
||||
gen_fsm:send_all_state_event(Pid, become_controller).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Callback functions from gen_fsm
|
||||
%%%----------------------------------------------------------------------
|
||||
@ -101,19 +95,12 @@ become_controller(Pid) ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([{SockMod, Socket}, Opts]) ->
|
||||
?INFO_MSG("started: ~p", [{SockMod, Socket}]),
|
||||
init([Socket, Opts]) ->
|
||||
?INFO_MSG("started: ~p", [Socket]),
|
||||
Shaper = case lists:keysearch(shaper, 1, Opts) of
|
||||
{value, {_, S}} -> S;
|
||||
_ -> none
|
||||
end,
|
||||
MaxStanzaSize =
|
||||
case lists:keysearch(max_stanza_size, 1, Opts) of
|
||||
{value, {_, Size}} -> Size;
|
||||
_ -> infinity
|
||||
end,
|
||||
ReceiverPid = ejabberd_receiver:start(
|
||||
Socket, SockMod, none, MaxStanzaSize),
|
||||
StartTLS = case ejabberd_config:get_local_option(s2s_use_starttls) of
|
||||
undefined ->
|
||||
false;
|
||||
@ -129,8 +116,6 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
|
||||
{ok, wait_for_stream,
|
||||
#state{socket = Socket,
|
||||
sockmod = SockMod,
|
||||
receiver = ReceiverPid,
|
||||
streamid = new_id(),
|
||||
shaper = Shaper,
|
||||
tls = StartTLS,
|
||||
@ -214,7 +199,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
{xmlelement, Name, Attrs, Els} = El,
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
SockMod = StateData#state.sockmod,
|
||||
SockMod = ejabberd_socket:get_sockmod(StateData#state.socket),
|
||||
case {xml:get_attr_s("xmlns", Attrs), Name} of
|
||||
{?NS_TLS, "starttls"} when TLS == true,
|
||||
TLSEnabled == false,
|
||||
@ -222,13 +207,11 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
?INFO_MSG("starttls", []),
|
||||
Socket = StateData#state.socket,
|
||||
TLSOpts = StateData#state.tls_options,
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
|
||||
ejabberd_receiver:starttls(StateData#state.receiver, TLSSocket),
|
||||
TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
|
||||
send_element(StateData,
|
||||
{xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{sockmod = tls,
|
||||
socket = TLSSocket,
|
||||
StateData#state{socket = TLSSocket,
|
||||
streamid = new_id(),
|
||||
tls_enabled = true
|
||||
}};
|
||||
@ -267,8 +250,8 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
end,
|
||||
if
|
||||
AuthRes ->
|
||||
ejabberd_receiver:reset_stream(
|
||||
StateData#state.receiver),
|
||||
ejabberd_socket:reset_stream(
|
||||
StateData#state.socket),
|
||||
send_element(StateData,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
@ -467,12 +450,6 @@ stream_established(closed, StateData) ->
|
||||
%% {next_state, NextStateName, NextStateData, Timeout} |
|
||||
%% {stop, Reason, NewStateData}
|
||||
%%----------------------------------------------------------------------
|
||||
handle_event(become_controller, StateName, StateData) ->
|
||||
ok = (StateData#state.sockmod):controlling_process(
|
||||
StateData#state.socket,
|
||||
StateData#state.receiver),
|
||||
ejabberd_receiver:become_controller(StateData#state.receiver),
|
||||
{next_state, StateName, StateData};
|
||||
handle_event(_Event, StateName, StateData) ->
|
||||
{next_state, StateName, StateData}.
|
||||
|
||||
@ -517,7 +494,7 @@ handle_info(_, StateName, StateData) ->
|
||||
%%----------------------------------------------------------------------
|
||||
terminate(Reason, _StateName, StateData) ->
|
||||
?INFO_MSG("terminated: ~p", [Reason]),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ok.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@ -525,7 +502,7 @@ terminate(Reason, _StateName, StateData) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
send_text(StateData, Text) ->
|
||||
(StateData#state.sockmod):send(StateData#state.socket, Text).
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_string(El)).
|
||||
@ -533,7 +510,7 @@ send_element(StateData, El) ->
|
||||
|
||||
change_shaper(StateData, Host, JID) ->
|
||||
Shaper = acl:match_rule(Host, StateData#state.shaper, JID),
|
||||
ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
|
||||
ejabberd_socket:change_shaper(StateData#state.socket, Shaper).
|
||||
|
||||
|
||||
new_id() ->
|
||||
|
@ -36,8 +36,7 @@
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(state, {socket, receiver,
|
||||
sockmod,
|
||||
-record(state, {socket,
|
||||
streamid,
|
||||
use_v10,
|
||||
tls = false,
|
||||
@ -152,9 +151,6 @@ open_socket(init, StateData) ->
|
||||
end
|
||||
end, {error, badarg}, AddrList) of
|
||||
{ok, Socket} ->
|
||||
ReceiverPid = ejabberd_receiver:start(Socket, gen_tcp, none),
|
||||
ok = gen_tcp:controlling_process(Socket, ReceiverPid),
|
||||
ejabberd_receiver:become_controller(ReceiverPid),
|
||||
Version = if
|
||||
StateData#state.use_v10 ->
|
||||
" version='1.0'";
|
||||
@ -162,9 +158,7 @@ open_socket(init, StateData) ->
|
||||
""
|
||||
end,
|
||||
NewStateData = StateData#state{socket = Socket,
|
||||
sockmod = gen_tcp,
|
||||
tls_enabled = false,
|
||||
receiver = ReceiverPid,
|
||||
streamid = new_id()},
|
||||
send_text(NewStateData, io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.server,
|
||||
@ -184,20 +178,23 @@ open_socket1(Addr, Port) ->
|
||||
false -> {error, badarg};
|
||||
ASCIIAddr ->
|
||||
?DEBUG("s2s_out: connecting to ~s:~p~n", [ASCIIAddr, Port]),
|
||||
case catch gen_tcp:connect(ASCIIAddr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}]) of
|
||||
case catch ejabberd_socket:connect(
|
||||
ASCIIAddr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}]) of
|
||||
{ok, _Socket} = R -> R;
|
||||
{error, Reason1} ->
|
||||
?DEBUG("s2s_out: connect return ~p~n", [Reason1]),
|
||||
catch gen_tcp:connect(Addr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}, inet6]);
|
||||
catch ejabberd_socket:connect(
|
||||
Addr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}, inet6]);
|
||||
{'EXIT', Reason1} ->
|
||||
?DEBUG("s2s_out: connect crashed ~p~n", [Reason1]),
|
||||
catch gen_tcp:connect(Addr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}, inet6])
|
||||
catch ejabberd_socket:connect(
|
||||
Addr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}, inet6])
|
||||
end
|
||||
end,
|
||||
case Res of
|
||||
@ -363,7 +360,7 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
|
||||
StartTLSRequired and (not StateData#state.tls) ->
|
||||
?INFO_MSG("restarted: ~p", [{StateData#state.myname,
|
||||
StateData#state.server}]),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
{next_state, reopen_socket,
|
||||
StateData#state{socket = undefined,
|
||||
use_v10 = false}};
|
||||
@ -373,7 +370,7 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
|
||||
?INFO_MSG("restarted: ~p", [{StateData#state.myname,
|
||||
StateData#state.server}]),
|
||||
% TODO: clear message queue
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
{next_state, reopen_socket, StateData#state{socket = undefined,
|
||||
use_v10 = false}}
|
||||
end;
|
||||
@ -406,8 +403,7 @@ wait_for_auth_result({xmlstreamelement, El}, StateData) ->
|
||||
?NS_SASL ->
|
||||
?INFO_MSG("auth: ~p", [{StateData#state.myname,
|
||||
StateData#state.server}]),
|
||||
ejabberd_receiver:reset_stream(
|
||||
StateData#state.receiver),
|
||||
ejabberd_socket:reset_stream(StateData#state.socket),
|
||||
send_text(StateData,
|
||||
io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.server,
|
||||
@ -427,7 +423,7 @@ wait_for_auth_result({xmlstreamelement, El}, StateData) ->
|
||||
?NS_SASL ->
|
||||
?INFO_MSG("restarted: ~p", [{StateData#state.myname,
|
||||
StateData#state.server}]),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
{next_state, reopen_socket,
|
||||
StateData#state{socket = undefined}};
|
||||
_ ->
|
||||
@ -477,11 +473,8 @@ wait_for_starttls_proceed({xmlstreamelement, El}, StateData) ->
|
||||
certfile, 1,
|
||||
StateData#state.tls_options)]
|
||||
end,
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
|
||||
ejabberd_receiver:starttls(
|
||||
StateData#state.receiver, TLSSocket),
|
||||
NewStateData = StateData#state{sockmod = tls,
|
||||
socket = TLSSocket,
|
||||
TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
|
||||
NewStateData = StateData#state{socket = TLSSocket,
|
||||
streamid = new_id(),
|
||||
tls_enabled = true
|
||||
},
|
||||
@ -672,7 +665,7 @@ terminate(Reason, StateName, StateData) ->
|
||||
undefined ->
|
||||
ok;
|
||||
_Socket ->
|
||||
ejabberd_receiver:close(StateData#state.receiver)
|
||||
ejabberd_socket:close(StateData#state.socket)
|
||||
end,
|
||||
ok.
|
||||
|
||||
@ -681,7 +674,7 @@ terminate(Reason, StateName, StateData) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
send_text(StateData, Text) ->
|
||||
(StateData#state.sockmod):send(StateData#state.socket, Text).
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_string(El)).
|
||||
|
@ -16,8 +16,7 @@
|
||||
-export([start/2,
|
||||
start_link/2,
|
||||
send_text/2,
|
||||
send_element/2,
|
||||
become_controller/1]).
|
||||
send_element/2]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1,
|
||||
@ -33,7 +32,7 @@
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(state, {socket, receiver, streamid, sockmod,
|
||||
-record(state, {socket, streamid,
|
||||
hosts, password, access}).
|
||||
|
||||
%-define(DBGFSM, true).
|
||||
@ -79,9 +78,6 @@ start(SockData, Opts) ->
|
||||
start_link(SockData, Opts) ->
|
||||
gen_fsm:start_link(ejabberd_service, [SockData, Opts], ?FSMOPTS).
|
||||
|
||||
become_controller(Pid) ->
|
||||
gen_fsm:send_all_state_event(Pid, become_controller).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Callback functions from gen_fsm
|
||||
%%%----------------------------------------------------------------------
|
||||
@ -93,7 +89,7 @@ become_controller(Pid) ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([{SockMod, Socket}, Opts]) ->
|
||||
init([Socket, Opts]) ->
|
||||
Access = case lists:keysearch(access, 1, Opts) of
|
||||
{value, {_, A}} -> A;
|
||||
_ -> all
|
||||
@ -123,11 +119,8 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
ReceiverPid = ejabberd_receiver:start(Socket, SockMod, none),
|
||||
{ok, wait_for_stream, #state{socket = Socket,
|
||||
receiver = ReceiverPid,
|
||||
streamid = new_id(),
|
||||
sockmod = SockMod,
|
||||
hosts = Hosts,
|
||||
password = Password,
|
||||
access = Access
|
||||
@ -259,12 +252,6 @@ stream_established(closed, StateData) ->
|
||||
%% {next_state, NextStateName, NextStateData, Timeout} |
|
||||
%% {stop, Reason, NewStateData}
|
||||
%%----------------------------------------------------------------------
|
||||
handle_event(become_controller, StateName, StateData) ->
|
||||
ok = (StateData#state.sockmod):controlling_process(
|
||||
StateData#state.socket,
|
||||
StateData#state.receiver),
|
||||
ejabberd_receiver:become_controller(StateData#state.receiver),
|
||||
{next_state, StateName, StateData};
|
||||
handle_event(_Event, StateName, StateData) ->
|
||||
{next_state, StateName, StateData}.
|
||||
|
||||
@ -328,7 +315,7 @@ terminate(Reason, StateName, StateData) ->
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ok.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@ -336,12 +323,11 @@ terminate(Reason, StateName, StateData) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
send_text(StateData, Text) ->
|
||||
(StateData#state.sockmod):send(StateData#state.socket,Text).
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_string(El)).
|
||||
|
||||
|
||||
new_id() ->
|
||||
randoms:get_string().
|
||||
|
||||
|
101
src/ejabberd_socket.erl
Normal file
101
src/ejabberd_socket.erl
Normal file
@ -0,0 +1,101 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_socket.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose : Socket with zlib and TLS support library
|
||||
%%% Created : 23 Aug 2006 by Alexey Shchepin <alex@alex.sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd_socket).
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
%% API
|
||||
-export([start/4,
|
||||
connect/3,
|
||||
starttls/2,
|
||||
compress/1,
|
||||
reset_stream/1,
|
||||
send/2,
|
||||
change_shaper/2,
|
||||
get_sockmod/1,
|
||||
close/1]).
|
||||
|
||||
-record(socket_state, {sockmod, socket, receiver}).
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function:
|
||||
%% Description:
|
||||
%%--------------------------------------------------------------------
|
||||
start(Module, SockMod, Socket, Opts) ->
|
||||
MaxStanzaSize =
|
||||
case lists:keysearch(max_stanza_size, 1, Opts) of
|
||||
{value, {_, Size}} -> Size;
|
||||
_ -> infinity
|
||||
end,
|
||||
Receiver = ejabberd_receiver:start(Socket, SockMod, none, MaxStanzaSize),
|
||||
SocketData = #socket_state{sockmod = SockMod,
|
||||
socket = Socket,
|
||||
receiver = Receiver},
|
||||
{ok, Pid} = Module:start(SocketData, Opts),
|
||||
case SockMod:controlling_process(Socket, Receiver) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, _Reason} ->
|
||||
SockMod:close(Socket)
|
||||
end,
|
||||
ejabberd_receiver:become_controller(Receiver, Pid).
|
||||
|
||||
connect(Addr, Port, Opts) ->
|
||||
case gen_tcp:connect(Addr, Port, Opts) of
|
||||
{ok, Socket} ->
|
||||
Receiver = ejabberd_receiver:start(Socket, gen_tcp, none),
|
||||
SocketData = #socket_state{sockmod = gen_tcp,
|
||||
socket = Socket,
|
||||
receiver = Receiver},
|
||||
Pid = self(),
|
||||
case gen_tcp:controlling_process(Socket, Receiver) of
|
||||
ok ->
|
||||
ejabberd_receiver:become_controller(Receiver, Pid),
|
||||
{ok, SocketData};
|
||||
{error, _Reason} = Error ->
|
||||
gen_tcp:close(Socket),
|
||||
Error
|
||||
end;
|
||||
{error, Reason} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
starttls(SocketData, TLSOpts) ->
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(SocketData#socket_state.socket, TLSOpts),
|
||||
ejabberd_receiver:starttls(SocketData#socket_state.receiver, TLSSocket),
|
||||
SocketData#socket_state{socket = TLSSocket, sockmod = tls}.
|
||||
|
||||
compress(SocketData) ->
|
||||
{ok, ZlibSocket} = ejabberd_zlib:enable_zlib(
|
||||
SocketData#socket_state.sockmod,
|
||||
SocketData#socket_state.socket),
|
||||
ejabberd_receiver:compress(SocketData#socket_state.receiver, ZlibSocket),
|
||||
SocketData#socket_state{socket = ZlibSocket, sockmod = ejabberd_zlib}.
|
||||
|
||||
reset_stream(SocketData) ->
|
||||
ejabberd_receiver:reset_stream(SocketData#socket_state.receiver).
|
||||
|
||||
send(SocketData, Data) ->
|
||||
catch (SocketData#socket_state.sockmod):send(
|
||||
SocketData#socket_state.socket, Data).
|
||||
|
||||
change_shaper(SocketData, Shaper) ->
|
||||
ejabberd_receiver:change_shaper(SocketData#socket_state.receiver, Shaper).
|
||||
|
||||
get_sockmod(SocketData) ->
|
||||
SocketData#socket_state.sockmod.
|
||||
|
||||
close(SocketData) ->
|
||||
ejabberd_receiver:close(SocketData#socket_state.receiver).
|
||||
|
||||
%%====================================================================
|
||||
%% Internal functions
|
||||
%%====================================================================
|
@ -141,11 +141,10 @@ get_user_roster(Acc, {LUser, LServer}) ->
|
||||
R ->
|
||||
SJID = jlib:jid_to_string(R#roster.jid),
|
||||
Groups = lists:flatmap(
|
||||
fun({S, G}) ->
|
||||
case jlib:jid_tolower(S) of
|
||||
SJID -> [G];
|
||||
_ -> []
|
||||
end
|
||||
fun({S, G}) when S == SJID ->
|
||||
[G];
|
||||
(_) ->
|
||||
[]
|
||||
end, JIDGroups),
|
||||
[R#roster{groups = Groups}]
|
||||
end
|
||||
|
@ -332,7 +332,8 @@ get_user_displayed_groups(US) ->
|
||||
[Group || Group <- DisplayedGroups1, is_group_enabled(Host, Group)].
|
||||
|
||||
is_user_in_group(US, Group, Host) ->
|
||||
case mnesia:match_object(#sr_user{us=US, group_host={Group, Host}}) of
|
||||
case catch mnesia:dirty_match_object(
|
||||
#sr_user{us=US, group_host={Group, Host}}) of
|
||||
[] -> false;
|
||||
_ -> true
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user