diff options
-rw-r--r-- | ChangeLog | 50 | ||||
-rw-r--r-- | doc/guide.html | 136 | ||||
-rw-r--r-- | doc/guide.tex | 2 | ||||
-rw-r--r-- | doc/release_note_1.1.2.txt | 0 | ||||
-rw-r--r-- | src/ejabberd_c2s.erl | 66 | ||||
-rw-r--r-- | src/ejabberd_listener.erl | 13 | ||||
-rw-r--r-- | src/ejabberd_receiver.erl | 28 | ||||
-rw-r--r-- | src/ejabberd_s2s_in.erl | 57 | ||||
-rw-r--r-- | src/ejabberd_s2s_out.erl | 49 | ||||
-rw-r--r-- | src/ejabberd_service.erl | 24 | ||||
-rw-r--r-- | src/ejabberd_socket.erl | 121 | ||||
-rw-r--r-- | src/web/ejabberd_http.erl | 4 |
12 files changed, 296 insertions, 254 deletions
@@ -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 diff --git a/doc/guide.html b/doc/guide.html index 489f76c02..fd3f0a75a 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -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--> @@ -3987,9 +3988,136 @@ References 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) + + +- Anonymous login bugfixes. + +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 + + - 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 +4134,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> diff --git a/doc/guide.tex b/doc/guide.tex index d7262c218..174dc95a6 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -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} diff --git a/doc/release_note_1.1.2.txt b/doc/release_note_1.1.2.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/doc/release_note_1.1.2.txt diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index a9e0d01ef..84c855c30 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -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)). diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl index 8bc168421..d387de7d4 100644 --- a/src/ejabberd_listener.erl +++ b/src/ejabberd_listener.erl @@ -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", diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl index dfa03fd4e..9591bd9c0 100644 --- a/src/ejabberd_receiver.erl +++ b/src/ejabberd_receiver.erl @@ -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}. diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 64a85fc1c..725421d1d 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -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() -> diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 80fa78baf..358abf5a3 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -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)). diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 925915aa9..551ff436e 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -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(). diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl deleted file mode 100644 index 9b0218803..000000000 --- a/src/ejabberd_socket.erl +++ /dev/null @@ -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 -%%==================================================================== diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl index 3220925ec..5113f1afe 100644 --- a/src/web/ejabberd_http.erl +++ b/src/web/ejabberd_http.erl @@ -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). |