aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ranch_acceptor.erl18
-rw-r--r--src/ranch_ssl.erl6
-rw-r--r--test/acceptor_SUITE.erl17
3 files changed, 34 insertions, 7 deletions
diff --git a/src/ranch_acceptor.erl b/src/ranch_acceptor.erl
index e03cde9..d208a7f 100644
--- a/src/ranch_acceptor.erl
+++ b/src/ranch_acceptor.erl
@@ -46,6 +46,11 @@ init(LSocket, Transport, Protocol, MaxConns, Opts, ListenerPid, ConnsSup) ->
non_neg_integer(), any(), pid(), pid()) -> no_return().
loop(LSocket, Transport, Protocol, MaxConns, Opts, ListenerPid, ConnsSup) ->
receive
+ %% We couldn't accept the socket but it's safe to continue.
+ {accept, continue} ->
+ ?MODULE:init(LSocket, Transport, Protocol,
+ MaxConns, Opts, ListenerPid, ConnsSup);
+ %% Found my sockets!
{accept, CSocket} ->
{ok, ConnPid} = supervisor:start_child(ConnsSup,
[ListenerPid, CSocket, Transport, Protocol, Opts]),
@@ -55,6 +60,7 @@ loop(LSocket, Transport, Protocol, MaxConns, Opts, ListenerPid, ConnsSup) ->
maybe_wait(ListenerPid, MaxConns, NbConns),
?MODULE:init(LSocket, Transport, Protocol,
MaxConns, Opts, ListenerPid, ConnsSup);
+ %% Upgrade the protocol options.
{set_opts, Opts2} ->
?MODULE:loop(LSocket, Transport, Protocol,
MaxConns, Opts2, ListenerPid, ConnsSup)
@@ -72,9 +78,13 @@ maybe_wait(ListenerPid, MaxConns, _) ->
async_accept(LSocket, Transport) ->
AcceptorPid = self(),
_ = spawn_link(fun() ->
- %% @todo {error, closed} must be handled and other errors ignored.
- {ok, CSocket} = Transport:accept(LSocket, infinity),
- Transport:controlling_process(CSocket, AcceptorPid),
- AcceptorPid ! {accept, CSocket}
+ case Transport:accept(LSocket, infinity) of
+ {ok, CSocket} ->
+ Transport:controlling_process(CSocket, AcceptorPid),
+ AcceptorPid ! {accept, CSocket};
+ %% We want to crash if the listening socket got closed.
+ {error, Reason} when Reason =/= closed ->
+ AcceptorPid ! {accept, continue}
+ end
end),
ok.
diff --git a/src/ranch_ssl.erl b/src/ranch_ssl.erl
index 51ea128..d85c05f 100644
--- a/src/ranch_ssl.erl
+++ b/src/ranch_ssl.erl
@@ -111,7 +111,7 @@ listen(Opts) ->
%% @see ssl:transport_accept/2
%% @see ssl:ssl_accept/2
-spec accept(ssl:sslsocket(), timeout())
- -> {ok, ssl:sslsocket()} | {error, closed | timeout | atom()}.
+ -> {ok, ssl:sslsocket()} | {error, closed | timeout | atom() | tuple()}.
accept(LSocket, Timeout) ->
case ssl:transport_accept(LSocket, Timeout) of
{ok, CSocket} ->
@@ -179,11 +179,11 @@ require([App|Tail]) ->
require(Tail).
-spec ssl_accept(ssl:sslsocket(), timeout())
- -> {ok, ssl:sslsocket()} | {error, closed | timeout | atom()}.
+ -> {ok, ssl:sslsocket()} | {error, {ssl_accept, atom()}}.
ssl_accept(Socket, Timeout) ->
case ssl:ssl_accept(Socket, Timeout) of
ok ->
{ok, Socket};
{error, Reason} ->
- {error, Reason}
+ {error, {ssl_accept, Reason}}
end.
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl
index 389f375..1c0931b 100644
--- a/test/acceptor_SUITE.erl
+++ b/test/acceptor_SUITE.erl
@@ -25,6 +25,7 @@
-export([end_per_group/2]).
%% ssl.
+-export([ssl_accept_error/1]).
-export([ssl_echo/1]).
%% tcp.
@@ -45,6 +46,7 @@ groups() ->
tcp_max_connections_and_beyond,
tcp_upgrade
]}, {ssl, [
+ ssl_accept_error,
ssl_echo
]}].
@@ -74,6 +76,21 @@ end_per_group(_, _) ->
%% ssl.
+ssl_accept_error(Config) ->
+ {ok, _} = ranch:start_listener(ssl_accept_error, 1,
+ ranch_ssl, [{port, 0},
+ {certfile, ?config(data_dir, Config) ++ "cert.pem"}],
+ echo_protocol, []),
+ Port = ranch:get_port(ssl_accept_error),
+ [AcceptorPid] = ets:lookup_element(ranch_server,
+ {acceptors, ssl_accept_error}, 2),
+ true = is_process_alive(AcceptorPid),
+ {ok, Socket} = gen_tcp:connect("localhost", Port,
+ [binary, {active, false}, {packet, raw}]),
+ ok = gen_tcp:close(Socket),
+ receive after 500 -> ok end,
+ true = is_process_alive(AcceptorPid).
+
ssl_echo(Config) ->
{ok, _} = ranch:start_listener(ssl_echo, 1,
ranch_ssl, [{port, 0},