diff --git a/src/ejabberd_bosh.erl b/src/ejabberd_bosh.erl index 3580cfab4..c8dde4b0f 100644 --- a/src/ejabberd_bosh.erl +++ b/src/ejabberd_bosh.erl @@ -284,7 +284,7 @@ init([#body{attrs = Attrs}, IP, SID]) -> buf_new(XMPPDomain)), Opts2} end, - case ejabberd_c2s:start({?MODULE, Socket}, [{receiver, self()}|Opts]) of + case ejabberd_c2s:start(?MODULE, Socket, [{receiver, self()}|Opts]) of {ok, C2SPid} -> ejabberd_c2s:accept(C2SPid), Inactivity = gen_mod:get_module_opt(XMPPDomain, diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 9ccd10099..25e6ee4d7 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -27,7 +27,7 @@ -protocol({rfc, 6121}). %% ejabberd_listener callbacks --export([start/2, start_link/2, accept/1, listen_opt_type/1, listen_options/0]). +-export([start/3, start_link/3, accept/1, listen_opt_type/1, listen_options/0]). %% ejabberd_config callbacks -export([opt_type/1, transform_listen_option/2]). %% xmpp_stream_in callbacks @@ -63,12 +63,12 @@ %%%=================================================================== %%% ejabberd_listener API %%%=================================================================== -start(SockData, Opts) -> - xmpp_stream_in:start(?MODULE, [SockData, Opts], +start(SockMod, Socket, Opts) -> + xmpp_stream_in:start(?MODULE, [{SockMod, Socket}, Opts], ejabberd_config:fsm_limit_opts(Opts)). -start_link(SockData, Opts) -> - xmpp_stream_in:start_link(?MODULE, [SockData, Opts], +start_link(SockMod, Socket, Opts) -> + xmpp_stream_in:start_link(?MODULE, [{SockMod, Socket}, Opts], ejabberd_config:fsm_limit_opts(Opts)). accept(Ref) -> diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl index c226dba1c..9588e6cd1 100644 --- a/src/ejabberd_http.erl +++ b/src/ejabberd_http.erl @@ -30,12 +30,12 @@ -author('alexey@process-one.net'). %% External exports --export([start/2, start_link/2, +-export([start/3, start_link/3, accept/1, receive_headers/1, recv_file/2, transform_listen_option/2, listen_opt_type/1, listen_options/0]). --export([init/2, opt_type/1]). +-export([init/3, opt_type/1]). -include("logger.hrl"). -include("xmpp.hrl"). @@ -89,17 +89,17 @@ -define(SEND_BUF, 65536). -define(MAX_POST_SIZE, 20971520). %% 20Mb -start(SockData, Opts) -> +start(SockMod, Socket, Opts) -> {ok, proc_lib:spawn(ejabberd_http, init, - [SockData, Opts])}. + [SockMod, Socket, Opts])}. -start_link(SockData, Opts) -> +start_link(SockMod, Socket, Opts) -> {ok, proc_lib:spawn_link(ejabberd_http, init, - [SockData, Opts])}. + [SockMod, Socket, Opts])}. -init({SockMod, Socket}, Opts) -> +init(SockMod, Socket, Opts) -> TLSEnabled = proplists:get_bool(tls, Opts), TLSOpts1 = lists:filter(fun ({ciphers, _}) -> true; ({dhfile, _}) -> true; diff --git a/src/ejabberd_http_ws.erl b/src/ejabberd_http_ws.erl index 675c7114e..0d0cdcb52 100644 --- a/src/ejabberd_http_ws.erl +++ b/src/ejabberd_http_ws.erl @@ -143,7 +143,7 @@ init([{#ws{ip = IP, http_opts = HOpts}, _} = WS]) -> Socket = {http_ws, self(), IP}, ?DEBUG("Client connected through websocket ~p", [Socket]), - case ejabberd_c2s:start({?MODULE, Socket}, [{receiver, self()}|Opts]) of + case ejabberd_c2s:start(?MODULE, Socket, [{receiver, self()}|Opts]) of {ok, C2SPid} -> ejabberd_c2s:accept(C2SPid), Timer = erlang:start_timer(WSTimeout, self(), []), diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl index c32f5be86..7413ee048 100644 --- a/src/ejabberd_listener.erl +++ b/src/ejabberd_listener.erl @@ -43,10 +43,12 @@ -type endpoint() :: {inet:port_number(), inet:ip_address(), transport()}. -type listen_opts() :: [proplists:property()]. -type listener() :: {endpoint(), module(), listen_opts()}. +-type sockmod() :: gen_tcp. +-type socket() :: inet:socket(). --callback start({gen_tcp, inet:socket()}, listen_opts()) -> +-callback start(sockmod(), socket(), listen_opts()) -> {ok, pid()} | {error, any()} | ignore. --callback start_link({gen_tcp, inet:socket()}, listen_opts()) -> +-callback start_link(sockmod(), socket(), listen_opts()) -> {ok, pid()} | {error, any()} | ignore. -callback accept(pid()) -> any(). -callback listen_opt_type(atom()) -> fun((term()) -> term()). @@ -197,10 +199,15 @@ split_opts(Opts) -> -spec accept(inet:socket(), module(), listen_opts(), atom()) -> no_return(). accept(ListenSocket, Module, Opts, Sup) -> Interval = proplists:get_value(accept_interval, Opts, 0), - accept(ListenSocket, Module, Opts, Sup, Interval). + Arity = case erlang:function_exported(Module, start, 3) of + true -> 3; + false -> 2 + end, + accept(ListenSocket, Module, Opts, Sup, Interval, Arity). --spec accept(inet:socket(), module(), listen_opts(), atom(), non_neg_integer()) -> no_return(). -accept(ListenSocket, Module, Opts, Sup, Interval) -> +-spec accept(inet:socket(), module(), listen_opts(), atom(), + non_neg_integer(), 2|3) -> no_return(). +accept(ListenSocket, Module, Opts, Sup, Interval, Arity) -> NewInterval = check_rate_limit(Interval), case gen_tcp:accept(ListenSocket) of {ok, Socket} -> @@ -213,7 +220,7 @@ accept(ListenSocket, Module, Opts, Sup, Interval) -> gen_tcp:close(Socket); {{Addr, Port}, {PAddr, PPort}} = SP -> Opts2 = [{sock_peer_name, SP} | Opts], - Receiver = case start_connection(Module, Socket, Opts2, Sup) of + Receiver = case start_connection(Module, Arity, Socket, Opts2, Sup) of {ok, RecvPid} -> RecvPid; _ -> @@ -228,7 +235,7 @@ accept(ListenSocket, Module, Opts, Sup, Interval) -> _ -> case {inet:sockname(Socket), inet:peername(Socket)} of {{ok, {Addr, Port}}, {ok, {PAddr, PPort}}} -> - Receiver = case start_connection(Module, Socket, Opts, Sup) of + Receiver = case start_connection(Module, Arity, Socket, Opts, Sup) of {ok, RecvPid} -> RecvPid; _ -> @@ -243,11 +250,11 @@ accept(ListenSocket, Module, Opts, Sup, Interval) -> gen_tcp:close(Socket) end end, - accept(ListenSocket, Module, Opts, Sup, NewInterval); + accept(ListenSocket, Module, Opts, Sup, NewInterval, Arity); {error, Reason} -> ?ERROR_MSG("(~w) Failed TCP accept: ~s", [ListenSocket, inet:format_error(Reason)]), - accept(ListenSocket, Module, Opts, Sup, NewInterval) + accept(ListenSocket, Module, Opts, Sup, NewInterval, Arity) end. -spec udp_recv(inet:socket(), module(), listen_opts()) -> no_return(). @@ -269,11 +276,15 @@ udp_recv(Socket, Module, Opts) -> throw({error, Reason}) end. --spec start_connection(module(), inet:socket(), listen_opts(), atom()) -> +-spec start_connection(module(), 2|3, inet:socket(), listen_opts(), atom()) -> {ok, pid()} | {error, any()} | ignore. -start_connection(Module, Socket, Opts, Sup) -> +start_connection(Module, Arity, Socket, Opts, Sup) -> Res = case Sup of - undefined -> Module:start({gen_tcp, Socket}, Opts); + undefined -> + case Arity of + 3 -> Module:start(gen_tcp, Socket, Opts); + 2 -> Module:start({gen_tcp, Socket}, Opts) + end; _ -> supervisor:start_child(Sup, [{gen_tcp, Socket}, Opts]) end, case Res of @@ -517,8 +528,11 @@ validate_module(Mod) -> case code:ensure_loaded(Mod) of {module, Mod} -> lists:foreach( - fun({Fun, Arity}) -> - case erlang:function_exported(Mod, Fun, Arity) of + fun({Fun, Arities}) -> + case lists:any( + fun(Arity) -> + erlang:function_exported(Mod, Fun, Arity) + end, Arities) of true -> ok; false -> ?ERROR_MSG("Failed to load listening module ~s, " @@ -526,11 +540,11 @@ validate_module(Mod) -> "The module is either not a listening module " "or it is a third-party module which " "requires update", - [Mod, Fun, Arity]), + [Mod, Fun, hd(Arities)]), erlang:error(badarg) end - end, [{start, 2}, {start_link, 2}, - {accept, 1}, {listen_options, 0}]); + end, [{start, [3,2]}, {start_link, [3,2]}, + {accept, [1]}, {listen_options, [0]}]); _ -> ?ERROR_MSG("Failed to load unknown listening module ~s: " "make sure there is no typo and ~s.beam " diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index db7655ef8..be2f85370 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -24,7 +24,7 @@ -behaviour(ejabberd_listener). %% ejabberd_listener callbacks --export([start/2, start_link/2, accept/1, listen_opt_type/1, listen_options/0]). +-export([start/3, start_link/3, accept/1, listen_opt_type/1, listen_options/0]). %% xmpp_stream_in callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -50,12 +50,12 @@ %%%=================================================================== %%% API %%%=================================================================== -start(SockData, Opts) -> - xmpp_stream_in:start(?MODULE, [SockData, Opts], +start(SockMod, Socket, Opts) -> + xmpp_stream_in:start(?MODULE, [{SockMod, Socket}, Opts], ejabberd_config:fsm_limit_opts(Opts)). -start_link(SockData, Opts) -> - xmpp_stream_in:start_link(?MODULE, [SockData, Opts], +start_link(SockMod, Socket, Opts) -> + xmpp_stream_in:start_link(?MODULE, [{SockMod, Socket}, Opts], ejabberd_config:fsm_limit_opts(Opts)). close(Ref) -> diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index c2fa2b8c0..d78a1e2ea 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -26,7 +26,7 @@ -protocol({xep, 114, '1.6'}). %% ejabberd_listener callbacks --export([start/2, start_link/2, accept/1]). +-export([start/3, start_link/3, accept/1]). -export([listen_opt_type/1, listen_options/0, transform_listen_option/2]). %% xmpp_stream_in callbacks -export([init/1, handle_info/2, terminate/2, code_change/3]). @@ -44,12 +44,12 @@ %%%=================================================================== %%% API %%%=================================================================== -start(SockData, Opts) -> - xmpp_stream_in:start(?MODULE, [SockData, Opts], +start(SockMod, Socket, Opts) -> + xmpp_stream_in:start(?MODULE, [{SockMod, Socket}, Opts], ejabberd_config:fsm_limit_opts(Opts)). -start_link(SockData, Opts) -> - xmpp_stream_in:start_link(?MODULE, [SockData, Opts], +start_link(SockMod, Socket, Opts) -> + xmpp_stream_in:start_link(?MODULE, [{SockMod, Socket}, Opts], ejabberd_config:fsm_limit_opts(Opts)). accept(Ref) -> diff --git a/src/ejabberd_sip.erl b/src/ejabberd_sip.erl index 8f6aed55c..226cad3e8 100644 --- a/src/ejabberd_sip.erl +++ b/src/ejabberd_sip.erl @@ -1,7 +1,7 @@ %%%------------------------------------------------------------------- %%% File : ejabberd_sip.erl %%% Author : Evgeny Khramtsov -%%% Purpose : +%%% Purpose : %%% Created : 30 Apr 2017 by Evgeny Khramtsov %%% %%% @@ -28,7 +28,7 @@ -ifndef(SIP). -include("logger.hrl"). --export([accept/1, start/2, start_link/2, listen_options/0]). +-export([accept/1, start/3, start_link/3, listen_options/0]). fail() -> ?CRITICAL_MSG("Listening module ~s is not available: " "ejabberd is not compiled with SIP support", @@ -38,14 +38,14 @@ accept(_) -> fail(). listen_options() -> fail(). -start(_, _) -> +start(_, _, _) -> fail(). -start_link(_, _) -> +start_link(_, _, _) -> fail(). -else. %% API --export([tcp_init/2, udp_init/2, udp_recv/5, start/2, - start_link/2, accept/1, listen_options/0]). +-export([tcp_init/2, udp_init/2, udp_recv/5, start/3, + start_link/3, accept/1, listen_options/0]). %%%=================================================================== @@ -62,10 +62,10 @@ udp_init(Socket, Opts) -> udp_recv(Sock, Addr, Port, Data, Opts) -> esip_socket:udp_recv(Sock, Addr, Port, Data, Opts). -start(Opaque, Opts) -> - esip_socket:start(Opaque, Opts). +start(SockMod, Socket, Opts) -> + esip_socket:start({SockMod, Socket}, Opts). -start_link({gen_tcp, Sock}, Opts) -> +start_link(gen_tcp, Sock, Opts) -> esip_socket:start_link(Sock, Opts). accept(_) -> diff --git a/src/ejabberd_stun.erl b/src/ejabberd_stun.erl index 24f3e696b..159c576f4 100644 --- a/src/ejabberd_stun.erl +++ b/src/ejabberd_stun.erl @@ -30,7 +30,7 @@ -ifndef(STUN). -include("logger.hrl"). --export([accept/1, start/2, start_link/2, listen_options/0]). +-export([accept/1, start/3, start_link/3, listen_options/0]). fail() -> ?CRITICAL_MSG("Listening module ~s is not available: " "ejabberd is not compiled with STUN/TURN support", @@ -40,13 +40,13 @@ accept(_) -> fail(). listen_options() -> fail(). -start(_, _) -> +start(_, _, _) -> fail(). -start_link(_, _) -> +start_link(_, _, _) -> fail(). -else. --export([tcp_init/2, udp_init/2, udp_recv/5, start/2, - start_link/2, accept/1, listen_opt_type/1, listen_options/0]). +-export([tcp_init/2, udp_init/2, udp_recv/5, start/3, + start_link/3, accept/1, listen_opt_type/1, listen_options/0]). -include("logger.hrl"). @@ -64,11 +64,11 @@ udp_init(Socket, Opts) -> udp_recv(Socket, Addr, Port, Packet, Opts) -> stun:udp_recv(Socket, Addr, Port, Packet, Opts). -start(Opaque, Opts) -> - stun:start(Opaque, Opts). +start(SockMod, Socket, Opts) -> + stun:start({SockMod, Socket}, Opts). -start_link({gen_tcp, Sock}, Opts) -> - stun:start_link(Sock, Opts). +start_link(_SockMod, Socket, Opts) -> + stun:start_link(Socket, Opts). accept(_Pid) -> ok. diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl index cda2864df..067b26803 100644 --- a/src/ejabberd_xmlrpc.erl +++ b/src/ejabberd_xmlrpc.erl @@ -35,7 +35,7 @@ -author('badlop@process-one.net'). --export([start/2, start_link/2, handler/2, process/2, accept/1, +-export([start/3, start_link/3, handler/2, process/2, accept/1, transform_listen_option/2, listen_opt_type/1, listen_options/0]). -include("logger.hrl"). @@ -188,11 +188,11 @@ %% Listener interface %% ----------------------------- -start({gen_tcp = _SockMod, Socket}, Opts) -> - ejabberd_http:start({gen_tcp, Socket}, [{xmlrpc, true}|Opts]). +start(gen_tcp = _SockMod, Socket, Opts) -> + ejabberd_http:start(gen_tcp, Socket, [{xmlrpc, true}|Opts]). -start_link({gen_tcp = _SockMod, Socket}, Opts) -> - ejabberd_http:start_link({gen_tcp, Socket}, [{xmlrpc, true}|Opts]). +start_link(gen_tcp = _SockMod, Socket, Opts) -> + ejabberd_http:start_link(gen_tcp, Socket, [{xmlrpc, true}|Opts]). accept(Pid) -> ejabberd_http:accept(Pid). diff --git a/src/mod_mqtt.erl b/src/mod_mqtt.erl index 86aea87be..9fd1e57ac 100644 --- a/src/mod_mqtt.erl +++ b/src/mod_mqtt.erl @@ -26,7 +26,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% ejabberd_listener API --export([start_link/2, listen_opt_type/1, listen_options/0, accept/1]). +-export([start/3, start_link/3, listen_opt_type/1, listen_options/0, accept/1]). %% Legacy ejabberd_listener API -export([become_controller/2, socket_type/0]). %% API @@ -71,12 +71,13 @@ %%%=================================================================== %%% API %%%=================================================================== -start({SockMod, Sock}, ListenOpts) -> - mod_mqtt_session:start(SockMod, Sock, ListenOpts); +start(SockMod, Sock, ListenOpts) -> + mod_mqtt_session:start(SockMod, Sock, ListenOpts). + start(Host, Opts) -> gen_mod:start_child(?MODULE, Host, Opts). -start_link({SockMod, Sock}, ListenOpts) -> +start_link(SockMod, Sock, ListenOpts) -> mod_mqtt_session:start_link(SockMod, Sock, ListenOpts). stop(Host) -> diff --git a/src/mod_proxy65_stream.erl b/src/mod_proxy65_stream.erl index 7e5c180ae..02d2643ee 100644 --- a/src/mod_proxy65_stream.erl +++ b/src/mod_proxy65_stream.erl @@ -38,7 +38,7 @@ wait_for_request/2, wait_for_activation/2, stream_established/2]). --export([start/2, stop/1, start_link/2, start_link/3, activate/2, +-export([start/3, stop/1, start_link/3, activate/2, relay/3, accept/1, listen_opt_type/1, listen_options/0]). @@ -65,20 +65,19 @@ code_change(_OldVsn, StateName, StateData, _Extra) -> %%------------------------------- -start({gen_tcp, Socket}, Opts1) -> +start(gen_tcp, Socket, Opts1) -> {[{server_host, Host}], Opts} = lists:partition( fun({server_host, _}) -> true; (_) -> false end, Opts1), p1_fsm:start(?MODULE, [Socket, Host, Opts], []). -start_link({gen_tcp, Socket}, Opts1) -> +start_link(gen_tcp, Socket, Opts1) -> {[{server_host, Host}], Opts} = lists:partition( fun({server_host, _}) -> true; (_) -> false end, Opts1), - start_link(Socket, Host, Opts). - + start_link(Socket, Host, Opts); start_link(Socket, Host, Opts) -> p1_fsm:start_link(?MODULE, [Socket, Host, Opts], []).