+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
start_link/2,
send_text/2,
send_element/2,
- become_controller/1,
get_presence/1]).
%% gen_fsm callbacks
-define(SETS, gb_sets).
--record(state, {socket, receiver,
- sockmod,
+-record(state, {socket,
streamid,
sasl_state,
access,
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).
%% ignore |
%% {stop, StopReason}
%%----------------------------------------------------------------------
-init([{SockMod, Socket}, Opts]) ->
+init([Socket, Opts]) ->
Access = case lists:keysearch(access, 1, Opts) of
{value, {_, A}} -> A;
_ -> all
{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),
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,
{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
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),
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}], []}),
{?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 ->
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
}};
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()
}};
_ ->
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}], []}),
%% {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}.
_ ->
ok
end,
- ejabberd_receiver:close(StateData#state.receiver),
+ ejabberd_socket:close(StateData#state.socket),
ok.
%%%----------------------------------------------------------------------
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)).
_ ->
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",
-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
%% 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}
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) ->
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).
%% {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 ->
{ok, #state{socket = Socket,
sock_mod = SockMod,
shaper_state = ShaperState,
- c2s_pid = C2SPid,
max_stanza_size = MaxStanzaSize,
- xml_stream_state = XMLStreamState,
timeout = Timeout}}.
%%--------------------------------------------------------------------
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}.
%% External exports
-export([start/2,
start_link/2,
- become_controller/1,
match_domain/2]).
%% gen_fsm callbacks
-define(DICT, dict).
-record(state, {socket,
- sockmod,
- receiver,
streamid,
shaper,
tls = false,
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
%%%----------------------------------------------------------------------
%% 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;
Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
{ok, wait_for_stream,
#state{socket = Socket,
- sockmod = SockMod,
- receiver = ReceiverPid,
streamid = new_id(),
shaper = Shaper,
tls = StartTLS,
{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,
?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
}};
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}], []}),
%% {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}.
%%----------------------------------------------------------------------
terminate(Reason, _StateName, StateData) ->
?INFO_MSG("terminated: ~p", [Reason]),
- ejabberd_receiver:close(StateData#state.receiver),
+ ejabberd_socket:close(StateData#state.socket),
ok.
%%%----------------------------------------------------------------------
%%%----------------------------------------------------------------------
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)).
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() ->
-include("ejabberd.hrl").
-include("jlib.hrl").
--record(state, {socket, receiver,
- sockmod,
+-record(state, {socket,
streamid,
use_v10,
tls = false,
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'";
""
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,
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
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}};
?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;
?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,
?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}};
_ ->
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
},
undefined ->
ok;
_Socket ->
- ejabberd_receiver:close(StateData#state.receiver)
+ ejabberd_socket:close(StateData#state.socket)
end,
ok.
%%%----------------------------------------------------------------------
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)).
-export([start/2,
start_link/2,
send_text/2,
- send_element/2,
- become_controller/1]).
+ send_element/2]).
%% gen_fsm callbacks
-export([init/1,
-include("ejabberd.hrl").
-include("jlib.hrl").
--record(state, {socket, receiver, streamid, sockmod,
+-record(state, {socket, streamid,
hosts, password, access}).
%-define(DBGFSM, true).
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
%%%----------------------------------------------------------------------
%% ignore |
%% {stop, StopReason}
%%----------------------------------------------------------------------
-init([{SockMod, Socket}, Opts]) ->
+init([Socket, Opts]) ->
Access = case lists:keysearch(access, 1, Opts) of
{value, {_, A}} -> A;
_ -> all
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
%% {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}.
_ ->
ok
end,
- ejabberd_receiver:close(StateData#state.receiver),
+ ejabberd_socket:close(StateData#state.socket),
ok.
%%%----------------------------------------------------------------------
%%%----------------------------------------------------------------------
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().
--- /dev/null
+%%%----------------------------------------------------------------------
+%%% 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
+%%====================================================================
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
[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.