ranch_acceptors_sup.erl (2859B)
1 %% Copyright (c) 2011-2018, Loïc Hoguin <essen@ninenines.eu> 2 %% 3 %% Permission to use, copy, modify, and/or distribute this software for any 4 %% purpose with or without fee is hereby granted, provided that the above 5 %% copyright notice and this permission notice appear in all copies. 6 %% 7 %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15 -module(ranch_acceptors_sup). 16 -behaviour(supervisor). 17 18 -export([start_link/2]). 19 -export([init/1]). 20 21 -spec start_link(ranch:ref(), module()) 22 -> {ok, pid()}. 23 start_link(Ref, Transport) -> 24 supervisor:start_link(?MODULE, [Ref, Transport]). 25 26 init([Ref, Transport]) -> 27 ConnsSup = ranch_server:get_connections_sup(Ref), 28 TransOpts = ranch_server:get_transport_options(Ref), 29 NumAcceptors = maps:get(num_acceptors, TransOpts, 10), 30 Logger = maps:get(logger, TransOpts, error_logger), 31 LSocket = case maps:get(socket, TransOpts, undefined) of 32 undefined -> 33 SocketOpts = maps:get(socket_opts, TransOpts, []), 34 %% We temporarily put the logger in the process dictionary 35 %% so that it can be used from ranch:filter_options. The 36 %% interface as it currently is does not allow passing it 37 %% down otherwise. 38 put(logger, Logger), 39 case Transport:listen(SocketOpts) of 40 {ok, Socket} -> 41 erase(logger), 42 Socket; 43 {error, Reason} -> 44 listen_error(Ref, Transport, SocketOpts, Reason, Logger) 45 end; 46 Socket -> 47 Socket 48 end, 49 {ok, Addr} = Transport:sockname(LSocket), 50 ranch_server:set_addr(Ref, Addr), 51 Procs = [ 52 {{acceptor, self(), N}, {ranch_acceptor, start_link, [ 53 LSocket, Transport, Logger, ConnsSup 54 ]}, permanent, brutal_kill, worker, []} 55 || N <- lists:seq(1, NumAcceptors)], 56 {ok, {{one_for_one, 1, 5}, Procs}}. 57 58 -spec listen_error(any(), module(), any(), atom(), module()) -> no_return(). 59 listen_error(Ref, Transport, SocketOpts0, Reason, Logger) -> 60 SocketOpts1 = [{cert, '...'}|proplists:delete(cert, SocketOpts0)], 61 SocketOpts2 = [{key, '...'}|proplists:delete(key, SocketOpts1)], 62 SocketOpts = [{cacerts, '...'}|proplists:delete(cacerts, SocketOpts2)], 63 ranch:log(error, 64 "Failed to start Ranch listener ~p in ~p:listen(~999999p) for reason ~p (~s)~n", 65 [Ref, Transport, SocketOpts, Reason, format_error(Reason)], Logger), 66 exit({listen_error, Ref, Reason}). 67 68 format_error(no_cert) -> 69 "no certificate provided; see cert, certfile, sni_fun or sni_hosts options"; 70 format_error(Reason) -> 71 inet:format_error(Reason).