From d44e7a16f7d2823cc658e39b5d953ba0850e47ba Mon Sep 17 00:00:00 2001 From: juhlig Date: Tue, 17 Sep 2019 17:55:25 +0200 Subject: Enable multiple steps handshake Also fix some Protocol:start_link/4 into start_link/3 left over in the documentation. --- doc/src/guide/listeners.asciidoc | 4 +- doc/src/guide/protocols.asciidoc | 2 +- doc/src/manual/ranch.asciidoc | 2 + doc/src/manual/ranch.handshake.asciidoc | 22 ++++++-- doc/src/manual/ranch.handshake_cancel.asciidoc | 55 +++++++++++++++++++ doc/src/manual/ranch.handshake_continue.asciidoc | 67 ++++++++++++++++++++++++ doc/src/manual/ranch.recv_proxy_header.asciidoc | 2 +- doc/src/manual/ranch_ssl.asciidoc | 10 ++++ doc/src/manual/ranch_transport.asciidoc | 52 +++++++++++++++++- 9 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 doc/src/manual/ranch.handshake_cancel.asciidoc create mode 100644 doc/src/manual/ranch.handshake_continue.asciidoc (limited to 'doc/src') diff --git a/doc/src/guide/listeners.asciidoc b/doc/src/guide/listeners.asciidoc index fd988f1..6e2dd19 100644 --- a/doc/src/guide/listeners.asciidoc +++ b/doc/src/guide/listeners.asciidoc @@ -239,8 +239,8 @@ with the name of the listener as the only argument. [source,erlang] ranch:remove_connection(Ref). -As seen in the chapter covering protocols, this pid is received as the -first argument of the protocol's `start_link/4` callback. +As seen in the chapter covering protocols, this reference is received +as the first argument of the protocol's `start_link/3` callback. You can modify the `max_connections` value on a running listener by using the `ranch:set_max_connections/2` function, with the name of the diff --git a/doc/src/guide/protocols.asciidoc b/doc/src/guide/protocols.asciidoc index 89360ef..b455143 100644 --- a/doc/src/guide/protocols.asciidoc +++ b/doc/src/guide/protocols.asciidoc @@ -6,7 +6,7 @@ protocol logic executed in this process. === Writing a protocol handler All protocol handlers must implement the `ranch_protocol` behavior -which defines a single callback, `start_link/4`. This callback is +which defines a single callback, `start_link/3`. This callback is responsible for spawning a new process for handling the connection. It receives four arguments: the name of the listener, the socket, the transport handler being used and the protocol options defined in diff --git a/doc/src/manual/ranch.asciidoc b/doc/src/manual/ranch.asciidoc index 065ded3..ed57236 100644 --- a/doc/src/manual/ranch.asciidoc +++ b/doc/src/manual/ranch.asciidoc @@ -26,6 +26,8 @@ Suspend/resume: Connections: * link:man:ranch:handshake(3)[ranch:handshake(3)] - Perform the transport handshake +* link:man:ranch:handshake_continue(3)[ranch:handshake_continue(3)] - Resume the paused transport handshake +* link:man:ranch:handshake_cancel(3)[ranch:handshake_cancel(3)] - Cancel the paused transport handshake * link:man:ranch:recv_proxy_header(3)[ranch:recv_proxy_header(3)] - Receive the PROXY protocol header * link:man:ranch:remove_connection(3)[ranch:remove_connection(3)] - Remove connection from the count diff --git a/doc/src/manual/ranch.handshake.asciidoc b/doc/src/manual/ranch.handshake.asciidoc index 5d2694c..508abe5 100644 --- a/doc/src/manual/ranch.handshake.asciidoc +++ b/doc/src/manual/ranch.handshake.asciidoc @@ -8,12 +8,13 @@ ranch:handshake - Perform the transport handshake [source,erlang] ---- -handshake(Ref) -> handshake(Ref, []) -handshake(Ref, Opts) -> {ok, Socket} +handshake(Ref) -> {ok, Socket} | {continue, Info} +handshake(Ref, Opts) -> {ok, Socket} | {continue, Info} Ref :: ranch:ref() Opts :: any() Socket :: any() +Info :: any() ---- Perform the transport handshake. @@ -38,12 +39,23 @@ Allowed options depend on the transport module. == Return value -An `ok` tuple is returned containing the socket for the connection. +An `ok` tuple is returned containing the socket for the connection +by default. + +Depending on configuration, a `continue` tuple can otherwise +be returned when the handshake operation is paused. It contains +data provided by the transport that can be used to inform further +decisions before resuming the handshake, for example to provide +new transport options. The handshake can be resumed using +link:man:ranch:handshake_continue(3)[ranch:handshake_continue(3)] +or canceled using +link:man:ranch:handshake_cancel(3)[ranch:handshake_cancel(3)]. This function will trigger an exception when an error occurs. == Changelog +* *2.0*: The `continue` tuple can now be returned. * *1.6*: Function introduced. Replaces `ranch:accept_ack/1`. == Examples @@ -51,7 +63,7 @@ This function will trigger an exception when an error occurs. .Initialize the connection process [source,erlang] ---- -start_link(Ref, _, Transport, Opts) -> +start_link(Ref, Transport, Opts) -> Pid = proc_lib:spawn_link(?MODULE, init, [Ref, Transport, Opts]), {ok, Pid}. @@ -65,6 +77,8 @@ init(Ref, Transport, Opts) -> == See also link:man:ranch:start_listener(3)[ranch:start_listener(3)], +link:man:ranch:handshake_continue(3)[ranch:handshake_continue(3)], +link:man:ranch:handshake_cancel(3)[ranch:handshake_cancel(3)], link:man:ranch:recv_proxy_header(3)[ranch:recv_proxy_header(3)], link:man:ranch:remove_connection(3)[ranch:remove_connection(3)], link:man:ranch(3)[ranch(3)] diff --git a/doc/src/manual/ranch.handshake_cancel.asciidoc b/doc/src/manual/ranch.handshake_cancel.asciidoc new file mode 100644 index 0000000..6f742f5 --- /dev/null +++ b/doc/src/manual/ranch.handshake_cancel.asciidoc @@ -0,0 +1,55 @@ += ranch:handshake_cancel(3) + +== Name + +ranch:handshake_cancel - Cancel the paused transport handshake + +== Description + +[source,erlang] +---- +handshake_cancel(Ref :: ranch:ref()) -> ok +---- + +Cancel the paused transport handshake. + +This function may be called by the protocol process +to cancel a paused handshake. + +== Arguments + +Ref:: + +The listener name. ++ +Allowed options depend on the transport module. + +== Return value + +The return value depends on the transport module. + +== Changelog + +* *2.0*: Function introduced. + +== Examples + +.Cancel a paused transport handshake +[source,erlang] +---- +start_link(Ref, Transport, Opts) -> + Pid = proc_lib:spawn_link(?MODULE, init, + [Ref, Transport, Opts]), + {ok, Pid}. + +init(Ref, Transport, Opts) -> + {continue, _Info} = ranch:handshake(Ref), + ranch:handshake_cancel(Ref), + exit(handshake_cancelled). +---- + +== See also + +link:man:ranch:handshake(3)[ranch:handshake(3)], +link:man:ranch:handshake_continue(3)[ranch:handshake_continue(3)], +link:man:ranch(3)[ranch(3)] diff --git a/doc/src/manual/ranch.handshake_continue.asciidoc b/doc/src/manual/ranch.handshake_continue.asciidoc new file mode 100644 index 0000000..4fb08bf --- /dev/null +++ b/doc/src/manual/ranch.handshake_continue.asciidoc @@ -0,0 +1,67 @@ += ranch:handshake_continue(3) + +== Name + +ranch:handshake_continue - Resume the paused transport handshake + +== Description + +[source,erlang] +---- +handshake_continue(Ref) -> {ok, Socket} +handshake_continue(Ref, Opts) -> {ok, Socket} + +Ref :: ranch:ref() +Opts :: any() +Socket :: any() +---- + +Resume the paused transport handshake. + +This function must be called by the protocol process in order +to resume a paused handshake. + +== Arguments + +Ref:: + +The listener name. + +Opts:: + +Transport handshake options. ++ +Allowed options depend on the transport module. + +== Return value + +An `ok` tuple is returned containing the socket for the connection. + +This function will trigger an exception when an error occurs. + +== Changelog + +* *2.0*: Function introduced. + +== Examples + +.Continue a paused transport handshake +[source,erlang] +---- +start_link(Ref, Transport, Opts) -> + Pid = proc_lib:spawn_link(?MODULE, init, + [Ref, Transport, Opts]), + {ok, Pid}. + +init(Ref, Transport, Opts) -> + {continue, _Info} = ranch:handshake(Ref), + {ok, Socket} = ranch:handshake_continue(Ref), + loop(#state{ref=Ref, socket=Socket, + transport=Transport, opts=Opts}). +---- + +== See also + +link:man:ranch:handshake(3)[ranch:handshake(3)], +link:man:ranch:handshake_cancel(3)[ranch:handshake_cancel(3)], +link:man:ranch(3)[ranch(3)] diff --git a/doc/src/manual/ranch.recv_proxy_header.asciidoc b/doc/src/manual/ranch.recv_proxy_header.asciidoc index 9f23bde..0536e3d 100644 --- a/doc/src/manual/ranch.recv_proxy_header.asciidoc +++ b/doc/src/manual/ranch.recv_proxy_header.asciidoc @@ -51,7 +51,7 @@ the error. .Receive the PROXY protocol header [source,erlang] ---- -start_link(Ref, _, Transport, Opts) -> +start_link(Ref, Transport, Opts) -> Pid = proc_lib:spawn_link(?MODULE, init, [Ref, Transport, Opts]), {ok, Pid}. diff --git a/doc/src/manual/ranch_ssl.asciidoc b/doc/src/manual/ranch_ssl.asciidoc index 00f6fad..66f91b1 100644 --- a/doc/src/manual/ranch_ssl.asciidoc +++ b/doc/src/manual/ranch_ssl.asciidoc @@ -54,6 +54,7 @@ ssl_opt() = {alpn_preferred_protocols, [binary()]} | {dhfile, file:filename()} | {eccs, [atom()]} | {fail_if_no_peer_cert, boolean()} + | {handshake, hello | full} | {hibernate_after, timeout()} | {honor_cipher_order, boolean()} | {honor_ecc_order, boolean()} @@ -156,6 +157,15 @@ fail_if_no_peer_cert (false):: Whether to refuse the connection if the client sends an empty certificate. +handshake (full):: + +If `hello` is specified for this option, the handshake is +paused after receiving the client hello message. The handshake +can then be resumed via `handshake_continue/3`, or cancelled +via `handshake_cancel/1`. ++ +This option cannot be given to `ranch:handshake/1,2`. + hibernate_after (undefined):: Time in ms after which SSL socket processes go into diff --git a/doc/src/manual/ranch_transport.asciidoc b/doc/src/manual/ranch_transport.asciidoc index 78468b3..c26d91c 100644 --- a/doc/src/manual/ranch_transport.asciidoc +++ b/doc/src/manual/ranch_transport.asciidoc @@ -80,9 +80,17 @@ Get one or more statistic options for the socket. [source,erlang] ---- handshake(Socket0 :: socket(), - SockOpts :: any(), Timeout :: timeout()) - -> {ok, Socket} + -> {ok, Socket :: socket()} + | {ok, Socket :: socket(), Info :: any()} + | {error, any()} + +handshake(Socket0 :: socket(), + SockOpts :: opts(), + Timeout :: timeout()) + -> {ok, Socket :: socket()} + | {ok, Socket :: socket(), Info :: any()} + | {error, any()} ---- Perform the transport-level handshake. @@ -92,11 +100,51 @@ 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. +If the handshake is completed by this call, the function will +return `{ok, Socket}`. However, some transports (notably, +`ranch_ssl` if `{handshake, hello}` is specified in the socket +options) may pause the handshake at a certain point and return +`{ok, Socket, Info}` instead, in order to allow for +additional decisions to be made before resuming the handshake +with `handshake_continue/3` or cancelling it with +`handshake_cancel/1`. + This function may also be used to upgrade a connection from a transport to another depending on the capabilities of the transports. For example a `ranch_tcp` socket may be upgraded to a `ranch_ssl` one using this function. +=== handshake_continue + +[source,erlang] +---- +handshake_continue(Socket0 :: socket(), + Timeout :: timeout()) + -> {ok, Socket :: socket()} + | {error, any()} + +handshake_continue(Socket0 :: socket(), + SockOpts :: opts(), + Timeout :: timeout()) + -> {ok, Socket :: socket()} + | {error, any()} +---- + +Resume the paused transport-level handshake and return a socket +that is ready to use. + +This function will be called by connection processes +to resume a paused handshake. + +=== handshake_cancel + +[source,erlang] +---- +handshake_cancel(Socket :: socket()) -> ok +---- + +Cancel the paused transport-level handshake. + === listen [source,erlang] -- cgit v1.2.3