2002-11-18 21:39:47 +01:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% File : ejabberd_listener.erl
|
|
|
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
|
|
|
%%% Purpose :
|
|
|
|
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
|
|
|
|
%%% Id : $Id$
|
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
|
|
|
-module(ejabberd_listener).
|
|
|
|
-author('alexey@sevcom.net').
|
|
|
|
-vsn('$Revision$ ').
|
|
|
|
|
2003-07-14 20:06:03 +02:00
|
|
|
-export([start_link/0, init/1, start/3,
|
|
|
|
init/3,
|
|
|
|
init_ssl/4
|
2003-02-06 20:09:22 +01:00
|
|
|
]).
|
2002-11-18 21:39:47 +01:00
|
|
|
|
2003-10-09 20:09:05 +02:00
|
|
|
-include("ejabberd.hrl").
|
|
|
|
|
2003-02-01 21:21:28 +01:00
|
|
|
start_link() ->
|
2003-01-07 20:10:35 +01:00
|
|
|
supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []).
|
2002-11-18 21:39:47 +01:00
|
|
|
|
2003-01-07 20:10:35 +01:00
|
|
|
|
|
|
|
init(_) ->
|
2003-01-21 21:36:55 +01:00
|
|
|
case ejabberd_config:get_local_option(listen) of
|
2003-01-07 20:10:35 +01:00
|
|
|
undefined ->
|
|
|
|
ignore;
|
|
|
|
Ls ->
|
|
|
|
{ok, {{one_for_one, 10, 1},
|
|
|
|
lists:map(
|
2003-07-14 20:06:03 +02:00
|
|
|
fun({Port, Module, Opts}) ->
|
2003-01-07 20:10:35 +01:00
|
|
|
{Port,
|
2003-07-14 20:06:03 +02:00
|
|
|
{?MODULE, start, [Port, Module, Opts]},
|
2003-01-07 20:10:35 +01:00
|
|
|
permanent,
|
|
|
|
brutal_kill,
|
|
|
|
worker,
|
2003-07-20 22:35:35 +02:00
|
|
|
[?MODULE]}
|
2003-01-07 20:10:35 +01:00
|
|
|
end, Ls)}}
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
2003-07-14 20:06:03 +02:00
|
|
|
start(Port, Module, Opts) ->
|
2003-02-06 20:09:22 +01:00
|
|
|
case lists:keysearch(ssl, 1, Opts) of
|
|
|
|
{value, {ssl, SSLOpts}} ->
|
2003-07-14 20:06:03 +02:00
|
|
|
{ok, proc_lib:spawn_link(?MODULE, init_ssl,
|
|
|
|
[Port, Module, Opts, SSLOpts])};
|
2003-02-06 20:09:22 +01:00
|
|
|
_ ->
|
2003-07-14 20:06:03 +02:00
|
|
|
{ok, proc_lib:spawn_link(?MODULE, init, [Port, Module, Opts])}
|
2003-02-06 20:09:22 +01:00
|
|
|
end.
|
2003-01-07 20:10:35 +01:00
|
|
|
|
2003-07-14 20:06:03 +02:00
|
|
|
init(Port, Module, Opts) ->
|
2002-12-06 21:59:19 +01:00
|
|
|
{ok, ListenSocket} = gen_tcp:listen(Port, [binary,
|
2002-11-18 21:39:47 +01:00
|
|
|
{packet, 0},
|
|
|
|
{active, false},
|
2003-10-11 19:39:36 +02:00
|
|
|
{reuseaddr, true},
|
|
|
|
{nodelay, true}]),
|
2003-07-14 20:06:03 +02:00
|
|
|
accept(ListenSocket, Module, Opts).
|
2002-11-18 21:39:47 +01:00
|
|
|
|
2003-07-14 20:06:03 +02:00
|
|
|
accept(ListenSocket, Module, Opts) ->
|
2002-11-18 21:39:47 +01:00
|
|
|
case gen_tcp:accept(ListenSocket) of
|
2003-03-12 20:48:05 +01:00
|
|
|
{ok, Socket} ->
|
2003-10-09 20:09:05 +02:00
|
|
|
case {inet:sockname(Socket), inet:peername(Socket)} of
|
|
|
|
{{ok, Addr}, {ok, PAddr}} ->
|
|
|
|
?INFO_MSG("(~w) Accepted connection ~w -> ~w",
|
|
|
|
[Socket, PAddr, Addr]);
|
|
|
|
_ ->
|
|
|
|
ok
|
|
|
|
end,
|
2003-07-20 22:35:35 +02:00
|
|
|
{ok, Pid} = Module:start({gen_tcp, Socket}, Opts),
|
2003-03-12 20:48:05 +01:00
|
|
|
gen_tcp:controlling_process(Socket, Pid),
|
2003-10-28 21:26:43 +01:00
|
|
|
accept(ListenSocket, Module, Opts);
|
|
|
|
{error, Reason} ->
|
|
|
|
?INFO_MSG("(~w) Failed TCP accept: ~w",
|
|
|
|
[ListenSocket, Reason]),
|
2003-07-14 20:06:03 +02:00
|
|
|
accept(ListenSocket, Module, Opts)
|
2003-02-06 20:09:22 +01:00
|
|
|
end.
|
|
|
|
|
|
|
|
|
2003-07-14 20:06:03 +02:00
|
|
|
init_ssl(Port, Module, Opts, SSLOpts) ->
|
2003-02-06 20:09:22 +01:00
|
|
|
{ok, ListenSocket} = ssl:listen(Port, [binary,
|
|
|
|
{packet, 0},
|
|
|
|
{active, false},
|
2003-08-30 21:19:23 +02:00
|
|
|
{nodelay, true} |
|
2003-02-06 20:09:22 +01:00
|
|
|
SSLOpts]),
|
2003-07-14 20:06:03 +02:00
|
|
|
accept_ssl(ListenSocket, Module, Opts).
|
2003-02-06 20:09:22 +01:00
|
|
|
|
2003-07-14 20:06:03 +02:00
|
|
|
accept_ssl(ListenSocket, Module, Opts) ->
|
2003-10-28 21:26:43 +01:00
|
|
|
case ssl:accept(ListenSocket, 200) of
|
2003-03-12 20:48:05 +01:00
|
|
|
{ok, Socket} ->
|
2003-10-09 20:09:05 +02:00
|
|
|
case {ssl:sockname(Socket), ssl:peername(Socket)} of
|
|
|
|
{{ok, Addr}, {ok, PAddr}} ->
|
|
|
|
?INFO_MSG("(~w) Accepted SSL connection ~w -> ~w",
|
|
|
|
[Socket, PAddr, Addr]);
|
|
|
|
_ ->
|
|
|
|
ok
|
|
|
|
end,
|
2003-10-29 21:09:09 +01:00
|
|
|
{ok, Pid} = Module:start({ssl, Socket}, Opts),
|
|
|
|
ssl:controlling_process(Socket, Pid),
|
2003-10-28 21:26:43 +01:00
|
|
|
accept_ssl(ListenSocket, Module, Opts);
|
|
|
|
{error, timeout} ->
|
|
|
|
accept_ssl(ListenSocket, Module, Opts);
|
|
|
|
{error, Reason} ->
|
|
|
|
?INFO_MSG("(~w) Failed SSL handshake: ~w",
|
|
|
|
[ListenSocket, Reason]),
|
2003-07-14 20:06:03 +02:00
|
|
|
accept_ssl(ListenSocket, Module, Opts)
|
2002-11-18 21:39:47 +01:00
|
|
|
end.
|
|
|
|
|
|
|
|
|