aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2015-08-22 13:15:08 +0200
committerLoïc Hoguin <[email protected]>2015-08-22 13:15:08 +0200
commitf4c6da56d4fe9494f4fe23c48b8d7c3c1e9e6b42 (patch)
tree5f73255bbd51d46fccf371ff7cdd67c6bea8e7b7
parentd30408b2e8c14c0e56ce997f5aff0010c03cef0b (diff)
downloadranch-f4c6da56d4fe9494f4fe23c48b8d7c3c1e9e6b42.tar.gz
ranch-f4c6da56d4fe9494f4fe23c48b8d7c3c1e9e6b42.tar.bz2
ranch-f4c6da56d4fe9494f4fe23c48b8d7c3c1e9e6b42.zip
Convert the documentation to Asciidoc
-rw-r--r--doc/src/guide/book.asciidoc20
-rw-r--r--doc/src/guide/embedded.asciidoc (renamed from guide/embedded.md)30
-rw-r--r--doc/src/guide/internals.asciidoc (renamed from guide/internals.md)19
-rw-r--r--doc/src/guide/introduction.asciidoc (renamed from guide/introduction.md)24
-rw-r--r--doc/src/guide/listeners.asciidoc (renamed from guide/listeners.md)131
-rw-r--r--doc/src/guide/parsers.asciidoc (renamed from guide/parsers.md)60
-rw-r--r--doc/src/guide/protocols.asciidoc (renamed from guide/protocols.md)82
-rw-r--r--doc/src/guide/ssl_auth.asciidoc (renamed from guide/ssl_auth.md)50
-rw-r--r--doc/src/guide/transports.asciidoc (renamed from guide/transports.md)84
-rw-r--r--doc/src/manual/ranch.asciidoc170
-rw-r--r--doc/src/manual/ranch_app.asciidoc (renamed from manual/ranch_app.md)21
-rw-r--r--doc/src/manual/ranch_protocol.asciidoc44
-rw-r--r--doc/src/manual/ranch_ssl.asciidoc142
-rw-r--r--doc/src/manual/ranch_tcp.asciidoc123
-rw-r--r--doc/src/manual/ranch_transport.asciidoc194
-rw-r--r--guide/toc.md25
-rw-r--r--manual/ranch.md182
-rw-r--r--manual/ranch_protocol.md42
-rw-r--r--manual/ranch_ssl.md135
-rw-r--r--manual/ranch_tcp.md115
-rw-r--r--manual/ranch_transport.md205
-rw-r--r--manual/toc.md11
22 files changed, 945 insertions, 964 deletions
diff --git a/doc/src/guide/book.asciidoc b/doc/src/guide/book.asciidoc
new file mode 100644
index 0000000..59e8e70
--- /dev/null
+++ b/doc/src/guide/book.asciidoc
@@ -0,0 +1,20 @@
+// a2x: --dblatex-opts "-P latex.output.revhistory=0 -P doc.publisher.show=0 -P index.numbered=0"
+// a2x: -d book --attribute tabsize=4
+
+= Ranch User Guide
+
+include::introduction.asciidoc[Introduction]
+
+include::listeners.asciidoc[Listeners]
+
+include::transports.asciidoc[Transports]
+
+include::protocols.asciidoc[Protocols]
+
+include::embedded.asciidoc[Embedded mode]
+
+include::parsers.asciidoc[Writing parsers]
+
+include::ssl_auth.asciidoc[SSL client authentication]
+
+include::internals.asciidoc[Internals]
diff --git a/guide/embedded.md b/doc/src/guide/embedded.asciidoc
index 6cac064..593a807 100644
--- a/guide/embedded.md
+++ b/doc/src/guide/embedded.asciidoc
@@ -1,16 +1,11 @@
-Embedded mode
-=============
-
-Purpose
--------
+== Embedded mode
Embedded mode allows you to insert Ranch listeners directly
in your supervision tree. This allows for greater fault tolerance
control by permitting the shutdown of a listener due to the
failure of another part of the application and vice versa.
-Embedding
----------
+=== Embedding
To embed Ranch in your application you can simply add the child specs
to your supervision tree. This can all be done in the `init/1` function
@@ -31,16 +26,19 @@ convenience function.
The following example adds both `ranch_sup` and one listener to another
application's supervision tree.
-``` erlang
+.Embed Ranch directly in your supervision tree
+
+[source,erlang]
+----
init([]) ->
- RanchSupSpec = {ranch_sup, {ranch_sup, start_link, []},
- permanent, 5000, supervisor, [ranch_sup]},
- ListenerSpec = ranch:child_spec(echo, 100,
- ranch_tcp, [{port, 5555}],
- echo_protocol, []
- ),
- {ok, {{one_for_one, 10, 10}, [RanchSupSpec, ListenerSpec]}}.
-```
+ RanchSupSpec = {ranch_sup, {ranch_sup, start_link, []},
+ permanent, 5000, supervisor, [ranch_sup]},
+ ListenerSpec = ranch:child_spec(echo, 100,
+ ranch_tcp, [{port, 5555}],
+ echo_protocol, []
+ ),
+ {ok, {{one_for_one, 10, 10}, [RanchSupSpec, ListenerSpec]}}.
+----
Remember, you can add as many listener child specs as needed, but only
one `ranch_sup` spec!
diff --git a/guide/internals.md b/doc/src/guide/internals.asciidoc
index 03977c1..fa63f1d 100644
--- a/guide/internals.md
+++ b/doc/src/guide/internals.asciidoc
@@ -1,5 +1,4 @@
-Internals
-=========
+== Internals
This chapter may not apply to embedded Ranch as embedding allows you
to use an architecture specific to your application, which may or may
@@ -11,8 +10,7 @@ matter to you. Generic benchmarks found on the web may or may not
be of use to you, you can never know until you benchmark your own
system.
-Architecture
-------------
+=== Architecture
Ranch is an OTP application.
@@ -47,8 +45,7 @@ sockets. Protocol handlers start a new process, which receives socket
ownership, with no requirements on how the code should be written inside
that new process.
-Number of acceptors
--------------------
+=== Number of acceptors
The second argument to `ranch:start_listener/6` is the number of
processes that will be accepting connections. Care should be taken
@@ -71,8 +68,7 @@ is a good solution, as it's big enough to always have acceptors ready
and it's low enough that it doesn't have a negative impact on the
system's performances.
-Platform-specific TCP features
-------------------------------
+=== Platform-specific TCP features
Some socket options are platform-specific and not supported by `inet`.
They can be of interest because they generally are related to
@@ -90,8 +86,9 @@ resources to idle connections.
To enable this mechanism, the following option can be used.
-``` erlang
- {raw, 6, 9, << 30:32/native >>}
-```
+.Using raw transport options
+
+[source,erlang]
+{raw, 6, 9, << 30:32/native >>}
It means go on layer 6, turn on option 9 with the given integer parameter.
diff --git a/guide/introduction.md b/doc/src/guide/introduction.asciidoc
index 9cb5f15..3199fb2 100644
--- a/guide/introduction.md
+++ b/doc/src/guide/introduction.asciidoc
@@ -1,8 +1,4 @@
-Introduction
-============
-
-Purpose
--------
+== Introduction
Ranch is a socket acceptor pool for TCP protocols.
@@ -10,28 +6,20 @@ Ranch aims to provide everything you need to accept TCP connections
with a small code base and low latency while being easy to use directly
as an application or to embed into your own.
-Prerequisites
--------------
+=== Prerequisites
It is assumed the developer already knows Erlang and has some experience
with socket programming and TCP protocols.
-Supported platforms
--------------------
+=== Supported platforms
Ranch is tested and supported on Linux.
-Ranch has been reported to work on other platforms, but we make no
-guarantee that the experience will be safe and smooth. You are advised
-to perform the necessary testing and security audits prior to deploying
-on other platforms.
-
-Ranch is developed for Erlang R15B01 and later versions.
+Ranch is developed for Erlang R15B01+.
Ranch may be compiled on earlier Erlang versions with small source code
modifications but there is no guarantee that it will work as expected.
-Versioning
-----------
+=== Versioning
-Ranch uses [Semantic Versioning 2.0.0](http://semver.org/).
+Ranch uses http://semver.org/[Semantic Versioning 2.0.0]
diff --git a/guide/listeners.md b/doc/src/guide/listeners.asciidoc
index d2f7eed..ef2d49c 100644
--- a/guide/listeners.md
+++ b/doc/src/guide/listeners.asciidoc
@@ -1,8 +1,4 @@
-Listeners
-=========
-
-Purpose
--------
+== Listeners
A listener is a set of processes whose role is to listen on a port
for new connections. It manages a pool of acceptor processes, each
@@ -13,8 +9,7 @@ programming is abstracted through the user of transport handlers.
The listener takes care of supervising all the acceptor and connection
processes, allowing developers to focus on building their application.
-Starting and stopping
----------------------
+=== Starting a listener
Ranch does nothing by default. It is up to the application developer
to request that Ranch listens for connections.
@@ -22,10 +17,11 @@ to request that Ranch listens for connections.
A listener can be started and stopped at will.
When starting a listener, a number of different settings are required:
- * A name to identify it locally and be able to interact with it.
- * The number of acceptors in the pool.
- * A transport handler and its associated options.
- * A protocol handler and its associated options.
+
+* A name to identify it locally and be able to interact with it.
+* The number of acceptors in the pool.
+* A transport handler and its associated options.
+* A protocol handler and its associated options.
Ranch includes both TCP and SSL transport handlers, respectively
`ranch_tcp` and `ranch_ssl`.
@@ -34,38 +30,41 @@ A listener can be started by calling the `ranch:start_listener/6`
function. Before doing so however, you must ensure that the `ranch`
application is started.
-To start the `ranch` application:
+.Starting the Ranch application
-``` erlang
+[source,erlang]
ok = application:start(ranch).
-```
You are then ready to start a listener. Let's call it `tcp_echo`. It will
have a pool of 100 acceptors, use a TCP transport and forward connections
to the `echo_protocol` handler.
-``` erlang
+.Starting a listener for TCP connections on port 5555
+
+[source,erlang]
{ok, _} = ranch:start_listener(tcp_echo, 100,
- ranch_tcp, [{port, 5555}],
- echo_protocol, []
+ ranch_tcp, [{port, 5555}],
+ echo_protocol, []
).
-```
You can try this out by compiling and running the `tcp_echo` example in the
-examples directory. To do so, open a shell in the `examples/tcp_echo/`
-directory and run the following commands:
+examples directory. To do so, open a shell in the 'examples/tcp_echo/'
+directory and run the following command:
+
+.Building and starting a Ranch example
-``` bash
-$ make
-$ ./_rel/bin/tcp_echo console
-```
+[source,bash]
+$ make run
You can then connect to it using telnet and see the echo server reply
everything you send to it. Then when you're done testing, you can use
the `Ctrl+]` key to escape to the telnet command line and type
`quit` to exit.
-```
+.Connecting to the example listener with telnet
+
+[source,bash]
+----
$ telnet localhost 5555
Trying 127.0.0.1...
Connected to localhost.
@@ -78,10 +77,21 @@ It works!
telnet> quit
Connection closed.
-```
+----
+
+=== Stopping a listener
+
+All you need to stop a Ranch listener is to call the
+`ranch:stop_listener/1` function with the listener's name
+as argument. In the previous section we started the listener
+named `tcp_echo`. We can now stop it.
+
+.Stopping a listener
-Default transport options
--------------------------
+[source,erlang]
+ranch:stop_listener(tcp_echo).
+
+=== Default transport options
By default the socket will be set to return `binary` data, with the
options `{active, false}`, `{packet, raw}`, `{reuseaddr, true}` set.
@@ -91,8 +101,7 @@ they can be overriden using `Transport:setopts/2` in the protocol.
It will also set `{backlog, 1024}` and `{nodelay, true}`, which
can be overriden at listener startup.
-Listening on a random port
---------------------------
+=== Listening on a random port
You do not have to specify a specific port to listen on. If you give
the port number 0, or if you omit the port number entirely, Ranch will
@@ -101,16 +110,16 @@ start listening on a random port.
You can retrieve this port number by calling `ranch:get_port/1`. The
argument is the name of the listener you gave in `ranch:start_listener/6`.
-``` erlang
+.Starting a listener for TCP connections on a random port
+
+[source,erlang]
{ok, _} = ranch:start_listener(tcp_echo, 100,
- ranch_tcp, [{port, 0}],
- echo_protocol, []
+ ranch_tcp, [{port, 0}],
+ echo_protocol, []
).
Port = ranch:get_port(tcp_echo).
-```
-Listening on privileged ports
------------------------------
+=== Listening on privileged ports
Some systems limit access to ports below 1024 for security reasons.
This can easily be identified by an `{error, eacces}` error when trying
@@ -123,8 +132,7 @@ We recommend the use of port rewriting for systems with a single server,
and load balancing for systems with multiple servers. Documenting these
solutions is however out of the scope of this guide.
-Accepting connections on an existing socket
--------------------------------------------
+=== Accepting connections on an existing socket
If you want to accept connections on an existing socket, you can use the
`socket` transport option, which should just be the relevant data returned
@@ -141,29 +149,30 @@ in which case the socket is closed. Therefore, to use this feature with SSL
with an erlang release prior to R16, ensure that the SSL socket is opened in a
persistant process.
-Limiting the number of concurrent connections
----------------------------------------------
+=== Limiting the number of concurrent connections
The `max_connections` transport option allows you to limit the number
of concurrent connections. It defaults to 1024. Its purpose is to
prevent your system from being overloaded and ensuring all the
connections are handled optimally.
-``` erlang
+.Customizing the maximum number of concurrent connections
+
+[source,erlang]
{ok, _} = ranch:start_listener(tcp_echo, 100,
- ranch_tcp, [{port, 5555}, {max_connections, 100}],
- echo_protocol, []
+ ranch_tcp, [{port, 5555}, {max_connections, 100}],
+ echo_protocol, []
).
-```
You can disable this limit by setting its value to the atom `infinity`.
-``` erlang
+.Disabling the limit for the number of connections
+
+[source,erlang]
{ok, _} = ranch:start_listener(tcp_echo, 100,
- ranch_tcp, [{port, 5555}, {max_connections, infinity}],
- echo_protocol, []
+ ranch_tcp, [{port, 5555}, {max_connections, infinity}],
+ echo_protocol, []
).
-```
You may not always want connections to be counted when checking for
`max_connections`. For example you might have a protocol where both
@@ -175,9 +184,10 @@ To remove the connection from the count, you must call the
`ranch:remove_connection/1` from within the connection process,
with the name of the listener as the only argument.
-``` erlang
+.Removing a connection from the count of connections
+
+[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.
@@ -186,14 +196,14 @@ 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
listener as first argument and the new value as the second.
-``` erlang
+.Upgrading the maximum number of connections
+
+[source,erlang]
ranch:set_max_connections(tcp_echo, MaxConns).
-```
The change will occur immediately.
-Using a supervisor for connection processes
--------------------------------------------
+=== Using a supervisor for connection processes
Ranch allows you to define the type of process that will be used
for the connection processes. By default it expects a `worker`.
@@ -216,8 +226,7 @@ under the supervisor process so that everything works as intended.
If not, you will most likely experience issues when the supervised
process is stopped.
-Upgrading
----------
+=== Upgrading
Ranch allows you to upgrade the protocol options. This takes effect
immediately and for all subsequent connections.
@@ -226,15 +235,17 @@ To upgrade the protocol options, call `ranch:set_protocol_options/2`
with the name of the listener as first argument and the new options
as the second.
-``` erlang
+.Upgrading the protocol options
+
+[source,erlang]
ranch:set_protocol_options(tcp_echo, NewOpts).
-```
All future connections will use the new options.
You can also retrieve the current options similarly by
calling `ranch:get_protocol_options/1`.
-``` erlang
+.Retrieving the current protocol options
+
+[source,erlang]
Opts = ranch:get_protocol_options(tcp_echo).
-```
diff --git a/guide/parsers.md b/doc/src/guide/parsers.asciidoc
index c38af0c..9eacbfa 100644
--- a/guide/parsers.md
+++ b/doc/src/guide/parsers.asciidoc
@@ -1,11 +1,10 @@
-Writing parsers
-===============
+== Writing parsers
There are three kinds of protocols:
- * Text protocols
- * Schema-less binary protocols
- * Schema-based binary protocols
+* Text protocols
+* Schema-less binary protocols
+* Schema-based binary protocols
This chapter introduces the first two kinds. It will not cover
more advanced topics such as continuations or parser generators.
@@ -17,22 +16,22 @@ time you read from the socket, the data read is appended to the
buffer. What happens next depends on the kind of protocol. We
will only cover the first two.
-Parsing text
-------------
+=== Parsing text
Text protocols are generally line based. This means that we can't
do anything with them until we receive the full line.
A simple way to get a full line is to use `binary:split/{2,3}`.
-``` erlang
+.Using binary:split/2 to get a line of input
+
+[source,erlang]
case binary:split(Buffer, <<"\n">>) of
- [_] ->
- get_more_data(Buffer);
- [Line, Rest] ->
- handle_line(Line, Rest)
+ [_] ->
+ get_more_data(Buffer);
+ [Line, Rest] ->
+ handle_line(Line, Rest)
end.
-```
In the above example, we can have two results. Either there was
a line break in the buffer and we get it split into two parts,
@@ -43,17 +42,18 @@ Next, we need to parse the line. The simplest way is to again
split, here on space. The difference is that we want to split
on all spaces character, as we want to tokenize the whole string.
-``` erlang
+.Using binary:split/3 to split text
+
+[source,erlang]
case binary:split(Line, <<" ">>, [global]) of
- [<<"HELLO">>] ->
- be_polite();
- [<<"AUTH">>, User, Password] ->
- authenticate_user(User, Password);
- [<<"QUIT">>, Reason] ->
- quit(Reason)
- %% ...
+ [<<"HELLO">>] ->
+ be_polite();
+ [<<"AUTH">>, User, Password] ->
+ authenticate_user(User, Password);
+ [<<"QUIT">>, Reason] ->
+ quit(Reason)
+ %% ...
end.
-```
Pretty simple, right? Match on the command name, get the rest
of the tokens in variables and call the respective functions.
@@ -62,8 +62,7 @@ After doing this, you will want to check if there is another
line in the buffer, and handle it immediately if any.
Otherwise wait for more data.
-Parsing binary
---------------
+=== Parsing binary
Binary protocols can be more varied, although most of them are
pretty similar. The first four bytes of a frame tend to be
@@ -76,15 +75,16 @@ And even other times little-endian is used instead of big-endian.
The general idea stays the same though.
-``` erlang
+.Using binary pattern matching to split frames
+
+[source,erlang]
<< Size:32, _/bits >> = Buffer,
case Buffer of
- << Frame:Size/binary, Rest/bits >> ->
- handle_frame(Frame, Rest);
- _ ->
- get_more_data(Buffer)
+ << Frame:Size/binary, Rest/bits >> ->
+ handle_frame(Frame, Rest);
+ _ ->
+ get_more_data(Buffer)
end.
-```
You will then need to parse this frame using binary pattern
matching, and handle it. Then you will want to check if there
diff --git a/guide/protocols.md b/doc/src/guide/protocols.asciidoc
index 0cf0dc1..8060343 100644
--- a/guide/protocols.md
+++ b/doc/src/guide/protocols.asciidoc
@@ -1,14 +1,9 @@
-Protocols
-=========
-
-Purpose
--------
+== Protocols
A protocol handler starts a connection process and defines the
protocol logic executed in this process.
-Writing a protocol handler
---------------------------
+=== Writing a protocol handler
All protocol handlers must implement the `ranch_protocol` behavior
which defines a single callback, `start_link/4`. This callback is
@@ -23,9 +18,10 @@ it must call `ranch:accept_ack/1` 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.
-``` erlang
+.Acknowledge accepting the socket
+
+[source,erlang]
ok = ranch:accept_ack(Ref).
-```
If your protocol code requires specific socket options, you should
set them while initializing your connection process, after
@@ -35,7 +31,10 @@ for that purpose.
Following is the complete protocol code for the example found
in `examples/tcp_echo/`.
-``` erlang
+.Protocol module that echoes everything it receives
+
+[source,erlang]
+----
-module(echo_protocol).
-behaviour(ranch_protocol).
@@ -43,25 +42,24 @@ in `examples/tcp_echo/`.
-export([init/4]).
start_link(Ref, Socket, Transport, Opts) ->
- Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts]),
- {ok, Pid}.
+ Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts]),
+ {ok, Pid}.
init(Ref, Socket, Transport, _Opts = []) ->
- ok = ranch:accept_ack(Ref),
- loop(Socket, Transport).
+ ok = ranch:accept_ack(Ref),
+ loop(Socket, Transport).
loop(Socket, Transport) ->
- case Transport:recv(Socket, 0, 5000) of
- {ok, Data} ->
- Transport:send(Socket, Data),
- loop(Socket, Transport);
- _ ->
- ok = Transport:close(Socket)
- end.
-```
-
-Using gen_server
-----------------
+ case Transport:recv(Socket, 0, 5000) of
+ {ok, Data} ->
+ Transport:send(Socket, Data),
+ loop(Socket, Transport);
+ _ ->
+ ok = Transport:close(Socket)
+ end.
+----
+
+=== Using gen_server
Special processes like the ones that use the `gen_server` or `gen_fsm`
behaviours have the particularity of having their `start_link` call not
@@ -77,7 +75,10 @@ normally (although it must be started with `proc_lib` like all special
processes), then perform any needed operations before falling back into
the normal `gen_server` execution loop.
-``` erlang
+.Use a gen_server for protocol handling
+
+[source,erlang]
+----
-module(my_protocol).
-behaviour(gen_server).
-behaviour(ranch_protocol).
@@ -87,23 +88,26 @@ the normal `gen_server` execution loop.
%% Exports of other gen_server callbacks here.
start_link(Ref, Socket, Transport, Opts) ->
- proc_lib:start_link(?MODULE, init, [Ref, Socket, Transport, Opts]).
+ proc_lib:start_link(?MODULE, init, [Ref, Socket, Transport, Opts]).
init(Ref, Socket, Transport, _Opts = []) ->
- ok = proc_lib:init_ack({ok, self()}),
- %% Perform any required state initialization here.
- ok = ranch:accept_ack(Ref),
- ok = Transport:setopts(Socket, [{active, once}]),
- gen_server:enter_loop(?MODULE, [], {state, Socket, Transport}).
+ ok = proc_lib:init_ack({ok, self()}),
+ %% Perform any required state initialization here.
+ ok = ranch:accept_ack(Ref),
+ ok = Transport:setopts(Socket, [{active, once}]),
+ gen_server:enter_loop(?MODULE, [], {state, Socket, Transport}).
%% Other gen_server callbacks here.
-```
+----
The second method involves triggering a timeout just after `gen_server:init`
ends. If you return a timeout value of `0` then the `gen_server` will call
`handle_info(timeout, _, _)` right away.
-``` erlang
+.Use a gen_server for protocol handling, method 2
+
+[source,erlang]
+----
-module(my_protocol).
-behaviour(gen_server).
-behaviour(ranch_protocol).
@@ -111,11 +115,11 @@ ends. If you return a timeout value of `0` then the `gen_server` will call
%% Exports go here.
init([Ref, Socket, Transport]) ->
- {ok, {state, Ref, Socket, Transport}, 0}.
+ {ok, {state, Ref, Socket, Transport}, 0}.
handle_info(timeout, State={state, Ref, Socket, Transport}) ->
- ok = ranch:accept_ack(Ref),
- ok = Transport:setopts(Socket, [{active, once}]),
- {noreply, State};
+ ok = ranch:accept_ack(Ref),
+ ok = Transport:setopts(Socket, [{active, once}]),
+ {noreply, State};
%% ...
-```
+----
diff --git a/guide/ssl_auth.md b/doc/src/guide/ssl_auth.asciidoc
index f9a4812..39f9c3c 100644
--- a/guide/ssl_auth.md
+++ b/doc/src/guide/ssl_auth.asciidoc
@@ -1,8 +1,6 @@
-SSL client authentication
-=========================
+== SSL client authentication
-Purpose
--------
+=== Purpose
SSL client authentication is a mechanism allowing applications to
identify certificates. This allows your application to make sure that
@@ -19,8 +17,7 @@ non-SSL transports, you need to make sure you are in an SSL context
before attempting to perform an SSL client authentication. This
can be done by checking the return value of `Transport:name/0`.
-Obtaining client certificates
------------------------------
+=== Obtaining client certificates
You can obtain client certificates from various sources. You can
generate them yourself, or you can use a service like CAcert.org
@@ -31,26 +28,27 @@ Following are the steps you need to take to create a CAcert.org
account, generate a certificate and install it in your favorite
browser.
- * Open [CAcert.org](http://cacert.org) in your favorite browser
- * Root Certificate link: install both certificates
- * Join (Register an account)
- * Verify your account (check your email inbox!)
- * Log in
- * Client Certificates: New
- * Follow instructions to create the certificate
- * Install the certificate in your browser
+* Open [CAcert.org](http://cacert.org) in your favorite browser
+* Root Certificate link: install both certificates
+* Join (Register an account)
+* Verify your account (check your email inbox!)
+* Log in
+* Client Certificates: New
+* Follow instructions to create the certificate
+* Install the certificate in your browser
You can optionally save the certificate for later use, for example
to extract the `IssuerID` information as will be detailed later on.
-Transport configuration
------------------------
+=== Transport configuration
The SSL transport does not request a client certificate by default.
You need to specify the `{verify, verify_peer}` option when starting
the listener to enable this behavior.
-``` erlang
+.Configure a listener for SSL authentication
+
+[source,erlang]
{ok, _} = ranch:start_listener(my_ssl, 100,
ranch_ssl, [
{port, SSLPort},
@@ -60,7 +58,6 @@ the listener to enable this behavior.
],
my_protocol, []
).
-```
In this example we set the required `port` and `certfile`, but also
the `cacertfile` containing the CACert.org root certificate, and
@@ -71,20 +68,22 @@ not have a client certificate configured for your domain, then no
certificate will be sent. This allows you to use SSL for more than
just authenticated clients.
-Authentication
---------------
+=== Authentication
To authenticate users, you must first save the certificate information
required. If you have your users' certificate files, you can simply
load the certificate and retrieve the information directly.
-``` erlang
+.Retrieve the issuer ID from a certificate
+
+[source,erlang]
+----
certfile_to_issuer_id(Filename) ->
{ok, Data} = file:read_file(Filename),
[{'Certificate', Cert, not_encrypted}] = public_key:pem_decode(Data),
{ok, IssuerID} = public_key:pkix_issuer_id(Cert, self),
IssuerID.
-```
+----
The `IssuerID` variable contains both the certificate serial number
and the certificate issuer stored in a tuple, so this value alone can
@@ -103,7 +102,10 @@ The following function returns the `IssuerID` or `false` if no client
certificate was found. This snippet is intended to be used from your
protocol code.
-``` erlang
+.Retrieve the issuer ID from the certificate for the current connection
+
+[source,erlang]
+----
socket_to_issuer_id(Socket) ->
case ssl:peercert(Socket) of
{error, no_peercert} ->
@@ -112,7 +114,7 @@ socket_to_issuer_id(Socket) ->
{ok, IssuerID} = public_key:pkix_issuer_id(Cert, self),
IssuerID
end.
-```
+----
You then only need to match the `IssuerID` value to authenticate the
user.
diff --git a/guide/transports.md b/doc/src/guide/transports.asciidoc
index 5c26c51..9195376 100644
--- a/guide/transports.md
+++ b/doc/src/guide/transports.asciidoc
@@ -1,8 +1,4 @@
-Transports
-==========
-
-Purpose
--------
+== Transports
A transport defines the interface to interact with a socket.
@@ -11,13 +7,11 @@ connections, but also for receiving and sending data. Both
passive and active mode are supported, although all sockets
are initialized as passive.
-TCP transport
--------------
+=== TCP transport
The TCP transport is a thin wrapper around `gen_tcp`.
-SSL transport
--------------
+=== SSL transport
The SSL transport is a thin wrapper around `ssl`. It requires
the `crypto`, `asn1`, `public_key` and `ssl` applications
@@ -25,9 +19,10 @@ to be started. When starting an SSL listener, Ranch will attempt
to automatically start them. It will not try to stop them when
the listener is removed, however.
-``` erlang
+.Starting the SSL application
+
+[source,erlang]
ssl:start().
-```
In a proper OTP setting, you will need to make your application
depend on the `crypto`, `public_key` and `ssl` applications.
@@ -38,8 +33,7 @@ and SSL accepts. Errors occurring during the SSL accept phase
are returned as `{error, {ssl_accept, atom()}}` to differentiate
on which socket the problem occurred.
-Sending and receiving data
---------------------------
+=== Sending and receiving data
This section assumes that `Transport` is a valid transport handler
(like `ranch_tcp` or `ranch_ssl`) and `Socket` is a connected
@@ -49,12 +43,15 @@ You can send data to a socket by calling the `Transport:send/2`
function. The data can be given as `iodata()`, which is defined as
`binary() | iolist()`. All the following calls will work:
-``` erlang
+.Sending data to the socket
+
+[source,erlang]
+----
Transport:send(Socket, <<"Ranch is cool!">>).
Transport:send(Socket, "Ranch is cool!").
Transport:send(Socket, ["Ranch", ["is", "cool!"]]).
Transport:send(Socket, ["Ranch", [<<"is">>, "cool!"]]).
-```
+----
You can receive data either in passive or in active mode. Passive mode
means that you will perform a blocking `Transport:recv/3` call, while
@@ -73,9 +70,10 @@ The function will wait for data until it has received exactly this amount.
If you are not expecting a precise size, you can specify 0 which will make
this call return as soon as data was read, regardless of its size.
-``` erlang
+.Receiving data from the socket in passive mode
+
+[source,erlang]
{ok, Data} = Transport:recv(Socket, 0, 5000).
-```
Active mode requires you to inform the socket that you want to receive
data as a message and to write the code to actually receive it.
@@ -88,67 +86,73 @@ flood your process mailbox. It's better to keep the data in the socket
and read it only when required.
Three different messages can be received:
- * `{OK, Socket, Data}`
- * `{Closed, Socket}`
- * `{Error, Socket, Reason}`
+
+* `{OK, Socket, Data}`
+* `{Closed, Socket}`
+* `{Error, Socket, Reason}`
The value of `OK`, `Closed` and `Error` can be different
depending on the transport being used. To be able to properly match
on them you must first call the `Transport:messages/0` function.
-``` erlang
+.Retrieving the transport's active message identifiers
+
+[source,erlang]
{OK, Closed, Error} = Transport:messages().
-```
To start receiving messages you will need to call the `Transport:setopts/2`
function, and do so every time you want to receive data.
-``` erlang
+.Receiving messages from the socket in active mode
+
+[source,erlang]
+----
{OK, Closed, Error} = Transport:messages(),
Transport:setopts(Socket, [{active, once}]),
receive
- {OK, Socket, Data} ->
- io:format("data received: ~p~n", [Data]);
- {Closed, Socket} ->
- io:format("socket got closed!~n");
- {Error, Socket, Reason} ->
- io:format("error happened: ~p~n", [Reason])
+ {OK, Socket, Data} ->
+ io:format("data received: ~p~n", [Data]);
+ {Closed, Socket} ->
+ io:format("socket got closed!~n");
+ {Error, Socket, Reason} ->
+ io:format("error happened: ~p~n", [Reason])
end.
-```
+----
You can easily integrate active sockets with existing Erlang code as all
you really need is just a few more clauses when receiving messages.
-Sending files
--------------
+=== Sending files
As in the previous section it is assumed `Transport` is a valid transport
handler and `Socket` is a connected socket obtained through the listener.
To send a whole file, with name `Filename`, over a socket:
-```erlang
+.Sending a file by filename
+
+[source,erlang]
{ok, SentBytes} = Transport:sendfile(Socket, Filename).
-```
Or part of a file, with `Offset` greater than or equal to 0, `Bytes` number of
bytes and chunks of size `ChunkSize`:
-```erlang
+.Sending part of a file by filename in chunks
+
+[source,erlang]
Opts = [{chunk_size, ChunkSize}],
{ok, SentBytes} = Transport:sendfile(Socket, Filename, Offset, Bytes, Opts).
-```
To improve efficiency when sending multiple parts of the same file it is also
possible to use a file descriptor opened in raw mode:
-```erlang
+.Sending a file opened in raw mode
+
+[source,erlang]
{ok, RawFile} = file:open(Filename, [raw, read, binary]),
{ok, SentBytes} = Transport:sendfile(Socket, RawFile, Offset, Bytes, Opts).
-```
-Writing a transport handler
----------------------------
+=== Writing a transport handler
A transport handler is a module implementing the `ranch_transport` behavior.
It defines a certain number of callbacks that must be written in order to
diff --git a/doc/src/manual/ranch.asciidoc b/doc/src/manual/ranch.asciidoc
new file mode 100644
index 0000000..f2e8a7d
--- /dev/null
+++ b/doc/src/manual/ranch.asciidoc
@@ -0,0 +1,170 @@
+= ranch(3)
+
+== Name
+
+ranch - socket acceptor pool
+
+== Description
+
+The `ranch` module provides functions for starting and
+manipulating Ranch listeners.
+
+== Types
+
+=== max_conns() = non_neg_integer() | infinity
+
+Maximum number of connections allowed on this listener.
+
+This is a soft limit. The actual number of connections
+might be slightly above the limit due to concurrency
+when accepting new connections. Some connections may
+also be removed from this count explicitly by the user
+code.
+
+=== opt()
+
+[source,erlang]
+----
+opt() = {ack_timeout, timeout()}
+ | {connection_type, worker | supervisor}
+ | {max_connections, max_conns()}
+ | {shutdown, timeout() | brutal_kill}
+ | {socket, any()}
+----
+
+Ranch-specific transport options.
+
+These options are not passed on to the transports.
+They are used by Ranch while setting up the listeners.
+
+=== ref() = any()
+
+Unique name used to refer to a listener.
+
+== Option descriptions
+
+None of the options are required.
+
+ack_timeout (5000)::
+ Maximum allowed time for the `ranch:accept_ack/1` call to finish.
+connection_type (worker)::
+ Type of process that will handle the connection.
+max_connections (1024)::
+ Maximum number of active connections. Soft limit. Using `infinity` will disable the limit entirely.
+shutdown (5000)::
+ Maximum allowed time for children to stop on listener shutdown.
+socket::
+ Listening socket opened externally to be used instead of calling `Transport:listen/1`.
+
+== Exports
+
+=== 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.
+
+=== child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) -> supervisor:child_spec()
+
+Ref = ref():: Listener name.
+NbAcceptors = non_neg_integer():: Number of acceptor processes.
+Transport = module():: Transport module.
+TransOpts = any():: Transport options.
+Protocol = module():: Protocol module.
+ProtoOpts = any():: Protocol options.
+
+Return child specifications for a new listener.
+
+This function can be used to embed a listener directly
+in an application instead of letting Ranch handle it.
+
+=== get_max_connections(Ref) -> MaxConns
+
+Ref = ref():: Listener name.
+MaxConns = max_conns():: Current maximum number of connections.
+
+Return the max number of connections allowed for the given listener.
+
+=== get_port(Ref) -> Port
+
+Ref = ref():: Listener name.
+Port = inet:port_number():: Port number used by this listener.
+
+Return the port for the given listener.
+
+=== get_protocol_options(Ref) -> ProtoOpts
+
+Ref = ref():: Listener name.
+ProtoOpts = any():: Current protocol options.
+
+Return the protocol options set for the given listener.
+
+=== remove_connection(Ref) -> ok
+
+Ref = ref():: Listener name.
+
+Do not count this connection when limiting the number of connections.
+
+You can use this function for long-running connection processes
+which spend most of their time idling rather than consuming
+resources. This allows Ranch to accept a lot more connections
+without sacrificing the latency of the system.
+
+This function may only be called from a connection process.
+
+=== set_max_connections(Ref, MaxConns) -> ok
+
+Ref = ref():: Listener name.
+MaxConns = max_conns():: New maximum number of connections.
+
+Set the max number of connections for the given listener.
+
+The change will be applied immediately. If the new value is
+smaller than the previous one, Ranch will not kill the extra
+connections, but will wait for them to terminate properly.
+
+=== set_protocol_options(Ref, ProtoOpts) -> ok
+
+Ref = ref():: Listener name.
+ProtoOpts = any():: New protocol options.
+
+Set the protocol options for the given listener.
+
+The change will be applied immediately for all new connections.
+Old connections will not receive the new options.
+
+=== start_listener(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) -> {ok, pid()} | {error, badarg}
+
+Ref = ref():: Listener name.
+NbAcceptors = non_neg_integer():: Number of acceptor processes.
+Transport = module():: Transport module.
+TransOpts = any():: Transport options.
+Protocol = module():: Protocol module.
+ProtoOpts = any():: Protocol options.
+
+Start listening for connections using the given transport
+and protocol. Returns the pid for this listener's supervisor.
+
+There are additional transport options that apply
+regardless of transport. They allow configuring how the
+connections are supervised, rate limited and more. Please
+consult the previous section for more details.
+
+=== stop_listener(Ref) -> ok | {error, not_found}
+
+Ref = ref():: Listener name.
+
+Stop the given listener.
+
+The listener is stopped gracefully, first by closing the
+listening port, then by stopping the connection processes.
+These processes are stopped according to the `shutdown`
+transport option, which may be set to brutally kill all
+connection processes or give them some time to stop properly.
+
+This function does not return until the listener is
+completely stopped.
diff --git a/manual/ranch_app.md b/doc/src/manual/ranch_app.asciidoc
index 1f9d976..2edfc72 100644
--- a/manual/ranch_app.md
+++ b/doc/src/manual/ranch_app.asciidoc
@@ -1,10 +1,10 @@
-The Ranch Application
-=====================
+= ranch(7)
-Socket acceptor pool for TCP protocols.
+== Name
-Dependencies
-------------
+ranch - Socket acceptor pool for TCP protocols.
+
+== Dependencies
The `ranch` application has no particular dependency required
to start.
@@ -14,15 +14,14 @@ listening for SSL connections. The dependencies are `crypto`,
`asn1`, `public_key` and `ssl`. They are started automatically
if they weren't before.
-Environment
------------
+== Environment
The `ranch` application defines one application environment
configuration parameter.
- - profile (false)
- - When enabled, Ranch will start `eprof` profiling automatically.
+profile (false)::
+ When enabled, Ranch will start `eprof` profiling automatically.
You can use the `ranch_app:profile_output/0` function to stop
-profiling and output the results to the files `procs.profile`
-and `total.profile`. Do not use in production.
+profiling and output the results to the files 'procs.profile'
+and 'total.profile'. Do not use in production.
diff --git a/doc/src/manual/ranch_protocol.asciidoc b/doc/src/manual/ranch_protocol.asciidoc
new file mode 100644
index 0000000..714a82b
--- /dev/null
+++ b/doc/src/manual/ranch_protocol.asciidoc
@@ -0,0 +1,44 @@
+= ranch_protocol(3)
+
+== Name
+
+ranch_protocol - behaviour for protocol modules
+
+== Description
+
+The `ranch_protocol` behaviour defines the interface used
+by Ranch protocols.
+
+== Types
+
+None.
+
+== Callbacks
+
+=== start_link(Ref, Socket, Transport, ProtoOpts) -> {ok, pid()} | {ok, pid(), pid()}
+
+Ref = ranch:ref():: Listener name.
+Socket = any():: Socket for this connection.
+Transport = module():: Transport module for this socket.
+ProtoOpts = any():: Protocol options.
+
+Start a new connection process for the given socket.
+
+The only purpose of this callback is to start a process that
+will handle the socket. It must spawn the process, link and
+then return the new pid. This function will always be called
+from inside a supervisor.
+
+This callback can also return two pids. The first pid is the
+pid of the process that will be supervised. The second pid is
+the pid of the process that will receive ownership of the
+socket. This second process must be a child of the first. This
+form is only available when `connection_type` is set to
+`supervisor`.
+
+If any other value is returned, the supervisor will close the
+socket and assume no process has been started.
+
+Do not perform any operations in this callback, as this would
+block the supervisor responsible for starting connection
+processes and degrade performance severely.
diff --git a/doc/src/manual/ranch_ssl.asciidoc b/doc/src/manual/ranch_ssl.asciidoc
new file mode 100644
index 0000000..55accad
--- /dev/null
+++ b/doc/src/manual/ranch_ssl.asciidoc
@@ -0,0 +1,142 @@
+= ranch_ssl(3)
+
+== Name
+
+ranch_ssl - SSL transport module
+
+== Description
+
+The `ranch_ssl` module implements an SSL Ranch transport.
+
+== Types
+
+=== ssl_opt()
+
+[source,erlang]
+----
+ssl_opt() = {alpn_preferred_protocols, [binary()]}
+ | {cacertfile, string()}
+ | {cacerts, [public_key:der_encoded()]}
+ | {cert, public_key:der_encoded()}
+ | {certfile, string()}
+ | {ciphers, [ssl:erl_cipher_suite()] | string()}
+ | {client_renegotiation, boolean()}
+ | {crl_cache, {module(), {internal | any(), list()}}}
+ | {crl_check, boolean() | peer | best_effort}
+ | {depth, 0..255}
+ | {dh, public_key:der_encoded()}
+ | {dhfile, string()}
+ | {fail_if_no_peer_cert, boolean()}
+ | {hibernate_after, integer() | undefined}
+ | {honor_cipher_order, boolean()}
+ | {key, {'RSAPrivateKey' | 'DSAPrivateKey' | 'PrivateKeyInfo', public_key:der_encoded()}}
+ | {keyfile, string()}
+ | {log_alert, boolean()}
+ | {next_protocols_advertised, [binary()]}
+ | {partial_chain, fun(([public_key:der_encoded()]) -> {trusted_ca, public_key:der_encoded()} | unknown_ca)}
+ | {password, string()}
+ | {psk_identity, string()}
+ | {reuse_session, fun()}
+ | {reuse_sessions, boolean()}
+ | {secure_renegotiate, boolean()}
+ | {sni_fun, fun()}
+ | {sni_hosts, [{string(), ssl_opt()}]}
+ | {user_lookup_fun, {fun(), any()}}
+ | {verify, ssl:verify_type()}
+ | {verify_fun, {fun(), any()}}
+ | {versions, [atom()]}.
+----
+
+SSL-specific listen options.
+
+=== opt() = ranch_tcp:opt() | ssl_opt()
+
+Listen options.
+
+=== opts() = [opt()]
+
+List of listen options.
+
+== Option descriptions
+
+Specifying a certificate is mandatory, either through the `cert`
+or the `certfile` option. None of the other options are required.
+
+The default value is given next to the option name.
+
+alpn_preferred_protocols::
+ Perform Application-Layer Protocol Negotiation with the given list of preferred protocols.
+cacertfile::
+ Path to PEM encoded trusted certificates file used to verify peer certificates.
+cacerts::
+ List of DER encoded trusted certificates.
+cert::
+ DER encoded user certificate.
+certfile::
+ Path to the PEM encoded user certificate file. May also contain the private key.
+ciphers::
+ List of ciphers that clients are allowed to use.
+client_renegotiation (true)::
+ Whether to allow client-initiated renegotiation.
+crl_cache ({ssl_crl_cache, {internal, []}})::
+ Customize the module used to cache Certificate Revocation Lists.
+crl_check (false)::
+ Whether to perform CRL check on all certificates in the chain during validation.
+depth (1)::
+ Maximum of intermediate certificates allowed in the certification path.
+dh::
+ DER encoded Diffie-Hellman parameters.
+dhfile::
+ Path to the PEM encoded Diffie-Hellman parameters file.
+fail_if_no_peer_cert (false)::
+ Whether to refuse the connection if the client sends an empty certificate.
+hibernate_after (undefined)::
+ Time in ms after which SSL socket processes go into hibernation to reduce memory usage.
+honor_cipher_order (false)::
+ If true, use the server's preference for cipher selection. If false, use the client's preference.
+key::
+ DER encoded user private key.
+keyfile::
+ Path to the PEM encoded private key file, if different than the certfile.
+log_alert (true)::
+ If false, error reports will not be displayed.
+next_protocols_advertised::
+ List of protocols to send to the client if it supports the Next Protocol extension.
+nodelay (true)::
+ Whether to enable TCP_NODELAY.
+partial_chain::
+ Claim an intermediate CA in the chain as trusted.
+password::
+ Password to the private key file, if password protected.
+psk_identity::
+ Provide the given PSK identity hint to the client during the handshake.
+reuse_session::
+ Custom policy to decide whether a session should be reused.
+reuse_sessions (false)::
+ Whether to allow session reuse.
+secure_renegotiate (false)::
+ Whether to reject renegotiation attempts that do not conform to RFC5746.
+sni_fun::
+ Function called when the client requests a host using Server Name Indication. Returns options to apply.
+sni_hosts::
+ Options to apply for the host that matches what the client requested with Server Name Indication.
+user_lookup_fun::
+ Function called to determine the shared secret when using PSK, or provide parameters when using SRP.
+verify (verify_none)::
+ Use `verify_peer` to request a certificate from the client.
+verify_fun::
+ Custom policy to decide whether a client certificate is valid.
+versions::
+ TLS protocol versions that will be supported.
+
+Note that the client will not send a certificate unless the
+value for the `verify` option is set to `verify_peer`. This
+means that the `fail_if_no_peer_cert` only apply when combined
+with the `verify` option. The `verify_fun` option allows
+greater control over the client certificate validation.
+
+The options `sni_fun` and `sni_hosts` are mutually exclusive.
+
+== Exports
+
+None.
diff --git a/doc/src/manual/ranch_tcp.asciidoc b/doc/src/manual/ranch_tcp.asciidoc
new file mode 100644
index 0000000..1fc268d
--- /dev/null
+++ b/doc/src/manual/ranch_tcp.asciidoc
@@ -0,0 +1,123 @@
+= ranch_tcp(3)
+
+== Name
+
+ranch_tcp - TCP transport module
+
+== Description
+
+The `ranch_tcp` module implements a TCP Ranch transport.
+
+Note that due to bugs in OTP up to at least R16B02, it is
+recommended to disable async threads when using the
+`sendfile` function of this transport, as it can make
+the threads stuck indefinitely.
+
+== Types
+
+=== opt()
+
+[source,erlang]
+----
+opt() = {backlog, non_neg_integer()}
+ | {buffer, non_neg_integer()}
+ | {delay_send, boolean()}
+ | {dontroute, boolean()}
+ | {exit_on_close, boolean()}
+ | {fd, non_neg_integer()}
+ | {high_msgq_watermark, non_neg_integer()}
+ | {high_watermark, non_neg_integer()}
+ | inet
+ | inet6
+ | {ip, inet:ip_address()}
+ | {keepalive, boolean()}
+ | {linger, {boolean(), non_neg_integer()}}
+ | {low_msgq_watermark, non_neg_integer()}
+ | {low_watermark, non_neg_integer()}
+ | {nodelay, boolean()}
+ | {port, inet:port_number()}
+ | {priority, integer()}
+ | {raw, non_neg_integer(), non_neg_integer(), binary()}
+ | {recbuf, non_neg_integer()}
+ | {send_timeout, timeout()}
+ | {send_timeout_close, boolean()}
+ | {sndbuf, non_neg_integer()}
+ | {tos, integer()}
+----
+
+Listen options.
+
+This does not represent the entirety of the options that can
+be set on the socket, but only the options that may be
+set independently of protocol implementation.
+
+=== opts() = [opt()]
+
+List of listen options.
+
+Option descriptions
+-------------------
+
+None of the options are required.
+
+Please consult the `gen_tcp` and `inet` manuals for a more
+thorough description of these options. This manual only aims
+to provide a short description along with what the defaults
+are. Defaults may be different in Ranch compared to `gen_tcp`.
+Defaults are given next to the option name.
+
+backlog (1024)::
+ Max length of the queue of pending connections.
+buffer::
+ Size of the buffer used by the Erlang driver. Default is system-dependent.
+delay_send (false)::
+ Always queue packets before sending, to send fewer, larger packets over the network.
+dontroute (false)::
+ Don't send via a gateway, only send to directly connected hosts.
+exit_on_close (true)::
+ Disable to allow sending data after a close has been detected.
+fd::
+ File descriptor of the socket, if it was opened externally.
+high_msgq_watermark (8192)::
+ Limit in the amount of data in the socket message queue before the socket queue becomes busy.
+high_watermark (8192)::
+ Limit in the amount of data in the ERTS socket implementation's queue before the socket becomes busy.
+inet::
+ Set up the socket for IPv4.
+inet6::
+ Set up the socket for IPv6.
+ip::
+ Interface to listen on. Listen on all interfaces by default.
+keepalive (false)::
+ Enable sending of keep-alive messages.
+linger ({false, 0})::
+ Whether to wait and how long to flush data sent before closing the socket.
+low_msgq_watermark (4096)::
+ Amount of data in the socket message queue before the socket queue leaves busy state.
+low_watermark (4096)::
+ Amount of data in the ERTS socket implementation's queue before the socket leaves busy state.
+nodelay (true)::
+ Whether to enable TCP_NODELAY.
+port (0)::
+ TCP port number to listen on. 0 means a random port will be used.
+priority (0)::
+ Priority value for all packets to be sent by this socket.
+recbuf::
+ Minimum size of the socket's receive buffer. Default is system-dependent.
+send_timeout (30000)::
+ How long the send call may wait for confirmation before returning.
+send_timeout_close (true)::
+ Whether to close the socket when the confirmation wasn't received.
+sndbuf::
+ Minimum size of the socket's send buffer. Default is system-dependent.
+tos::
+ Value for the IP_TOS IP level option. Use with caution.
+
+In addition, the `raw` option can be used to set system-specific
+options by specifying the protocol level, the option number and
+the actual option value specified as a binary. This option is not
+portable. Use with caution.
+
+== Exports
+
+None.
diff --git a/doc/src/manual/ranch_transport.asciidoc b/doc/src/manual/ranch_transport.asciidoc
new file mode 100644
index 0000000..a9322f4
--- /dev/null
+++ b/doc/src/manual/ranch_transport.asciidoc
@@ -0,0 +1,194 @@
+= ranch_transport(3)
+
+== Name
+
+ranch_transport - behaviour for transport modules
+
+== Description
+
+The `ranch_transport` behaviour defines the interface used
+by Ranch transports.
+
+== Types
+
+=== sendfile_opts() = [{chunk_size, non_neg_integer()}]
+
+Options used by the sendfile function and callbacks.
+
+Allows configuring the chunk size, in bytes. Defaults to 8191 bytes.
+
+== Callbacks
+
+=== accept(LSocket, Timeout) -> {ok, CSocket} | {error, closed | timeout | atom()}
+
+LSocket = CSocket = any():: Listening socket.
+Timeout = timeout():: Accept timeout.
+
+Accept a connection on the given listening socket.
+
+The `accept_ack` 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.
+
+Close the given socket.
+
+=== controlling_process(Socket, Pid) -> ok | {error, closed | not_owner | atom()}
+
+Socket = any():: Socket opened with listen/1 or accept/2.
+Pid = pid():: Pid of the new owner of the socket.
+
+Change the controlling process for the given socket.
+
+The controlling process is the process that is allowed to
+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.
+
+=== listen(TransOpts) -> {ok, LSocket} | {error, atom()}
+
+TransOpts = any():: Transport options.
+LSocket = any():: Listening socket.
+
+Listen for connections on the given port.
+
+The port is given as part of the transport options under
+the key `port`. Any other option is transport dependent.
+
+The socket returned by this call can then be used to
+accept connections. It is not possible to send or receive
+data from the listening socket.
+
+=== messages() -> {OK, Closed, Error}
+
+OK = Closed = Error = atom():: Tuple names.
+
+Return the atoms used to identify messages sent in active mode.
+
+=== name() -> Name
+
+Name = atom():: Transport module name.
+
+Return the name of the transport.
+
+=== peername(CSocket) -> {ok, {IP, Port}} | {error, atom()}
+
+CSocket = any():: Socket for this connection.
+IP = inet:ip_address():: IP of the remote endpoint.
+Port = inet:port_number():: Port of the remote endpoint.
+
+Return the IP and port of the remote endpoint.
+
+=== recv(CSocket, Length, Timeout) -> {ok, Packet} | {error, closed | timeout | atom()}
+
+CSocket = any():: Socket for this connection.
+Length = non_neg_integer():: Requested length.
+Timeout = timeout():: Receive timeout.
+Packet = iodata() | any():: Data received.
+
+Receive data from the given socket when in passive mode.
+
+Trying to receive data from a socket that is in active mode
+will return an error.
+
+A length of 0 will return any data available on the socket.
+
+While it is possible to use the timeout value `infinity`,
+this is highly discouraged as this could cause your process
+to get stuck waiting for data that will never come. This may
+happen when a socket becomes half-open due to a crash of the
+remote endpoint. Wi-Fi going down is another common culprit
+of this issue.
+
+=== send(CSocket, Packet) -> ok | {error, atom()}
+
+CSocket = any():: Socket for this connection.
+Packet = iodata():: Data to be sent.
+
+Send data to the given socket.
+
+=== sendfile(CSocket, File) -> sendfile(CSocket, File, 0, 0, [])
+
+Alias of `ranch_transport:sendfile/5`.
+
+=== sendfile(CSocket, File, Offset, Bytes) -> sendfile(CSocket, File, Offset, Bytes, [])
+
+Alias of `ranch_transport:sendfile/5`.
+
+=== sendfile(CSocket, File, Offset, Bytes, SfOpts) -> {ok, SentBytes} | {error, atom()}
+
+CSocket = any():: Socket for this connection.
+File = file:filename_all() | file:fd():: Filename or file descriptor for the file to be sent.
+Offset = non_neg_integer():: Begin sending at this position in the file.
+Bytes = non_neg_integer():: Send this many bytes.
+SentBytes = non_neg_integer():: This many bytes were sent.
+SfOpts = sendfile_opts():: Sendfile options.
+
+Send data from a file to the given socket.
+
+The file may be sent full or in parts, and may be specified
+by its filename or by an already open file descriptor.
+
+Transports that manipulate TCP directly may use the
+`file:sendfile/{2,4,5}` function, which calls the sendfile
+syscall where applicable (on Linux, for example). Other
+transports can use the `sendfile/6` function exported from
+this module.
+
+=== setopts(CSocket, SockOpts) -> ok | {error, atom()}
+
+CSocket = any():: Socket for this connection.
+SockOpts = any():: Socket options.
+
+Change options for the given socket.
+
+This is mainly useful for switching to active or passive mode
+or to set protocol-specific options.
+
+=== shutdown(CSocket, How) -> ok | {error, atom()}
+
+CSocket = any():: Socket for this connection.
+How = read | write | read_write:: Which side(s) of the socket to close.
+
+Immediately close the socket in one or two directions.
+
+=== sockname(Socket) -> {ok, {IP, Port}} | {error, atom()}
+
+Socket = any():: Socket opened with listen/1 or accept/2.
+IP = inet:ip_address():: IP of the local endpoint.
+Port = inet:port_number():: Port of the local endpoint.
+
+Return the IP and port of the local endpoint.
+
+== Exports
+
+=== sendfile(Transport, CSocket, File, Offset, Bytes, SfOpts) -> {ok, SentBytes} | {error, atom()}
+
+Transport = module():: Transport module for this socket.
+CSocket = any():: Socket for this connection.
+File = file:filename_all() | file:fd():: Filename or file descriptor for the file to be sent.
+Offset = non_neg_integer():: Begin sending at this position in the file.
+Bytes = non_neg_integer():: Send this many bytes.
+SentBytes = non_neg_integer():: This many bytes were sent.
+SfOpts = sendfile_opts():: Sendfile options.
+
+Send data from a file to the given socket.
+
+This function emulates the function `file:sendfile/{2,4,5}`
+and may be used when transports are not manipulating TCP
+directly.
diff --git a/guide/toc.md b/guide/toc.md
deleted file mode 100644
index 4f17a22..0000000
--- a/guide/toc.md
+++ /dev/null
@@ -1,25 +0,0 @@
-Ranch User Guide
-================
-
-The Ranch User Guide explores how to make best use of Ranch
-for writing powerful TCP applications.
-
-Introducing Ranch
------------------
-
- * [Introduction](introduction.md)
-
-Using Ranch
------------
-
- * [Listeners](listeners.md)
- * [Transports](transports.md)
- * [Protocols](protocols.md)
- * [Writing parsers](parsers.md)
-
-Advanced topics
----------------
-
- * [SSL client authentication](ssl_auth.md)
- * [Embedded mode](embedded.md)
- * [Internals](internals.md)
diff --git a/manual/ranch.md b/manual/ranch.md
deleted file mode 100644
index 52c792e..0000000
--- a/manual/ranch.md
+++ /dev/null
@@ -1,182 +0,0 @@
-ranch
-=====
-
-The `ranch` module provides functions for starting and
-manipulating Ranch listeners.
-
-Types
------
-
-### max_conns() = non_neg_integer() | infinity
-
-> Maximum number of connections allowed on this listener.
->
-> This is a soft limit. The actual number of connections
-> might be slightly above the limit due to concurrency
-> when accepting new connections. Some connections may
-> also be removed from this count explicitly by the user
-> code.
-
-### opt() = {ack_timeout, timeout()}
- | {connection_type, worker | supervisor}
- | {max_connections, max_conns()}
- | {shutdown, timeout() | brutal_kill}
- | {socket, any()}
-
-> Ranch-specific transport options.
->
-> These options are not passed on to the transports.
-> They are used by Ranch while setting up the listeners.
-
-### ref() = any()
-
-> Unique name used to refer to a listener.
-
-Exports
--------
-
-### accept_ack(Ref) -> ok
-
-> Types:
-> * Ref = ref()
->
-> 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.
-
-### child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
- -> supervisor:child_spec()
-
-> Types:
-> * Ref = ref()
-> * NbAcceptors = non_neg_integer()
-> * Transport = module()
-> * TransOpts = any()
-> * Protocol = module()
-> * ProtoOpts = any()
->
-> Return child specifications for a new listener.
->
-> This function can be used to embed a listener directly
-> in an application instead of letting Ranch handle it.
-
-### get_max_connections(Ref) -> MaxConns
-
-> Types:
-> * Ref = ref()
-> * MaxConns = max_conns()
->
-> Return the max number of connections allowed for the given listener.
-
-### get_port(Ref) -> Port
-
-> Types:
-> * Ref = ref()
-> * Port = inet:port_number()
->
-> Return the port for the given listener.
-
-### get_protocol_options(Ref) -> ProtoOpts
-
-> Types:
-> * Ref = ref()
-> * ProtoOpts = any()
->
-> Return the protocol options set for the given listener.
-
-### remove_connection(Ref) -> ok
-
-> Types:
-> * Ref = ref()
->
-> Do not count this connection when limiting the number of connections.
->
-> You can use this function for long-running connection processes
-> which spend most of their time idling rather than consuming
-> resources. This allows Ranch to accept a lot more connections
-> without sacrificing the latency of the system.
->
-> This function may only be called from a connection process.
-
-### set_max_connections(Ref, MaxConns) -> ok
-
-> Types:
-> * Ref = ref()
-> * MaxConns = max_conns()
->
-> Set the max number of connections for the given listener.
->
-> The change will be applied immediately. If the new value is
-> smaller than the previous one, Ranch will not kill the extra
-> connections, but will wait for them to terminate properly.
-
-### set_protocol_options(Ref, ProtoOpts) -> ok
-
-> Types:
-> * Ref = ref()
-> * ProtoOpts = any()
->
-> Set the protocol options for the given listener.
->
-> The change will be applied immediately for all new connections.
-> Old connections will not receive the new options.
-
-### start_listener(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
- -> {ok, pid()} | {error, badarg}
-
-> Types:
-> * Ref = ref()
-> * NbAcceptors = non_neg_integer()
-> * Transport = module()
-> * TransOpts = any()
-> * Protocol = module()
-> * ProtoOpts = any()
->
-> Start listening for connections using the given transport
-> and protocol. Returns the pid for this listener's supervisor.
->
-> There are five additional transport options that apply
-> regardless of transport. They allow configuring how the
-> connections are supervised, rate limited and allow using
-> an already open listening socket.
->
-> The `ack_timeout` option defines how long post-accept socket
-> initialization should take at a maximum. It defaults to `5000`.
->
-> The `connection_type` option defines the type of process
-> that will handle the connection. It can be either `worker`
-> or `supervisor`. It defaults to `worker`.
->
-> The `max_connections` option determines how many active
-> connections are allowed before Ranch starts throttling
-> the accept rate. This is a soft limit. It defaults to `1024`.
-> Using the value `infinity` will disable this functionality
-> entirely.
->
-> The `shutdown` option determines the policy used with
-> regards to connection processes when shutting down the listener.
-> It can be either a positive integer indicating the max number
-> of ms the supervisor will wait before forcibly killing the
-> children, or the atom `brutal_kill`. It defaults to `5000`.
->
-> The `socket` option allow passing an already open listening
-> socket. In this case, Ranch will not call `Transport:listen/1`
-> and so none of the transport specific options apply.
-
-### stop_listener(Ref) -> ok | {error, not_found}
-
-> Types:
-> * Ref = ref()
->
-> Stop the given listener.
->
-> The listener is stopped gracefully, first by closing the
-> listening port, then by stopping the connection processes.
-> These processes are stopped according to the `shutdown`
-> transport option, which may be set to brutally kill all
-> connection processes or give them some time to stop properly.
->
-> This function does not return until the listener is
-> completely stopped.
diff --git a/manual/ranch_protocol.md b/manual/ranch_protocol.md
deleted file mode 100644
index 807d20a..0000000
--- a/manual/ranch_protocol.md
+++ /dev/null
@@ -1,42 +0,0 @@
-ranch_protocol
-==============
-
-The `ranch_protocol` behaviour defines the interface used
-by Ranch protocols.
-
-Types
------
-
-None.
-
-Callbacks
----------
-
-### start_link(Ref, Socket, Transport, ProtoOpts) -> {ok, pid()} | {ok, pid(), pid()}
-
-> Types:
-> * Ref = ranch:ref()
-> * Socket = any()
-> * Transport = module()
-> * ProtoOpts = any()
->
-> Start a new connection process for the given socket.
->
-> The only purpose of this callback is to start a process that
-> will handle the socket. It must spawn the process, link and
-> then return the new pid. This function will always be called
-> from inside a supervisor.
->
-> This callback can also return two pids. The first pid is the
-> pid of the process that will be supervised. The second pid is
-> the pid of the process that will receive ownership of the
-> socket. This second process must be a child of the first. This
-> form is only available when `connection_type` is set to
-> `supervisor`.
->
-> If any other value is returned, the supervisor will close the
-> socket and assume no process has been started.
->
-> Do not perform any operations in this callback, as this would
-> block the supervisor responsible for starting connection
-> processes and degrade performance severely.
diff --git a/manual/ranch_ssl.md b/manual/ranch_ssl.md
deleted file mode 100644
index 13790d6..0000000
--- a/manual/ranch_ssl.md
+++ /dev/null
@@ -1,135 +0,0 @@
-ranch_ssl
-=========
-
-The `ranch_ssl` module implements an SSL Ranch transport.
-
-Types
------
-
-### ssl_opt() = {alpn_preferred_protocols, [binary()]}
- | {cacertfile, string()}
- | {cacerts, [public_key:der_encoded()]}
- | {cert, public_key:der_encoded()}
- | {certfile, string()}
- | {ciphers, [ssl:erl_cipher_suite()] | string()}
- | {client_renegotiation, boolean()}
- | {crl_cache, {module(), {internal | any(), list()}}}
- | {crl_check, boolean() | peer | best_effort}
- | {depth, 0..255}
- | {dh, public_key:der_encoded()}
- | {dhfile, string()}
- | {fail_if_no_peer_cert, boolean()}
- | {hibernate_after, integer() | undefined}
- | {honor_cipher_order, boolean()}
- | {key, {'RSAPrivateKey' | 'DSAPrivateKey' | 'PrivateKeyInfo', public_key:der_encoded()}}
- | {keyfile, string()}
- | {log_alert, boolean()}
- | {next_protocols_advertised, [binary()]}
- | {partial_chain, fun(([public_key:der_encoded()]) -> {trusted_ca, public_key:der_encoded()} | unknown_ca)}
- | {password, string()}
- | {psk_identity, string()}
- | {reuse_session, fun()}
- | {reuse_sessions, boolean()}
- | {secure_renegotiate, boolean()}
- | {sni_fun, fun()}
- | {sni_hosts, [{string(), ssl_opt()}]}
- | {user_lookup_fun, {fun(), any()}}
- | {verify, ssl:verify_type()}
- | {verify_fun, {fun(), any()}}
- | {versions, [atom()]}.
-
-> SSL-specific listen options.
-
-### opt() = ranch_tcp:opt() | ssl_opt()
-
-> Listen options.
-
-### opts() = [opt()]
-
-> List of listen options.
-
-Option descriptions
--------------------
-
-Specifying a certificate is mandatory, either through the `cert`
-or the `certfile` option. None of the other options are required.
-
-The default value is given next to the option name.
-
- - alpn_preferred_protocols
- - Perform Application-Layer Protocol Negotiation with the given list of preferred protocols.
- - cacertfile
- - Path to PEM encoded trusted certificates file used to verify peer certificates.
- - cacerts
- - List of DER encoded trusted certificates.
- - cert
- - DER encoded user certificate.
- - certfile
- - Path to the PEM encoded user certificate file. May also contain the private key.
- - ciphers
- - List of ciphers that clients are allowed to use.
- - client_renegotiation (true)
- - Whether to allow client-initiated renegotiation.
- - crl_cache ({ssl_crl_cache, {internal, []}})
- - Customize the module used to cache Certificate Revocation Lists.
- - crl_check (false)
- - Whether to perform CRL check on all certificates in the chain during validation.
- - depth (1)
- - Maximum of intermediate certificates allowed in the certification path.
- - dh
- - DER encoded Diffie-Hellman parameters.
- - dhfile
- - Path to the PEM encoded Diffie-Hellman parameters file.
- - fail_if_no_peer_cert (false)
- - Whether to refuse the connection if the client sends an empty certificate.
- - hibernate_after (undefined)
- - Time in ms after which SSL socket processes go into hibernation to reduce memory usage.
- - honor_cipher_order (false)
- - If true, use the server's preference for cipher selection. If false, use the client's preference.
- - key
- - DER encoded user private key.
- - keyfile
- - Path to the PEM encoded private key file, if different than the certfile.
- - log_alert (true)
- - If false, error reports will not be displayed.
- - next_protocols_advertised
- - List of protocols to send to the client if it supports the Next Protocol extension.
- - nodelay (true)
- - Whether to enable TCP_NODELAY.
- - partial_chain
- - Claim an intermediate CA in the chain as trusted.
- - password
- - Password to the private key file, if password protected.
- - psk_identity
- - Provide the given PSK identity hint to the client during the handshake.
- - reuse_session
- - Custom policy to decide whether a session should be reused.
- - reuse_sessions (false)
- - Whether to allow session reuse.
- - secure_renegotiate (false)
- - Whether to reject renegotiation attempts that do not conform to RFC5746.
- - sni_fun
- - Function called when the client requests a host using Server Name Indication. Returns options to apply.
- - sni_hosts
- - Options to apply for the host that matches what the client requested with Server Name Indication.
- - user_lookup_fun
- - Function called to determine the shared secret when using PSK, or provide parameters when using SRP.
- - verify (verify_none)
- - Use `verify_peer` to request a certificate from the client.
- - verify_fun
- - Custom policy to decide whether a client certificate is valid.
- - versions
- - TLS protocol versions that will be supported.
-
-Note that the client will not send a certificate unless the
-value for the `verify` option is set to `verify_peer`. This
-means that the `fail_if_no_peer_cert` only apply when combined
-with the `verify` option. The `verify_fun` option allows
-greater control over the client certificate validation.
-
-The options `sni_fun` and `sni_hosts` are mutually exclusive.
-
-Exports
--------
-
-None.
diff --git a/manual/ranch_tcp.md b/manual/ranch_tcp.md
deleted file mode 100644
index c274b0b..0000000
--- a/manual/ranch_tcp.md
+++ /dev/null
@@ -1,115 +0,0 @@
-ranch_tcp
-=========
-
-The `ranch_tcp` module implements a TCP Ranch transport.
-
-Note that due to bugs in OTP up to at least R16B02, it is
-recommended to disable async threads when using the
-`sendfile` function of this transport, as it can make
-the threads stuck indefinitely.
-
-Types
------
-
-### opt() = {backlog, non_neg_integer()}
- | {buffer, non_neg_integer()}
- | {delay_send, boolean()}
- | {dontroute, boolean()}
- | {exit_on_close, boolean()}
- | {fd, non_neg_integer()}
- | {high_msgq_watermark, non_neg_integer()}
- | {high_watermark, non_neg_integer()}
- | inet
- | inet6
- | {ip, inet:ip_address()}
- | {keepalive, boolean()}
- | {linger, {boolean(), non_neg_integer()}}
- | {low_msgq_watermark, non_neg_integer()}
- | {low_watermark, non_neg_integer()}
- | {nodelay, boolean()}
- | {port, inet:port_number()}
- | {priority, integer()}
- | {raw, non_neg_integer(), non_neg_integer(), binary()}
- | {recbuf, non_neg_integer()}
- | {send_timeout, timeout()}
- | {send_timeout_close, boolean()}
- | {sndbuf, non_neg_integer()}
- | {tos, integer()}
-
-> Listen options.
->
-> This does not represent the entirety of the options that can
-> be set on the socket, but only the options that may be
-> set independently of protocol implementation.
-
-### opts() = [opt()]
-
-> List of listen options.
-
-Option descriptions
--------------------
-
-None of the options are required.
-
-Please consult the `gen_tcp` and `inet` manuals for a more
-thorough description of these options. This manual only aims
-to provide a short description along with what the defaults
-are. Defaults may be different in Ranch compared to `gen_tcp`.
-Defaults are given next to the option name.
-
- - backlog (1024)
- - Max length of the queue of pending connections.
- - buffer
- - Size of the buffer used by the Erlang driver. Default is system-dependent.
- - delay_send (false)
- - Always queue packets before sending, to send fewer, larger packets over the network.
- - dontroute (false)
- - Don't send via a gateway, only send to directly connected hosts.
- - exit_on_close (true)
- - Disable to allow sending data after a close has been detected.
- - fd
- - File descriptor of the socket, if it was opened externally.
- - high_msgq_watermark (8192)
- - Limit in the amount of data in the socket message queue before the socket queue becomes busy.
- - high_watermark (8192)
- - Limit in the amount of data in the ERTS socket implementation's queue before the socket becomes busy.
- - inet
- - Set up the socket for IPv4.
- - inet6
- - Set up the socket for IPv6.
- - ip
- - Interface to listen on. Listen on all interfaces by default.
- - keepalive (false)
- - Enable sending of keep-alive messages.
- - linger ({false, 0})
- - Whether to wait and how long to flush data sent before closing the socket.
- - low_msgq_watermark (4096)
- - Amount of data in the socket message queue before the socket queue leaves busy state.
- - low_watermark (4096)
- - Amount of data in the ERTS socket implementation's queue before the socket leaves busy state.
- - nodelay (true)
- - Whether to enable TCP_NODELAY.
- - port (0)
- - TCP port number to listen on. 0 means a random port will be used.
- - priority (0)
- - Priority value for all packets to be sent by this socket.
- - recbuf
- - Minimum size of the socket's receive buffer. Default is system-dependent.
- - send_timeout (30000)
- - How long the send call may wait for confirmation before returning.
- - send_timeout_close (true)
- - Whether to close the socket when the confirmation wasn't received.
- - sndbuf
- - Minimum size of the socket's send buffer. Default is system-dependent.
- - tos
- - Value for the IP_TOS IP level option. Use with caution.
-
-In addition, the `raw` option can be used to set system-specific
-options by specifying the protocol level, the option number and
-the actual option value specified as a binary. This option is not
-portable. Use with caution.
-
-Exports
--------
-
-None.
diff --git a/manual/ranch_transport.md b/manual/ranch_transport.md
deleted file mode 100644
index 7ae3e31..0000000
--- a/manual/ranch_transport.md
+++ /dev/null
@@ -1,205 +0,0 @@
-ranch_transport
-===============
-
-The `ranch_transport` behaviour defines the interface used
-by Ranch transports.
-
-Types
------
-
-### sendfile_opts() = [{chunk_size, non_neg_integer()}]
-
-> Options used by the sendfile function and callbacks.
->
-> Allows configuring the chunk size, in bytes. Defaults to 8191 bytes.
-
-Callbacks
----------
-
-### accept(LSocket, Timeout)
- -> {ok, CSocket} | {error, closed | timeout | atom()}
-
-> Types:
-> * LSocket = CSocket = any()
-> * Timeout = timeout()
->
-> Accept a connection on the given listening socket.
->
-> The `accept_ack` 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
-
-> Types:
-> * CSocket = any()
-> * Timeout = 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(CSocket) -> ok
-
-> Types:
-> * CSocket = any()
->
-> Close the given socket.
-
-### controlling_process(CSocket, Pid)
- -> ok | {error, closed | not_owner | atom()}
-
-> Types:
-> * CSocket = any()
-> * Pid = pid()
->
-> Change the controlling process for the given socket.
->
-> The controlling process is the process that is allowed to
-> 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.
-
-### listen(TransOpts) -> {ok, LSocket} | {error, atom()}
-
-> Types:
-> * TransOpts = any()
-> * LSocket = any()
->
-> Listen for connections on the given port.
->
-> The port is given as part of the transport options under
-> the key `port`. Any other option is transport dependent.
->
-> The socket returned by this call can then be used to
-> accept connections. It is not possible to send or receive
-> data from the listening socket.
-
-### messages() -> {OK, Closed, Error}
-
-> Types:
-> * OK = Closed = Error = atom()
->
-> Return the atoms used to identify messages sent in active mode.
-
-### name() -> Name
-
-> Types:
-> * Name = atom()
->
-> Return the name of the transport.
-
-### peername(CSocket) -> {ok, {IP, Port}} | {error, atom()}
-
-> Types:
-> * CSocket = any()
-> * IP = inet:ip_address()
-> * Port = inet:port_number()
->
-> Return the IP and port of the remote endpoint.
-
-### recv(CSocket, Length, Timeout)
- -> {ok, Packet} | {error, closed | timeout | atom()}
-
-> Types:
-> * CSocket = any()
-> * Length = non_neg_integer()
-> * Timeout = timeout()
-> * Packet = iodata() | any()
->
-> Receive data from the given socket when in passive mode.
->
-> Trying to receive data from a socket that is in active mode
-> will return an error.
->
-> A length of 0 will return any data available on the socket.
->
-> While it is possible to use the timeout value `infinity`,
-> this is highly discouraged as this could cause your process
-> to get stuck waiting for data that will never come. This may
-> happen when a socket becomes half-open due to a crash of the
-> remote endpoint. Wi-Fi going down is another common culprit
-> of this issue.
-
-### send(CSocket, Packet) -> ok | {error, atom()}
-
-> Types:
-> * CSocket = any()
-> * Packet = iodata()
->
-> Send data to the given socket.
-
-### sendfile(CSocket, File)
- -> sendfile(CSocket, File, 0, 0, [])
-### sendfile(CSocket, File, Offset, Bytes)
- -> sendfile(CSocket, File, Offset, Bytes, [])
-### sendfile(CSocket, File, Offset, Bytes, SfOpts)
- -> {ok, SentBytes} | {error, atom()}
-
-> Types:
-> * CSocket = any()
-> * File = file:filename_all() | file:fd()
-> * Offset = non_neg_integer()
-> * Bytes = SentBytes = non_neg_integer()
-> * SfOpts = sendfile_opts()
->
-> Send data from a file to the given socket.
->
-> The file may be sent full or in parts, and may be specified
-> by its filename or by an already open file descriptor.
->
-> Transports that manipulate TCP directly may use the
-> `file:sendfile/{2,4,5}` function, which calls the sendfile
-> syscall where applicable (on Linux, for example). Other
-> transports can use the `sendfile/6` function exported from
-> this module.
-
-### setopts(CSocket, TransOpts) -> ok | {error, atom()}
-
-> Types:
-> * CSocket = any()
-> * TransOpts = any()
->
-> Change transport options for the given socket.
->
-> This is mainly useful for switching to active or passive mode.
-
-### shutdown(CSocket, How) -> ok | {error, atom()}
-
-> Types:
-> * CSocket = any()
-> * How = read | write | read_write
->
-> Immediately close the socket in one or two directions.
-
-### sockname(CSocket) -> {ok, {IP, Port}} | {error, atom()}
-
-> Types:
-> * CSocket = any()
-> * IP = inet:ip_address()
-> * Port = inet:port_number()
->
-> Return the IP and port of the local endpoint.
-
-Exports
--------
-
-### sendfile(Transport, CSocket, File, Offset, Bytes, SfOpts)
- -> {ok, SentBytes} | {error, atom()}
-
-> Types:
-> * Transport = module()
-> * CSocket = any()
-> * File = file:filename_all() | file:fd()
-> * Offset = non_neg_integer()
-> * Bytes = SentBytes = non_neg_integer()
-> * SfOpts = sendfile_opts()
->
-> Send data from a file to the given socket.
->
-> This function emulates the function `file:sendfile/{2,4,5}`
-> and may be used when transports are not manipulating TCP
-> directly.
diff --git a/manual/toc.md b/manual/toc.md
deleted file mode 100644
index af99d14..0000000
--- a/manual/toc.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Ranch Function Reference
-========================
-
-The function reference documents the public interface of Ranch.
-
- * [The Ranch Application](ranch_app.md)
- * [ranch](ranch.md)
- * [ranch_protocol](ranch_protocol.md)
- * [ranch_ssl](ranch_ssl.md)
- * [ranch_tcp](ranch_tcp.md)
- * [ranch_transport](ranch_transport.md)