From 5ada450fe10a5fc51b7f3f0900571a10547635a1 Mon Sep 17 00:00:00 2001 From: "j.uhlig" Date: Tue, 26 Jun 2018 17:07:13 +0200 Subject: Introduce Transport:handshake/1,2 This commit deprecates Transport:accept_ack/1 in favor of a new forward-compatible function. Transport:handshake/1,2 will use ssl:handshake/2,3 from Ranch 2.0 onward. --- doc/src/guide/protocols.asciidoc | 28 +++++++++++------------ doc/src/manual/ranch.asciidoc | 40 +++++++++++++++++++++++++-------- doc/src/manual/ranch_transport.asciidoc | 28 ++++++++++++----------- 3 files changed, 60 insertions(+), 36 deletions(-) (limited to 'doc/src') diff --git a/doc/src/guide/protocols.asciidoc b/doc/src/guide/protocols.asciidoc index 91f4b07..b20b22d 100644 --- a/doc/src/guide/protocols.asciidoc +++ b/doc/src/guide/protocols.asciidoc @@ -14,18 +14,18 @@ the call to `ranch:start_listener/5`. This callback must return `{ok, Pid}`, with `Pid` the pid of the new process. The newly started process can then freely initialize itself. However, -it must call `ranch:accept_ack/1` before doing any socket operation. +it must call `ranch:handshake/{1,2}` before doing any socket operation. This will ensure the connection process is the owner of the socket. It expects the listener's name as argument. -.Acknowledge accepting the socket +.Perform the socket handshake [source,erlang] -ok = ranch:accept_ack(Ref). +{ok, Socket} = ranch:handshake(Ref). If your protocol code requires specific socket options, you should set them while initializing your connection process, after -calling `ranch:accept_ack/1`. You can use `Transport:setopts/2` +calling `ranch:handshake/{1,2}`. You can use `Transport:setopts/2` for that purpose. Following is the complete protocol code for the example found @@ -39,14 +39,14 @@ in `examples/tcp_echo/`. -behaviour(ranch_protocol). -export([start_link/4]). --export([init/4]). +-export([init/3]). -start_link(Ref, Socket, Transport, Opts) -> - Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts]), +start_link(Ref, _Socket, Transport, Opts) -> + Pid = spawn_link(?MODULE, init, [Ref, Transport, Opts]), {ok, Pid}. -init(Ref, Socket, Transport, _Opts = []) -> - ok = ranch:accept_ack(Ref), +init(Ref, Transport, _Opts = []) -> + {ok, Socket} = ranch:handshake(Ref), loop(Socket, Transport). loop(Socket, Transport) -> @@ -64,7 +64,7 @@ loop(Socket, Transport) -> Special processes like the ones that use the `gen_statem` or `gen_server` behaviours have the particularity of having their `start_link` call not return until the `init` function returns. This is problematic, because -you won't be able to call `ranch:accept_ack/1` from the `init` callback +you won't be able to call `ranch:handshake/{1,2}` from the `init` callback as this would cause a deadlock to happen. Use the `gen_statem:enter_loop/4` function. It allows you to start your process @@ -84,12 +84,12 @@ the normal `gen_statem` execution loop. -export([init/1]). %% Exports of other gen_statem callbacks here. -start_link(Ref, Socket, Transport, Opts) -> - {ok, proc_lib:spawn_link(?MODULE, init, [{Ref, Socket, Transport, Opts}])}. +start_link(Ref, _Socket, Transport, Opts) -> + {ok, proc_lib:spawn_link(?MODULE, init, [{Ref, Transport, Opts}])}. -init({Ref, Socket, Transport, _Opts = []}) -> +init({Ref, Transport, _Opts = []}) -> %% Perform any required state initialization here. - ok = ranch:accept_ack(Ref), + {ok, Socket} = ranch:handshake(Ref), ok = Transport:setopts(Socket, [{active, once}]), gen_statem:enter_loop(?MODULE, [], state_name, {state_data, Socket, Transport}). diff --git a/doc/src/manual/ranch.asciidoc b/doc/src/manual/ranch.asciidoc index 7fd18d0..2380646 100644 --- a/doc/src/manual/ranch.asciidoc +++ b/doc/src/manual/ranch.asciidoc @@ -47,7 +47,7 @@ Unique name used to refer to a listener. None of the options are required. ack_timeout (5000):: - Maximum allowed time for the `ranch:accept_ack/1` call to finish. + Maximum allowed time for the `ranch:handshake/{1,2}` call to finish. connection_type (worker):: Type of process that will handle the connection. max_connections (1024):: @@ -63,13 +63,7 @@ socket:: === accept_ack(Ref) -> ok -Ref = ref():: Listener name. - -Acknowledge that the connection is accepted. - -This function MUST be used by a connection process to inform -Ranch that it initialized properly and let it perform any -additional operations before the socket can be safely used. +This function is deprecated in favor of `ranch:handshake/1,2`. === child_spec(Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts) -> supervisor:child_spec() @@ -127,6 +121,34 @@ TransOpts = any():: Current transport options. Return the transport options set for the given listener. +=== handshake(Ref) -> {ok, Socket} + +Ref = ref():: Listener name. +Socket = any():: Initialized socket. + +Acknowledge that the connection is accepted. +Returns a socket that is ready to use. + +One of the `ranch:handshake/{1,2}` functions MUST be used +by a connection process to inform Ranch that it initialized +properly and let it perform any additional operations before +the socket can be safely used. + +=== handshake(Ref, Opts) -> {ok, Socket} + +Ref = ref():: Listener name. +Opts = any():: Initialization options. +Socket = any():: Initialized socket. + +Acknowledge that the connection is accepted. +Additional options can be provided for socket initialization. +Returns a socket that is ready to use. + +One of the `ranch:handshake/{1,2}` functions MUST be used +by a connection process to inform Ranch that it initialized +properly and let it perform any additional operations before +the socket can be safely used. + === info() -> [{Ref, [{Key, Value}]}] Ref = ref():: Listener name. @@ -272,4 +294,4 @@ Operator = '>' | '>=' | '==' | '=<' | '<':: Comparison operator. NumConnections = non_neg_integer():: Number of connections to wait for. Wait until the number of connections on the given listener matches -the given operator and number of connections. \ No newline at end of file +the given operator and number of connections. diff --git a/doc/src/manual/ranch_transport.asciidoc b/doc/src/manual/ranch_transport.asciidoc index cbcea42..ed0ad70 100644 --- a/doc/src/manual/ranch_transport.asciidoc +++ b/doc/src/manual/ranch_transport.asciidoc @@ -26,22 +26,10 @@ Timeout = timeout():: Accept timeout. Accept a connection on the given listening socket. -The `accept_ack` callback will be used to initialize the socket +The `handshake` callback will be used to initialize the socket after accepting the connection. This is most useful when the transport is not raw TCP, like with SSL for example. -=== accept_ack(CSocket, Timeout) -> ok - -CSocket = any():: Socket for this connection. -Timeout = timeout():: Ack timeout. - -Perform post-accept initialization of the connection. - -This function will be called by connection processes -before performing any socket operation. It allows -transports that require extra initialization to perform -their task and make the socket ready to use. - === close(Socket) -> ok Socket = any():: Socket opened with listen/1 or accept/2. @@ -60,6 +48,20 @@ perform operations on the socket, and that will receive messages from the socket when active mode is used. When the controlling process dies, the socket is closed. +=== handshake(CSocket0, Options, Timeout) -> {ok, CSocket1} + +CSocket0 = any():: Uninitialized socket for this connection. +Options = any():: Options for initialization. +Timeout = timeout():: Handshake timeout. +CSocket1 = any():: Initialized socket for this connection. + +Perform post-accept initialization of the connection. + +This function will be called by connection processes +before performing any socket operation. It allows +transports that require extra initialization to perform +their task and return a socket that is ready to use. + === listen(TransOpts) -> {ok, LSocket} | {error, atom()} TransOpts = any():: Transport options. -- cgit v1.2.3