From 0d5d855da3d0b2d508fae4258b125a3a5ab7b306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 18 Aug 2015 17:15:45 +0200 Subject: Update the list of allowed transport options We are now up to date with regard to transport options we should accept for the listening socket. Documentation of existing options has been updated with regard to recent changes in the OTP docs and type specifications. --- src/ranch.erl | 6 ++++++ src/ranch_ssl.erl | 61 +++++++++++++++++++++++++++++++------------------------ src/ranch_tcp.erl | 45 +++++++++++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/ranch.erl b/src/ranch.erl index fc9bad3..3fbb9a2 100644 --- a/src/ranch.erl +++ b/src/ranch.erl @@ -131,11 +131,17 @@ filter_options(UserOptions, AllowedKeys, DefaultOptions) -> AllowedOptions = filter_user_options(UserOptions, AllowedKeys), lists:foldl(fun merge_options/2, DefaultOptions, AllowedOptions). +%% 2-tuple options. filter_user_options([Opt = {Key, _}|Tail], AllowedKeys) -> case lists:member(Key, AllowedKeys) of true -> [Opt|filter_user_options(Tail, AllowedKeys)]; false -> filter_user_options(Tail, AllowedKeys) end; +%% Special option forms. +filter_user_options([inet|Tail], AllowedKeys) -> + [inet|filter_user_options(Tail, AllowedKeys)]; +filter_user_options([inet6|Tail], AllowedKeys) -> + [inet6|filter_user_options(Tail, AllowedKeys)]; filter_user_options([Opt = {raw, _, _, _}|Tail], AllowedKeys) -> case lists:member(raw, AllowedKeys) of true -> [Opt|filter_user_options(Tail, AllowedKeys)]; diff --git a/src/ranch_ssl.erl b/src/ranch_ssl.erl index acfe38d..305fbb8 100644 --- a/src/ranch_ssl.erl +++ b/src/ranch_ssl.erl @@ -19,6 +19,7 @@ -export([secure/0]). -export([messages/0]). -export([listen/1]). +-export([listen_options/0]). -export([accept/2]). -export([accept_ack/2]). -export([connect/3]). @@ -35,36 +36,40 @@ -export([shutdown/2]). -export([close/1]). --type opt() :: {backlog, non_neg_integer()} +-type ssl_opt() :: {alpn_preferred_protocols, [binary()]} | {cacertfile, string()} - | {cacerts, [Der::binary()]} - | {cert, Der::binary()} + | {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()} - | {ip, inet:ip_address()} - | {key, Der::binary()} + | {key, {'RSAPrivateKey' | 'DSAPrivateKey' | 'PrivateKeyInfo', public_key:der_encoded()}} | {keyfile, string()} - | {linger, {boolean(), non_neg_integer()}} | {log_alert, boolean()} | {next_protocols_advertised, [binary()]} - | {nodelay, boolean()} - | {partial_chain, fun(([Der::binary()]) -> - {trusted_ca, Der::binary()} | unknown_ca)} + | {partial_chain, fun(([public_key:der_encoded()]) -> {trusted_ca, public_key:der_encoded()} | unknown_ca)} | {password, string()} - | {port, inet:port_number()} - | {raw, non_neg_integer(), non_neg_integer(), - non_neg_integer() | binary()} + | {psk_identity, string()} | {reuse_session, fun()} | {reuse_sessions, boolean()} | {secure_renegotiate, boolean()} - | {send_timeout, timeout()} - | {send_timeout_close, boolean()} + | {sni_fun, fun()} + | {sni_hosts, [{string(), ssl_opt()}]} + | {user_lookup_fun, {fun(), any()}} | {verify, ssl:verify_type()} - | {verify_fun, {fun(), InitialUserState::term()}} + | {verify_fun, {fun(), any()}} | {versions, [atom()]}. +-export_type([ssl_opt/0]). + +-type opt() :: ranch_tcp:opt() | ssl_opt(). -export_type([opt/0]). -type opts() :: [opt()]. @@ -84,24 +89,26 @@ listen(Opts) -> true = lists:keymember(cert, 1, Opts) orelse lists:keymember(certfile, 1, Opts), Opts2 = ranch:set_option_default(Opts, backlog, 1024), - Opts3 = ranch:set_option_default(Opts2, send_timeout, 30000), - Opts4 = ranch:set_option_default(Opts3, send_timeout_close, true), - Opts5 = ranch:set_option_default(Opts4, ciphers, unbroken_cipher_suites()), + Opts3 = ranch:set_option_default(Opts2, ciphers, unbroken_cipher_suites()), + Opts4 = ranch:set_option_default(Opts3, nodelay, true), + Opts5 = ranch:set_option_default(Opts4, send_timeout, 30000), + Opts6 = ranch:set_option_default(Opts5, send_timeout_close, true), %% We set the port to 0 because it is given in the Opts directly. %% The port in the options takes precedence over the one in the %% first argument. - ssl:listen(0, ranch:filter_options(Opts5, - [backlog, cacertfile, cacerts, cert, certfile, ciphers, - fail_if_no_peer_cert, hibernate_after, - honor_cipher_order, ip, key, keyfile, linger, - next_protocols_advertised, nodelay, - log_alert, partial_chain, password, port, raw, - reuse_session, reuse_sessions, secure_renegotiate, - send_timeout, send_timeout_close, verify, verify_fun, - versions], + ssl:listen(0, ranch:filter_options(Opts6, listen_options(), [binary, {active, false}, {packet, raw}, {reuseaddr, true}, {nodelay, true}])). +listen_options() -> + [alpn_preferred_protocols, cacertfile, cacerts, cert, certfile, + ciphers, client_renegotiation, crl_cache, crl_check, depth, + dh, dhfile, fail_if_no_peer_cert, hibernate_after, honor_cipher_order, + key, keyfile, log_alert, next_protocols_advertised, partial_chain, + password, psk_identity, reuse_session, reuse_sessions, secure_renegotiate, + sni_fun, sni_hosts, user_lookup_fun, verify, verify_fun, versions + |ranch_tcp:listen_options()]. + -spec accept(ssl:sslsocket(), timeout()) -> {ok, ssl:sslsocket()} | {error, closed | timeout | atom()}. accept(LSocket, Timeout) -> diff --git a/src/ranch_tcp.erl b/src/ranch_tcp.erl index 51b10ba..797dec1 100644 --- a/src/ranch_tcp.erl +++ b/src/ranch_tcp.erl @@ -19,6 +19,7 @@ -export([secure/0]). -export([messages/0]). -export([listen/1]). +-export([listen_options/0]). -export([accept/2]). -export([accept_ack/2]). -export([connect/3]). @@ -36,14 +37,29 @@ -export([close/1]). -type 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()} - | {raw, non_neg_integer(), non_neg_integer(), - non_neg_integer() | binary()} + | {priority, integer()} + | {raw, non_neg_integer(), non_neg_integer(), binary()} + | {recbuf, non_neg_integer()} | {send_timeout, timeout()} - | {send_timeout_close, boolean()}. + | {send_timeout_close, boolean()} + | {sndbuf, non_neg_integer()} + | {tos, integer()}. -export_type([opt/0]). -type opts() :: [opt()]. @@ -60,16 +76,25 @@ messages() -> {tcp, tcp_closed, tcp_error}. -spec listen(opts()) -> {ok, inet:socket()} | {error, atom()}. listen(Opts) -> Opts2 = ranch:set_option_default(Opts, backlog, 1024), - Opts3 = ranch:set_option_default(Opts2, send_timeout, 30000), - Opts4 = ranch:set_option_default(Opts3, send_timeout_close, true), + Opts3 = ranch:set_option_default(Opts2, nodelay, true), + Opts4 = ranch:set_option_default(Opts3, send_timeout, 30000), + Opts5 = ranch:set_option_default(Opts4, send_timeout_close, true), %% We set the port to 0 because it is given in the Opts directly. %% The port in the options takes precedence over the one in the %% first argument. - gen_tcp:listen(0, ranch:filter_options(Opts4, - [backlog, ip, linger, nodelay, port, raw, - send_timeout, send_timeout_close], - [binary, {active, false}, {packet, raw}, - {reuseaddr, true}, {nodelay, true}])). + gen_tcp:listen(0, ranch:filter_options(Opts5, listen_options(), + [binary, {active, false}, {packet, raw}, {reuseaddr, true}])). + +%% 'inet' and 'inet6' are also allowed but they are handled +%% specifically as they do not have 2-tuple equivalents. +%% +%% The 4-tuple 'raw' option is also handled specifically. +listen_options() -> + [backlog, buffer, delay_send, dontroute, exit_on_close, fd, + high_msgq_watermark, high_watermark, ip, + keepalive, linger, low_msgq_watermark, + low_watermark, nodelay, port, priority, recbuf, + send_timeout, send_timeout_close, sndbuf, tos]. -spec accept(inet:socket(), timeout()) -> {ok, inet:socket()} | {error, closed | timeout | atom()}. -- cgit v1.2.3