aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--manual/ranch_transport.md2
-rw-r--r--src/ranch.erl4
-rw-r--r--src/ranch_conns_sup.erl26
-rw-r--r--src/ranch_listener_sup.erl3
-rw-r--r--src/ranch_ssl.erl32
-rw-r--r--src/ranch_tcp.erl5
-rw-r--r--src/ranch_transport.erl5
-rw-r--r--test/sendfile_SUITE.erl1
8 files changed, 42 insertions, 36 deletions
diff --git a/manual/ranch_transport.md b/manual/ranch_transport.md
index 7eb350d..291b0e4 100644
--- a/manual/ranch_transport.md
+++ b/manual/ranch_transport.md
@@ -17,7 +17,7 @@ Callbacks
---------
### accept(LSocket, Timeout)
- -> {ok, CSocket} | {error, closed | timeout | atom() | tuple()}
+ -> {ok, CSocket} | {error, closed | timeout | atom()}
> Types:
> * LSocket = CSocket = any()
diff --git a/src/ranch.erl b/src/ranch.erl
index 2db4921..9bcd328 100644
--- a/src/ranch.erl
+++ b/src/ranch.erl
@@ -128,7 +128,9 @@ child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
%% the protocol process before starting to use it.
-spec accept_ack(ref()) -> ok.
accept_ack(Ref) ->
- receive {shoot, Ref} -> ok end.
+ receive {shoot, Ref, Transport, Socket, AckTimeout} ->
+ Transport:accept_ack(Socket, AckTimeout)
+ end.
%% @doc Remove the calling process' connection from the pool.
%%
diff --git a/src/ranch_conns_sup.erl b/src/ranch_conns_sup.erl
index 245a5e0..f920919 100644
--- a/src/ranch_conns_sup.erl
+++ b/src/ranch_conns_sup.erl
@@ -20,12 +20,12 @@
-module(ranch_conns_sup).
%% API.
--export([start_link/4]).
+-export([start_link/5]).
-export([start_protocol/2]).
-export([active_connections/1]).
%% Supervisor internals.
--export([init/5]).
+-export([init/6]).
-export([system_continue/3]).
-export([system_terminate/4]).
-export([system_code_change/4]).
@@ -39,15 +39,17 @@
transport = undefined :: module(),
protocol = undefined :: module(),
opts :: any(),
- max_conns = undefined :: non_neg_integer() | infinity
+ ack_timeout :: timeout(),
+ max_conns = undefined :: ranch:max_conns()
}).
%% API.
--spec start_link(ranch:ref(), conn_type(), module(), module()) -> {ok, pid()}.
-start_link(Ref, ConnType, Transport, Protocol) ->
+-spec start_link(ranch:ref(), conn_type(), module(), timeout(), module())
+ -> {ok, pid()}.
+start_link(Ref, ConnType, Transport, AckTimeout, Protocol) ->
proc_lib:start_link(?MODULE, init,
- [self(), Ref, ConnType, Transport, Protocol]).
+ [self(), Ref, ConnType, Transport, AckTimeout, Protocol]).
%% We can safely assume we are on the same node as the supervisor.
%%
@@ -92,8 +94,9 @@ active_connections(SupPid) ->
%% Supervisor internals.
--spec init(pid(), ranch:ref(), conn_type(), module(), module()) -> no_return().
-init(Parent, Ref, ConnType, Transport, Protocol) ->
+-spec init(pid(), ranch:ref(), conn_type(), module(), timeout(), module())
+ -> no_return().
+init(Parent, Ref, ConnType, Transport, AckTimeout, Protocol) ->
process_flag(trap_exit, true),
ok = ranch_server:set_connections_sup(Ref, self()),
MaxConns = ranch_server:get_max_connections(Ref),
@@ -101,17 +104,18 @@ init(Parent, Ref, ConnType, Transport, Protocol) ->
ok = proc_lib:init_ack(Parent, {ok, self()}),
loop(#state{parent=Parent, ref=Ref, conn_type=ConnType,
transport=Transport, protocol=Protocol, opts=Opts,
- max_conns=MaxConns}, 0, 0, []).
+ ack_timeout=AckTimeout, max_conns=MaxConns}, 0, 0, []).
loop(State=#state{parent=Parent, ref=Ref, conn_type=ConnType,
transport=Transport, protocol=Protocol, opts=Opts,
- max_conns=MaxConns}, CurConns, NbChildren, Sleepers) ->
+ ack_timeout=AckTimeout, max_conns=MaxConns},
+ CurConns, NbChildren, Sleepers) ->
receive
{?MODULE, start_protocol, To, Socket} ->
case Protocol:start_link(Ref, Socket, Transport, Opts) of
{ok, Pid} ->
Transport:controlling_process(Socket, Pid),
- Pid ! {shoot, Ref},
+ Pid ! {shoot, Ref, Transport, Socket, AckTimeout},
put(Pid, true),
CurConns2 = CurConns + 1,
if CurConns2 < MaxConns ->
diff --git a/src/ranch_listener_sup.erl b/src/ranch_listener_sup.erl
index 56df6b7..b0a6bd5 100644
--- a/src/ranch_listener_sup.erl
+++ b/src/ranch_listener_sup.erl
@@ -36,10 +36,11 @@ start_link(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) ->
%% supervisor.
init({Ref, NbAcceptors, Transport, TransOpts, Protocol}) ->
+ AckTimeout = proplists:get_value(ack_timeout, TransOpts, 5000),
ConnType = proplists:get_value(connection_type, TransOpts, worker),
ChildSpecs = [
{ranch_conns_sup, {ranch_conns_sup, start_link,
- [Ref, ConnType, Transport, Protocol]},
+ [Ref, ConnType, Transport, AckTimeout, Protocol]},
permanent, infinity, supervisor, [ranch_conns_sup]},
{ranch_acceptors_sup, {ranch_acceptors_sup, start_link,
[Ref, NbAcceptors, Transport, TransOpts]},
diff --git a/src/ranch_ssl.erl b/src/ranch_ssl.erl
index 8fa7358..a6ceb4d 100644
--- a/src/ranch_ssl.erl
+++ b/src/ranch_ssl.erl
@@ -30,6 +30,7 @@
-export([messages/0]).
-export([listen/1]).
-export([accept/2]).
+-export([accept_ack/2]).
-export([connect/3]).
-export([recv/3]).
-export([send/2]).
@@ -164,13 +165,18 @@ listen(Opts) ->
%% @see ssl:transport_accept/2
%% @see ssl:ssl_accept/2
-spec accept(ssl:sslsocket(), timeout())
- -> {ok, ssl:sslsocket()} | {error, closed | timeout | atom() | tuple()}.
+ -> {ok, ssl:sslsocket()} | {error, closed | timeout | atom()}.
accept(LSocket, Timeout) ->
- case ssl:transport_accept(LSocket, Timeout) of
- {ok, CSocket} ->
- ssl_accept(CSocket, Timeout);
+ ssl:transport_accept(LSocket, Timeout).
+
+-spec accept_ack(ssl:sslsocket(), timeout()) -> ok.
+accept_ack(CSocket, Timeout) ->
+ case ssl:ssl_accept(CSocket, Timeout) of
+ ok ->
+ ok;
{error, Reason} ->
- {error, Reason}
+ ok = close(CSocket),
+ error(Reason)
end.
%% @private Experimental. Open a connection to the given host and port number.
@@ -263,22 +269,6 @@ close(Socket) ->
%% Internal.
-%% This call always times out, either because a numeric timeout value
-%% was given, or because we've decided to use 5000ms instead of infinity.
-%% This value should be reasonable enough for the moment.
--spec ssl_accept(ssl:sslsocket(), timeout())
- -> {ok, ssl:sslsocket()} | {error, {ssl_accept, atom()}}.
-ssl_accept(Socket, infinity) ->
- ssl_accept(Socket, 5000);
-ssl_accept(Socket, Timeout) ->
- case ssl:ssl_accept(Socket, Timeout) of
- ok ->
- {ok, Socket};
- {error, Reason} ->
- ok = close(Socket),
- {error, {ssl_accept, Reason}}
- end.
-
%% Unfortunately the implementation of elliptic-curve ciphers that has
%% been introduced in R16B01 is incomplete. Depending on the particular
%% client, this can cause the TLS handshake to break during key
diff --git a/src/ranch_tcp.erl b/src/ranch_tcp.erl
index 087cf09..86b1e35 100644
--- a/src/ranch_tcp.erl
+++ b/src/ranch_tcp.erl
@@ -24,6 +24,7 @@
-export([messages/0]).
-export([listen/1]).
-export([accept/2]).
+-export([accept_ack/2]).
-export([connect/3]).
-export([recv/3]).
-export([send/2]).
@@ -89,6 +90,10 @@ listen(Opts) ->
accept(LSocket, Timeout) ->
gen_tcp:accept(LSocket, Timeout).
+-spec accept_ack(inet:socket(), timeout()) -> ok.
+accept_ack(_, _) ->
+ ok.
+
%% @private Experimental. Open a connection to the given host and port number.
%% @see gen_tcp:connect/3
%% @todo Probably filter Opts?
diff --git a/src/ranch_transport.erl b/src/ranch_transport.erl
index d557594..5c1153c 100644
--- a/src/ranch_transport.erl
+++ b/src/ranch_transport.erl
@@ -46,7 +46,10 @@
%% Accept connections with the given listening socket.
-callback accept(socket(), timeout())
- -> {ok, socket()} | {error, closed | timeout | atom() | tuple()}.
+ -> {ok, socket()} | {error, closed | timeout | atom()}.
+
+%% Perform post-accept operations on the socket.
+-callback accept_ack(socket(), timeout()) -> ok.
%% Experimental. Open a connection to the given host and port number.
-callback connect(string(), inet:port_number(), opts())
diff --git a/test/sendfile_SUITE.erl b/test/sendfile_SUITE.erl
index dc05fe6..c74659e 100644
--- a/test/sendfile_SUITE.erl
+++ b/test/sendfile_SUITE.erl
@@ -305,6 +305,7 @@ sockets(Config) ->
end,
_ = spawn_link(Fun),
{ok, Server} = Transport:accept(LSocket, 500),
+ ok = Transport:accept_ack(Server, 500),
receive
{ok, Client} ->
ok = Transport:close(LSocket),