Skip to content

emqx/quic

Repository files navigation

Quicer

QUIC (Next-generation transport protocol) erlang library.

msquic NIF binding.

Project Status: Preview

Erlang CI License Coverage Status

OS Support

OS Status
Linux Supported
macOS Supported
Windows Help Needed

Add to your project

rebar.config

{deps, [
    {quicer, {git, "https://github.com/qzhuyan/quic.git", {tag, "0.1.0"}}},
    ...

Examples

Ping Pong server and client

Server

application:ensure_all_started(quicer),
Port = 4567,
LOptions = [ {certfile, "cert.pem"}
           , {keyfile,  "key.pem"}
           , {alpn, ["sample"]}
           , {peer_bidi_stream_count, 1}
             ],
{ok, L} = quicer:listen(Port, LOptions),
{ok, Conn} = quicer:accept(L, [], 120000),
{ok, Conn} = quicer:handshake(Conn),
{ok, Stm} = quicer:accept_stream(Conn, []),
receive {quic, <<"ping">>, Stm, _Props} -> ok end,
{ok, 4} = quicer:send(Stm, <<"pong">>),
quicer:close_listener(L).

Client

application:ensure_all_started(quicer),
Port = 4567,
{ok, Conn} = quicer:connect("localhost", Port, [{alpn, ["sample"]}, {verify, none}], 5000),
{ok, Stm} = quicer:start_stream(Conn, []),
{ok, 4} = quicer:send(Stm, <<"ping">>),
receive {quic, <<"pong">>, Stm, _Props} -> ok end,
ok = quicer:close_connection(Conn).

Try connect to Google with QUIC transport

%% Connect to google and disconnect, 
%% You could also tweak the parameters to see how it goes
{ok, Conn} = quicer:connect("google.com", 443, [{alpn, ["h3"]}, 
                            {verify, verify_peer}, 
                            {peer_unidi_stream_count, 3}], 5000),
quicer:shutdown_connection(Conn).

More examples in test dir

refer to test dir.

Documentation

Get Started

  1. Understand the handles and the ownership in Terminology

  2. Then check how to receives the data and signals: Messages

  3. Read more in msquic doc

Offline hex doc

$ make doc
$ firefox doc/index.html

Dependencies

  1. OTP25+
  2. rebar3
  3. cmake3.16+

Build and test

Dev mode

$ make ci

Troubleshooting

Log to stdout

Debug log could be enabled to print to stdout with the envvar QUIC_LOGGING_TYPE=stdout

QUIC_LOGGING_TYPE=stdout make
%% Debug one testcase
QUIC_LOGGING_TYPE=stdout rebar3 ct --suite test/quicer_connection_SUITE.erl --case tc_conn_basic_verify_peer

Decrypt traffic with Wireshark

Client could specify the connect param sslkeylogfile to record tls secrets for wireshark to decrypt.

    {ok, Conn} = quicer:connect(
        "google.com",
        443,
        [
            {verify, verify_peer},
            {sslkeylogfile, "/tmp/SSLKEYLOGFILE"},
            {peer_unidi_stream_count, 3},
            {alpn, ["h3"]}
        ],
        5000
    )

License

Apache License Version 2.0