diff options
Diffstat (limited to 'doc/src/manual')
-rw-r--r-- | doc/src/manual/ranch.asciidoc | 170 | ||||
-rw-r--r-- | doc/src/manual/ranch_app.asciidoc | 27 | ||||
-rw-r--r-- | doc/src/manual/ranch_protocol.asciidoc | 44 | ||||
-rw-r--r-- | doc/src/manual/ranch_ssl.asciidoc | 142 | ||||
-rw-r--r-- | doc/src/manual/ranch_tcp.asciidoc | 123 | ||||
-rw-r--r-- | doc/src/manual/ranch_transport.asciidoc | 194 |
6 files changed, 700 insertions, 0 deletions
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/doc/src/manual/ranch_app.asciidoc b/doc/src/manual/ranch_app.asciidoc new file mode 100644 index 0000000..2edfc72 --- /dev/null +++ b/doc/src/manual/ranch_app.asciidoc @@ -0,0 +1,27 @@ += ranch(7) + +== Name + +ranch - Socket acceptor pool for TCP protocols. + +== Dependencies + +The `ranch` application has no particular dependency required +to start. + +It has optional dependencies that are only required when +listening for SSL connections. The dependencies are `crypto`, +`asn1`, `public_key` and `ssl`. They are started automatically +if they weren't before. + +== Environment + +The `ranch` application defines one application environment +configuration parameter. + +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. 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. |