TLS
An alternative implementation of Erlang TLS layer.
TLS is a NIF-based implementation of the whole TLS stack, built on top of Asio and BoringSSL. It manages its own native threads to asynchronously handle socket operations.
The main (and very important) benefit of using this project instead of Erlang's
built-in ssl is hardware acceleration. ssl2 module achieves an order of
magnitude higher bandwidth when encoding/decoding data.
Currently only TLSv1.2 is supported, and default BoringSSL cipher is used.
Performance
Benchmark ran on OS X 10.11.5, 2,2 GHz Intel Core i7 (4 cores with HT). The benchmark consisted of 10 concurrent connections, each sending 10 messages, each of size 100 MB for a total of 1 GB per connection. The bandwidth has been calculated using time measured between the first message sent and the last message received.
| OTP version | transport | bandwidth |
|---|---|---|
| 18.3 | ssl | 70 MB/s |
| 19.0-rc1 | ssl | 111 MB/s |
| 19.0-rc1 | ssl2 | 833 MB/s |
Build
Dependencies:
cmake>= 3.0.0erlang>= 17.0g++>= 4.9.0gitgolangmakeninja-build
To build the project, simply run make from its directory.
User Guide
Add TLS as a rebar dependency to your project:
{deps, [
{ssl2, "1.0.3", {git, "https://github.com/kzemek/erlang_tls.git", {tag, "1.0.3"}}}
}.
Now you can use ssl2 module much like you would use ssl:
% Server side
application:start(ssl2),
{ok, ListenSocket} =
ssl2:listen(9999, [{certfile, "cert.pem"}, {keyfile, "key.pem"},
{reuseaddr, true}]),
{ok, Socket} = ssl2:accept(ListenSocket),
ssl2:handshake(Socket),
ssl2:setopts(Socket, [{active, once}]),
receive AMessage -> io:format("~p~n", [AMessage]) end.% Client side
application:start(ssl2),
{ok, Socket} = ssl2:connect("localhost", 9999, [], infinity),
ssl2:send(Socket, "foo").Using with Ranch
ssl2 can be easily used with Ranch by starting a
listener with
ranch_ssl2 as the transport module:
{ok, _} = ranch:start_listener(tcp_echo, 100,
ranch_ssl2, [{port, 5555}, {certfile, CertPath}],
echo_protocol, []).APIs
Implemented ssl functions
The following ssl/inet functions are currently implemented:
connect/3connect/4send/2recv/2recv/3listen/2accept/1(ssl:transport_accept/1)accept/2(ssl:transport_accept/2)handshake/1(ssl:accept/1)handshake/2(ssl:accept/2)setopts/2controlling_process/2peername/1sockname/1close/1peercert/1certificate_chain/1(not present inssl)shutdown/2
Implemented ssl options
The following ssl/inet options are currently supported:
{packet, raw | 0 | 1 | 2 | 4}{active, boolean() | once}{exit_on_close, boolean()}{verify_type, verify_none | verify_peer}{fail_if_no_peer_cert, boolean()}{verify_client_once, boolean()}{rfc2818_verification_hostname, str()}{cacerts, [pem_encoded()]}{crls, [pem_encoded()]}{certfile, str()}{keyfile, str()}{chain, [pem_encoded()]}