Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e1eef9f84b | |||
| 441d31ac3e | |||
| fcc4adcde5 | |||
| 9057197446 | |||
| 8515833954 | |||
| 51fa955e11 | |||
| 7e948fbbac | |||
| de306d0364 | |||
| 7214549508 | |||
| 4cb24c3e6a | |||
| 16c2d399e9 | |||
| 54d05f64ba | |||
| 2a542e9e09 | |||
| d9487135c0 | |||
| 539000bf62 | |||
| 4646bf818a | |||
| 751fbec0b6 | |||
| 37f56859e7 | |||
| 9d7006dfa2 | |||
| b2acdac5fa | |||
| 5d4093b8ac | |||
| 6a3afa778b | |||
| d574757de4 | |||
| 5b9526d998 | |||
| 79f5d2772e | |||
| 78aeb15aac | |||
| d786782a0f | |||
| ccfcfa49fa | |||
| e734ad1682 | |||
| 4ea5e493ea | |||
| d31ab5ca13 | |||
| 1632aec61e | |||
| 8583e3f9be | |||
| 23b78b0f0c | |||
| 677a6004cf | |||
| ec668cd85a | |||
| 0b660a42f4 | |||
| 8c8c7b1e3f | |||
| 4211540272 | |||
| 6bdabb0c3b | |||
| 647acc7768 |
@@ -7,11 +7,11 @@
|
||||
2006-09-26 Mickael Remond <mickael.remond@process-one.net>
|
||||
|
||||
* doc/release_notes_1.1.2.txt: Draft release notes.
|
||||
|
||||
|
||||
* src/msgs/pl.msg: Updated (thanks to Andrzej Smyk).
|
||||
|
||||
* src/ejabberd_s2s.erl: More precise message for the new s2s
|
||||
statistic command.
|
||||
* src/ejabberd_s2s.erl: Added incoming-s2s-number and
|
||||
outgoing-s2s-number ejabberdctl commands
|
||||
|
||||
* src/mod_muc/mod_muc_room.erl: Minor english update.
|
||||
* src/msgs/pl.msg: Likewise.
|
||||
@@ -48,39 +48,27 @@
|
||||
|
||||
* doc/introduction.tex: Minor doc updates for release 1.1.2.
|
||||
|
||||
2006-09-25 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/ejabberd_s2s.erl: Added incoming-s2s-number and
|
||||
outgoing-s2s-number ejabberdctl commands
|
||||
|
||||
* src/ejabberd_socket.erl: Support for non-xml sockets
|
||||
* src/ejabberd_c2s.erl: Likewise
|
||||
* src/ejabberd_s2s_in.erl: Likewise
|
||||
* src/ejabberd_service.erl: Likewise
|
||||
* src/web/ejabberd_http.erl: Likewise
|
||||
|
||||
2006-09-24 Mickael Remond <mickael.remond@process-one.net>
|
||||
|
||||
* src/msgs/es.msg: Updated Spanish translation (thanks to Badlop).
|
||||
|
||||
* src/mod_muc/mod_muc_room.erl: Strings update (thanks to Sergei
|
||||
Golovan).
|
||||
* src/msgs/ru.msg: Updated Russian translation (thanks to Sergei
|
||||
Golovan).
|
||||
* src/msgs/uk.msg: Updated Ukrainian translation (thanks to Sergei
|
||||
Golovan).
|
||||
* src/msgs/fr.msg: Update French translation.
|
||||
|
||||
* src/mod_muc/mod_muc_room.erl: Strings update (thanks to Serguei
|
||||
Golovan).
|
||||
* src/msgs/ru.msg: Updated Russian translation (thanks to Serguei
|
||||
Golovan).
|
||||
* src/msgs/uk.msg: Updated Ukrainian translation (thanks to Serguei
|
||||
Golovan).
|
||||
* src/msgs/fr.msg: Updated French translation.
|
||||
|
||||
* src/doc/guide.html: Minor W3C compliance fix in an Hevea
|
||||
generated URL.
|
||||
|
||||
* src/doc/features.html: Added to be consistent (guide.html is in
|
||||
the repository to make Latex optional, but still allow access to
|
||||
the doc).
|
||||
* src/doc/features.html: Added to be consistent (guide.html is in the
|
||||
repository to make Latex optional, but still allow access to the doc).
|
||||
|
||||
2006-09-23 Mickael Remond <mickael.remond@process-one.net>
|
||||
|
||||
* src/ejabberd.hrl: Updated to version 1.1.2
|
||||
* src/ejabberd.hrl: Updated to version 1.1.2
|
||||
|
||||
2006-09-23 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
@@ -136,8 +124,6 @@
|
||||
escaping, added new image buttons, chatroom titles now point to
|
||||
xmpp: URIs (thanks to Badlop)
|
||||
|
||||
* src/ejabberd_listener.erl: Bugfix
|
||||
|
||||
2006-09-05 Mickael Remond <mickael.remond@process-one.net>
|
||||
|
||||
* src/mod_muc/mod_muc.erl: It is now possible to configure the MUC room
|
||||
@@ -149,14 +135,6 @@
|
||||
|
||||
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
|
||||
|
||||
+130
-4
@@ -182,9 +182,10 @@ SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
|
||||
<LI CLASS="li-toc"><A HREF="#htoc88">B.4 ejabberd 1.0.0</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc89">B.5 ejabberd 1.1.0</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc90">B.6 ejabberd 1.1.1</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc91">B.7 ejabberd 1.1.2</A>
|
||||
</UL>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc91">C Acknowledgements</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc92">D Copyright Information</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc92">C Acknowledgements</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc93">D Copyright Information</A>
|
||||
</UL>
|
||||
|
||||
<!--TOC section Introduction-->
|
||||
@@ -3985,11 +3986,136 @@ References
|
||||
- Frequently Asked Questions:
|
||||
http://ejabberd.jabber.ru/faq
|
||||
|
||||
END
|
||||
</PRE>
|
||||
<!--TOC subsection ejabberd 1.1.2-->
|
||||
|
||||
<H3 CLASS="subsection"><A NAME="htoc91">B.7</A> ejabberd 1.1.2</H3><!--SEC END -->
|
||||
|
||||
<PRE CLASS="verbatim">
|
||||
Release Notes
|
||||
ejabberd 1.1.2
|
||||
27 September 2006
|
||||
|
||||
This document describes the main changes in ejabberd 1.1.2.
|
||||
|
||||
This version is a major improvement over ejabberd 1.1.1, improving the
|
||||
overall behaviour of the server in many areas. Users of ejabberd 1.1.1
|
||||
should upgrade to this new release for improved robustness and compliance.
|
||||
|
||||
ejabberd can be downloaded from the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
Detailed information can be found in the Feature Sheet and in the
|
||||
Installation and Operation Guide which are both available on the
|
||||
Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/docs.html
|
||||
|
||||
ejabberd includes 44 improvements. A complete list of changes can be
|
||||
retrieved from:
|
||||
http://redir.process-one.net/ejabberd-1.1.2
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
LDAP Improvements
|
||||
|
||||
- Major improvements have been made on the LDAP module. It is now more
|
||||
flexible and more robust.
|
||||
|
||||
HTTP Polling Fixes
|
||||
|
||||
- The HTTP polling modules have been fixed and improved: the connections are
|
||||
closed properly and polled messages cannot be lost anymore.
|
||||
|
||||
Roster Management Improvement
|
||||
|
||||
- Roster management improvements increase reliability, especially in cases
|
||||
where users are on different servers.
|
||||
- Shared rosters are more reliable.
|
||||
|
||||
Improved Robustness
|
||||
|
||||
- It is now possible to limit the number of opened connections for a single
|
||||
user.
|
||||
|
||||
Relational databases
|
||||
|
||||
- Database support: Microsoft SQL Server is now officially supported in ODBC
|
||||
mode.
|
||||
|
||||
Publish-Subscribe Improvement
|
||||
|
||||
- Restricting node creation with a dedicated ACL rule is now possible.
|
||||
|
||||
Localization
|
||||
|
||||
- A Czech translation has been added.
|
||||
- Translations have been updated.
|
||||
|
||||
Binary Installer
|
||||
|
||||
- New binary installer for Windows including all requirements.
|
||||
- Improved installers for Linux and MacOSX (PowerPC)
|
||||
|
||||
XMPP Compliancy
|
||||
|
||||
- Some protocol compliance fix have been added, after the Portland XMPP
|
||||
Interop Meeting in July.
|
||||
|
||||
Miscelanous
|
||||
|
||||
- MUC have been improved (logging rendering).
|
||||
- The command line tool ejabberdctl has been improved.
|
||||
- The build chain has been improved, including MacOSX support.
|
||||
- The documentation has been improved and updated to describe the new
|
||||
features.
|
||||
|
||||
Bugfixes
|
||||
|
||||
- Anonymous login bugfixes.
|
||||
- Please refer to the ChangeLog file supplied with this release regarding
|
||||
all improvements in ejabberd.
|
||||
|
||||
|
||||
Installation Notes
|
||||
|
||||
Supported Erlang Version
|
||||
|
||||
- You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.2.
|
||||
- The recommanded version is Erlang/OTP R10B-10.
|
||||
- Erlang/OTP R11B has not yet been fully certified for ejabberd.
|
||||
|
||||
Installation
|
||||
|
||||
Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
|
||||
They can be retrieved from:
|
||||
http://www.process-one.net/en/projects/ejabberd/download.html
|
||||
|
||||
Migration Notes
|
||||
|
||||
- Before any migration, ejabberd system and database must be properly
|
||||
backed up.
|
||||
- The relational database schema has changed between version 1.1.1 and
|
||||
1.1.2. An "askmessage" column needs to be added in the "rosterusers" table
|
||||
to perform the migration.
|
||||
|
||||
|
||||
References
|
||||
|
||||
Contributed tutorials and documents of interest are:
|
||||
- Migration from other XMPP servers to ejabberd:
|
||||
http://ejabberd.jabber.ru/migrate-to-ejabberd
|
||||
- Transport configuration for connecting to other networks:
|
||||
http://ejabberd.jabber.ru/tutorials-transports
|
||||
- Frequently Asked Questions:
|
||||
http://ejabberd.jabber.ru/faq
|
||||
|
||||
END
|
||||
</PRE>
|
||||
<!--TOC section Acknowledgements-->
|
||||
|
||||
<H2 CLASS="section"><A NAME="htoc91">C</A> <A NAME="acknowledgements">Acknowledgements</A></H2><!--SEC END -->
|
||||
<H2 CLASS="section"><A NAME="htoc92">C</A> <A NAME="acknowledgements">Acknowledgements</A></H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:acknowledgements"></A>
|
||||
Thanks to all people who contributed to this guide:
|
||||
@@ -4006,7 +4132,7 @@ Alexey Shchepin (<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT
|
||||
</UL>
|
||||
<!--TOC section Copyright Information-->
|
||||
|
||||
<H2 CLASS="section"><A NAME="htoc92">D</A> <A NAME="copyright">Copyright Information</A></H2><!--SEC END -->
|
||||
<H2 CLASS="section"><A NAME="htoc93">D</A> <A NAME="copyright">Copyright Information</A></H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:copyright"></A>
|
||||
Ejabberd Installation and Operation Guide.<BR>
|
||||
|
||||
@@ -3077,6 +3077,8 @@ figure~\ref{fig:webadmmainru} with figure~\ref{fig:webadmmain})
|
||||
\subsection{ejabberd 1.1.1}
|
||||
\verbatiminput{release_notes_1.1.1.txt}
|
||||
|
||||
\subsection{ejabberd 1.1.2}
|
||||
\verbatiminput{release_notes_1.1.2.txt}
|
||||
|
||||
\section{\aname{acknowledgements}{Acknowledgements}}
|
||||
\label{sec:acknowledgements}
|
||||
|
||||
@@ -63,9 +63,6 @@ Binary Installer
|
||||
- New binary installer for Windows including all requirements.
|
||||
- Improved installers for Linux and MacOSX (PowerPC)
|
||||
|
||||
|
||||
- Anonymous login bugfixes.
|
||||
|
||||
XMPP Compliancy
|
||||
|
||||
- Some protocol compliance fix have been added, after the Portland XMPP
|
||||
@@ -81,6 +78,7 @@ Miscelanous
|
||||
|
||||
Bugfixes
|
||||
|
||||
- Anonymous login bugfixes.
|
||||
- Please refer to the ChangeLog file supplied with this release regarding
|
||||
all improvements in ejabberd.
|
||||
|
||||
|
||||
+45
-21
@@ -17,7 +17,7 @@
|
||||
start_link/2,
|
||||
send_text/2,
|
||||
send_element/2,
|
||||
socket_type/0,
|
||||
become_controller/1,
|
||||
get_presence/1]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
-define(SETS, gb_sets).
|
||||
|
||||
-record(state, {socket,
|
||||
-record(state, {socket, receiver,
|
||||
sockmod,
|
||||
streamid,
|
||||
sasl_state,
|
||||
access,
|
||||
@@ -99,8 +100,8 @@ start(SockData, Opts) ->
|
||||
start_link(SockData, Opts) ->
|
||||
gen_fsm:start_link(ejabberd_c2s, [SockData, Opts], ?FSMOPTS).
|
||||
|
||||
socket_type() ->
|
||||
xml_stream.
|
||||
become_controller(Pid) ->
|
||||
gen_fsm:send_all_state_event(Pid, become_controller).
|
||||
|
||||
%% Return Username, Resource and presence information
|
||||
get_presence(FsmRef) ->
|
||||
@@ -117,7 +118,7 @@ get_presence(FsmRef) ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([Socket, Opts]) ->
|
||||
init([{SockMod, Socket}, Opts]) ->
|
||||
Access = case lists:keysearch(access, 1, Opts) of
|
||||
{value, {_, A}} -> A;
|
||||
_ -> all
|
||||
@@ -126,6 +127,11 @@ init([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),
|
||||
@@ -134,14 +140,21 @@ init([Socket, Opts]) ->
|
||||
TLSOpts = lists:filter(fun({certfile, _}) -> true;
|
||||
(_) -> false
|
||||
end, Opts),
|
||||
Socket1 =
|
||||
{SockMod1, Socket1, ReceiverPid} =
|
||||
if
|
||||
TLSEnabled ->
|
||||
ejabberd_socket:starttls(Socket, TLSOpts);
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
|
||||
RecPid = ejabberd_receiver:start(
|
||||
TLSSocket, tls, none, MaxStanzaSize),
|
||||
{tls, TLSSocket, RecPid};
|
||||
true ->
|
||||
Socket
|
||||
RecPid = ejabberd_receiver:start(
|
||||
Socket, SockMod, none, MaxStanzaSize),
|
||||
{SockMod, Socket, RecPid}
|
||||
end,
|
||||
{ok, wait_for_stream, #state{socket = Socket1,
|
||||
sockmod = SockMod1,
|
||||
receiver = ReceiverPid,
|
||||
zlib = Zlib,
|
||||
tls = TLS,
|
||||
tls_required = StartTLSRequired,
|
||||
@@ -198,8 +211,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
{xmlelement, "mechanism", [],
|
||||
[{xmlcdata, S}]}
|
||||
end, cyrsasl:listmech(Server)),
|
||||
SockMod = ejabberd_socket:get_sockmod(
|
||||
StateData#state.socket),
|
||||
SockMod = StateData#state.sockmod,
|
||||
Zlib = StateData#state.zlib,
|
||||
CompressFeature =
|
||||
case Zlib andalso
|
||||
@@ -453,7 +465,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
TLSRequired = StateData#state.tls_required,
|
||||
SockMod = ejabberd_socket:get_sockmod(StateData#state.socket),
|
||||
SockMod = StateData#state.sockmod,
|
||||
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),
|
||||
@@ -462,7 +474,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
Mech,
|
||||
ClientIn) of
|
||||
{ok, Props} ->
|
||||
ejabberd_socket:reset_stream(StateData#state.socket),
|
||||
ejabberd_receiver:reset_stream(StateData#state.receiver),
|
||||
send_element(StateData,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
@@ -492,6 +504,7 @@ 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 ->
|
||||
@@ -501,12 +514,13 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
lists:keydelete(
|
||||
certfile, 1, StateData#state.tls_options)]
|
||||
end,
|
||||
Socket = StateData#state.socket,
|
||||
TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
|
||||
ejabberd_receiver:starttls(StateData#state.receiver, TLSSocket),
|
||||
send_element(StateData,
|
||||
{xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{socket = TLSSocket,
|
||||
StateData#state{sockmod = tls,
|
||||
socket = TLSSocket,
|
||||
streamid = new_id(),
|
||||
tls_enabled = true
|
||||
}};
|
||||
@@ -523,12 +537,16 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
case xml:get_tag_cdata(Method) of
|
||||
"zlib" ->
|
||||
Socket = StateData#state.socket,
|
||||
ZlibSocket = ejabberd_socket:compress(Socket),
|
||||
{ok, ZlibSocket} = ejabberd_zlib:enable_zlib(SockMod,
|
||||
Socket),
|
||||
ejabberd_receiver:compress(StateData#state.receiver,
|
||||
ZlibSocket),
|
||||
send_element(StateData,
|
||||
{xmlelement, "compressed",
|
||||
[{"xmlns", ?NS_COMPRESS}], []}),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{socket = ZlibSocket,
|
||||
StateData#state{sockmod = ejabberd_zlib,
|
||||
socket = ZlibSocket,
|
||||
streamid = new_id()
|
||||
}};
|
||||
_ ->
|
||||
@@ -575,7 +593,7 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
||||
case cyrsasl:server_step(StateData#state.sasl_state,
|
||||
ClientIn) of
|
||||
{ok, Props} ->
|
||||
ejabberd_socket:reset_stream(StateData#state.socket),
|
||||
ejabberd_receiver:reset_stream(StateData#state.receiver),
|
||||
send_element(StateData,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
@@ -841,6 +859,12 @@ 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}.
|
||||
|
||||
@@ -1167,7 +1191,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ok.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -1177,11 +1201,11 @@ terminate(_Reason, StateName, StateData) ->
|
||||
change_shaper(StateData, JID) ->
|
||||
Shaper = acl:match_rule(StateData#state.server,
|
||||
StateData#state.shaper, JID),
|
||||
ejabberd_socket:change_shaper(StateData#state.socket, Shaper).
|
||||
ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
|
||||
|
||||
send_text(StateData, Text) ->
|
||||
?DEBUG("Send XML on stream = ~p", [lists:flatten(Text)]),
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
catch (StateData#state.sockmod):send(StateData#state.socket, Text).
|
||||
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_string(El)).
|
||||
|
||||
@@ -92,13 +92,14 @@ accept(ListenSocket, Module, Opts) ->
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
case Module of
|
||||
ejabberd_http ->
|
||||
{ok, Pid} = Module:start({gen_tcp, Socket}, Opts),
|
||||
catch gen_tcp:controlling_process(Socket, Pid);
|
||||
_ ->
|
||||
ejabberd_socket:start(Module, gen_tcp, Socket, Opts)
|
||||
{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),
|
||||
accept(ListenSocket, Module, Opts);
|
||||
{error, Reason} ->
|
||||
?INFO_MSG("(~w) Failed TCP accept: ~w",
|
||||
|
||||
+14
-14
@@ -13,14 +13,14 @@
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% API
|
||||
-export([start_link/4,
|
||||
-export([start_link/5,
|
||||
start/3,
|
||||
start/4,
|
||||
change_shaper/2,
|
||||
reset_stream/1,
|
||||
starttls/2,
|
||||
compress/2,
|
||||
become_controller/2,
|
||||
become_controller/1,
|
||||
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) ->
|
||||
start_link(Socket, SockMod, Shaper, MaxStanzaSize, C2SPid) ->
|
||||
gen_server:start_link(
|
||||
?MODULE, [Socket, SockMod, Shaper, MaxStanzaSize], []).
|
||||
?MODULE, [Socket, SockMod, Shaper, MaxStanzaSize, C2SPid], []).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% 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]),
|
||||
[Socket, SockMod, Shaper, MaxStanzaSize, self()]),
|
||||
Pid.
|
||||
|
||||
change_shaper(Pid, Shaper) ->
|
||||
@@ -73,8 +73,8 @@ starttls(Pid, TLSSocket) ->
|
||||
compress(Pid, ZlibSocket) ->
|
||||
gen_server:call(Pid, {compress, ZlibSocket}).
|
||||
|
||||
become_controller(Pid, C2SPid) ->
|
||||
gen_server:call(Pid, {become_controller, C2SPid}).
|
||||
become_controller(Pid) ->
|
||||
gen_server:call(Pid, become_controller).
|
||||
|
||||
close(Pid) ->
|
||||
gen_server:cast(Pid, close).
|
||||
@@ -90,7 +90,8 @@ close(Pid) ->
|
||||
%% {stop, Reason}
|
||||
%% Description: Initiates the server
|
||||
%%--------------------------------------------------------------------
|
||||
init([Socket, SockMod, Shaper, MaxStanzaSize]) ->
|
||||
init([Socket, SockMod, Shaper, MaxStanzaSize, C2SPid]) ->
|
||||
XMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
|
||||
ShaperState = shaper:new(Shaper),
|
||||
Timeout = case SockMod of
|
||||
ssl ->
|
||||
@@ -101,7 +102,9 @@ init([Socket, SockMod, Shaper, MaxStanzaSize]) ->
|
||||
{ok, #state{socket = Socket,
|
||||
sock_mod = SockMod,
|
||||
shaper_state = ShaperState,
|
||||
c2s_pid = C2SPid,
|
||||
max_stanza_size = MaxStanzaSize,
|
||||
xml_stream_state = XMLStreamState,
|
||||
timeout = Timeout}}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
@@ -151,13 +154,10 @@ 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, 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),
|
||||
handle_call(become_controller, _From, State) ->
|
||||
activate_socket(State),
|
||||
Reply = ok,
|
||||
{reply, Reply, NewState};
|
||||
{reply, Reply, State};
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
||||
+37
-20
@@ -14,8 +14,8 @@
|
||||
%% External exports
|
||||
-export([start/2,
|
||||
start_link/2,
|
||||
match_domain/2,
|
||||
socket_type/0]).
|
||||
become_controller/1,
|
||||
match_domain/2]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1,
|
||||
@@ -37,6 +37,8 @@
|
||||
-define(DICT, dict).
|
||||
|
||||
-record(state, {socket,
|
||||
sockmod,
|
||||
receiver,
|
||||
streamid,
|
||||
shaper,
|
||||
tls = false,
|
||||
@@ -85,8 +87,8 @@ start(SockData, Opts) ->
|
||||
start_link(SockData, Opts) ->
|
||||
gen_fsm:start_link(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS).
|
||||
|
||||
socket_type() ->
|
||||
xml_stream.
|
||||
become_controller(Pid) ->
|
||||
gen_fsm:send_all_state_event(Pid, become_controller).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Callback functions from gen_fsm
|
||||
@@ -99,12 +101,19 @@ socket_type() ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([Socket, Opts]) ->
|
||||
?INFO_MSG("started: ~p", [Socket]),
|
||||
init([{SockMod, Socket}, Opts]) ->
|
||||
?INFO_MSG("started: ~p", [{SockMod, 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;
|
||||
@@ -120,6 +129,8 @@ init([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,
|
||||
@@ -144,10 +155,9 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
SASL =
|
||||
if
|
||||
StateData#state.tls_enabled ->
|
||||
case ejabberd_socket:get_peer_certificate(
|
||||
StateData#state.socket) of
|
||||
case tls:get_peer_certificate(StateData#state.socket) of
|
||||
{ok, _Cert} ->
|
||||
case ejabberd_socket:get_verify_result(
|
||||
case tls:get_verify_result(
|
||||
StateData#state.socket) of
|
||||
0 ->
|
||||
[{xmlelement, "mechanisms",
|
||||
@@ -204,7 +214,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
{xmlelement, Name, Attrs, Els} = El,
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
SockMod = ejabberd_socket:get_sockmod(StateData#state.socket),
|
||||
SockMod = StateData#state.sockmod,
|
||||
case {xml:get_attr_s("xmlns", Attrs), Name} of
|
||||
{?NS_TLS, "starttls"} when TLS == true,
|
||||
TLSEnabled == false,
|
||||
@@ -212,11 +222,13 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
?INFO_MSG("starttls", []),
|
||||
Socket = StateData#state.socket,
|
||||
TLSOpts = StateData#state.tls_options,
|
||||
TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
|
||||
ejabberd_receiver:starttls(StateData#state.receiver, TLSSocket),
|
||||
send_element(StateData,
|
||||
{xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{socket = TLSSocket,
|
||||
StateData#state{sockmod = tls,
|
||||
socket = TLSSocket,
|
||||
streamid = new_id(),
|
||||
tls_enabled = true
|
||||
}};
|
||||
@@ -227,10 +239,9 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
Auth = jlib:decode_base64(xml:get_cdata(Els)),
|
||||
AuthDomain = jlib:nameprep(Auth),
|
||||
AuthRes =
|
||||
case ejabberd_socket:get_peer_certificate(
|
||||
StateData#state.socket) of
|
||||
case tls:get_peer_certificate(StateData#state.socket) of
|
||||
{ok, Cert} ->
|
||||
case ejabberd_socket:get_verify_result(
|
||||
case tls:get_verify_result(
|
||||
StateData#state.socket) of
|
||||
0 ->
|
||||
case AuthDomain of
|
||||
@@ -256,8 +267,8 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
end,
|
||||
if
|
||||
AuthRes ->
|
||||
ejabberd_socket:reset_stream(
|
||||
StateData#state.socket),
|
||||
ejabberd_receiver:reset_stream(
|
||||
StateData#state.receiver),
|
||||
send_element(StateData,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
@@ -456,6 +467,12 @@ 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}.
|
||||
|
||||
@@ -500,7 +517,7 @@ handle_info(_, StateName, StateData) ->
|
||||
%%----------------------------------------------------------------------
|
||||
terminate(Reason, _StateName, StateData) ->
|
||||
?INFO_MSG("terminated: ~p", [Reason]),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ok.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -508,7 +525,7 @@ terminate(Reason, _StateName, StateData) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
send_text(StateData, Text) ->
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
(StateData#state.sockmod):send(StateData#state.socket, Text).
|
||||
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_string(El)).
|
||||
@@ -516,7 +533,7 @@ send_element(StateData, El) ->
|
||||
|
||||
change_shaper(StateData, Host, JID) ->
|
||||
Shaper = acl:match_rule(Host, StateData#state.shaper, JID),
|
||||
ejabberd_socket:change_shaper(StateData#state.socket, Shaper).
|
||||
ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
|
||||
|
||||
|
||||
new_id() ->
|
||||
|
||||
+28
-21
@@ -36,7 +36,8 @@
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(state, {socket,
|
||||
-record(state, {socket, receiver,
|
||||
sockmod,
|
||||
streamid,
|
||||
use_v10,
|
||||
tls = false,
|
||||
@@ -151,6 +152,9 @@ 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'";
|
||||
@@ -158,7 +162,9 @@ 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,
|
||||
@@ -178,23 +184,20 @@ open_socket1(Addr, Port) ->
|
||||
false -> {error, badarg};
|
||||
ASCIIAddr ->
|
||||
?DEBUG("s2s_out: connecting to ~s:~p~n", [ASCIIAddr, Port]),
|
||||
case catch ejabberd_socket:connect(
|
||||
ASCIIAddr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}]) of
|
||||
case catch gen_tcp:connect(ASCIIAddr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}]) of
|
||||
{ok, _Socket} = R -> R;
|
||||
{error, Reason1} ->
|
||||
?DEBUG("s2s_out: connect return ~p~n", [Reason1]),
|
||||
catch ejabberd_socket:connect(
|
||||
Addr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}, inet6]);
|
||||
catch gen_tcp:connect(Addr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}, inet6]);
|
||||
{'EXIT', Reason1} ->
|
||||
?DEBUG("s2s_out: connect crashed ~p~n", [Reason1]),
|
||||
catch ejabberd_socket:connect(
|
||||
Addr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}, inet6])
|
||||
catch gen_tcp:connect(Addr, Port,
|
||||
[binary, {packet, 0},
|
||||
{active, false}, inet6])
|
||||
end
|
||||
end,
|
||||
case Res of
|
||||
@@ -360,7 +363,7 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
|
||||
StartTLSRequired and (not StateData#state.tls) ->
|
||||
?INFO_MSG("restarted: ~p", [{StateData#state.myname,
|
||||
StateData#state.server}]),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
{next_state, reopen_socket,
|
||||
StateData#state{socket = undefined,
|
||||
use_v10 = false}};
|
||||
@@ -370,7 +373,7 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
|
||||
?INFO_MSG("restarted: ~p", [{StateData#state.myname,
|
||||
StateData#state.server}]),
|
||||
% TODO: clear message queue
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
{next_state, reopen_socket, StateData#state{socket = undefined,
|
||||
use_v10 = false}}
|
||||
end;
|
||||
@@ -403,7 +406,8 @@ wait_for_auth_result({xmlstreamelement, El}, StateData) ->
|
||||
?NS_SASL ->
|
||||
?INFO_MSG("auth: ~p", [{StateData#state.myname,
|
||||
StateData#state.server}]),
|
||||
ejabberd_socket:reset_stream(StateData#state.socket),
|
||||
ejabberd_receiver:reset_stream(
|
||||
StateData#state.receiver),
|
||||
send_text(StateData,
|
||||
io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.server,
|
||||
@@ -423,7 +427,7 @@ wait_for_auth_result({xmlstreamelement, El}, StateData) ->
|
||||
?NS_SASL ->
|
||||
?INFO_MSG("restarted: ~p", [{StateData#state.myname,
|
||||
StateData#state.server}]),
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
{next_state, reopen_socket,
|
||||
StateData#state{socket = undefined}};
|
||||
_ ->
|
||||
@@ -473,8 +477,11 @@ wait_for_starttls_proceed({xmlstreamelement, El}, StateData) ->
|
||||
certfile, 1,
|
||||
StateData#state.tls_options)]
|
||||
end,
|
||||
TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
|
||||
NewStateData = StateData#state{socket = TLSSocket,
|
||||
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
|
||||
ejabberd_receiver:starttls(
|
||||
StateData#state.receiver, TLSSocket),
|
||||
NewStateData = StateData#state{sockmod = tls,
|
||||
socket = TLSSocket,
|
||||
streamid = new_id(),
|
||||
tls_enabled = true
|
||||
},
|
||||
@@ -665,7 +672,7 @@ terminate(Reason, StateName, StateData) ->
|
||||
undefined ->
|
||||
ok;
|
||||
_Socket ->
|
||||
ejabberd_socket:close(StateData#state.socket)
|
||||
ejabberd_receiver:close(StateData#state.receiver)
|
||||
end,
|
||||
ok.
|
||||
|
||||
@@ -674,7 +681,7 @@ terminate(Reason, StateName, StateData) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
send_text(StateData, Text) ->
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
(StateData#state.sockmod):send(StateData#state.socket, Text).
|
||||
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_string(El)).
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
start_link/2,
|
||||
send_text/2,
|
||||
send_element/2,
|
||||
socket_type/0]).
|
||||
become_controller/1]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1,
|
||||
@@ -33,7 +33,7 @@
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(state, {socket, streamid,
|
||||
-record(state, {socket, receiver, streamid, sockmod,
|
||||
hosts, password, access}).
|
||||
|
||||
%-define(DBGFSM, true).
|
||||
@@ -79,8 +79,8 @@ start(SockData, Opts) ->
|
||||
start_link(SockData, Opts) ->
|
||||
gen_fsm:start_link(ejabberd_service, [SockData, Opts], ?FSMOPTS).
|
||||
|
||||
socket_type() ->
|
||||
xml_stream.
|
||||
become_controller(Pid) ->
|
||||
gen_fsm:send_all_state_event(Pid, become_controller).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Callback functions from gen_fsm
|
||||
@@ -93,7 +93,7 @@ socket_type() ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([Socket, Opts]) ->
|
||||
init([{SockMod, Socket}, Opts]) ->
|
||||
Access = case lists:keysearch(access, 1, Opts) of
|
||||
{value, {_, A}} -> A;
|
||||
_ -> all
|
||||
@@ -123,8 +123,11 @@ init([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
|
||||
@@ -256,6 +259,12 @@ 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}.
|
||||
|
||||
@@ -319,7 +328,7 @@ terminate(Reason, StateName, StateData) ->
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
ejabberd_socket:close(StateData#state.socket),
|
||||
ejabberd_receiver:close(StateData#state.receiver),
|
||||
ok.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -327,11 +336,12 @@ terminate(Reason, StateName, StateData) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
send_text(StateData, Text) ->
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
(StateData#state.sockmod):send(StateData#state.socket,Text).
|
||||
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_string(El)).
|
||||
|
||||
|
||||
new_id() ->
|
||||
randoms:get_string().
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% 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,
|
||||
get_peer_certificate/1,
|
||||
get_verify_result/1,
|
||||
close/1]).
|
||||
|
||||
-record(socket_state, {sockmod, socket, receiver}).
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function:
|
||||
%% Description:
|
||||
%%--------------------------------------------------------------------
|
||||
start(Module, SockMod, Socket, Opts) ->
|
||||
case Module:socket_type() of
|
||||
xml_stream ->
|
||||
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);
|
||||
raw ->
|
||||
{ok, Pid} = Module:start({SockMod, Socket}, Opts),
|
||||
case SockMod:controlling_process(Socket, Pid) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, _Reason} ->
|
||||
SockMod:close(Socket)
|
||||
end,
|
||||
ejabberd_receiver:become_controller(Pid)
|
||||
end.
|
||||
|
||||
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.
|
||||
|
||||
get_peer_certificate(SocketData) ->
|
||||
tls:get_peer_certificate(SocketData#socket_state.socket).
|
||||
|
||||
get_verify_result(SocketData) ->
|
||||
tls:get_verify_result(SocketData#socket_state.socket).
|
||||
|
||||
close(SocketData) ->
|
||||
ejabberd_receiver:close(SocketData#socket_state.receiver).
|
||||
|
||||
%%====================================================================
|
||||
%% Internal functions
|
||||
%%====================================================================
|
||||
@@ -14,7 +14,6 @@
|
||||
-export([start/2,
|
||||
start_link/2,
|
||||
become_controller/1,
|
||||
socket_type/0,
|
||||
receive_headers/1,
|
||||
url_encode/1]).
|
||||
|
||||
@@ -86,9 +85,6 @@ start_link({SockMod, Socket}, Opts) ->
|
||||
become_controller(_Pid) ->
|
||||
ok.
|
||||
|
||||
socket_type() ->
|
||||
raw.
|
||||
|
||||
send_text(State, Text) ->
|
||||
(State#state.sockmod):send(State#state.socket, Text).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user