aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/ngtcp2/README.rst
blob: 5d6990ff25b60fbf8bf5f365e460601f7e55a039 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
ngtcp2
======

"Call it TCP/2.  One More Time."

ngtcp2 project is an effort to implement `RFC9000
<https://datatracker.ietf.org/doc/html/rfc9000>`_ QUIC protocol.

Documentation
-------------

`Online documentation <https://nghttp2.org/ngtcp2/>`_ is available.

Public test server
------------------

The following endpoints are available to try out ngtcp2
implementation:

- https://nghttp2.org:4433
- https://nghttp2.org:4434 (requires address validation token)
- https://nghttp2.org (powered by `nghttpx
  <https://nghttp2.org/documentation/nghttpx.1.html>`_)

  This endpoints sends Alt-Svc header field to clients if it is
  accessed via HTTP/1.1 or HTTP/2 to tell them that HTTP/3 is
  available at UDP 443.

Requirements
------------

The libngtcp2 C library itself does not depend on any external
libraries.  The example client, and server are written in C++20, and
should compile with the modern C++ compilers (e.g., clang >= 11.0, or
gcc >= 11.0).

The following packages are required to configure the build system:

- pkg-config >= 0.20
- autoconf
- automake
- autotools-dev
- libtool

To build sources under the examples directory, libev and nghttp3 are
required:

- libev
- `nghttp3 <https://github.com/ngtcp2/nghttp3>`_ for HTTP/3

To enable `TLS Certificate Compression
<https://datatracker.ietf.org/doc/html/rfc8879>`_ in bsslclient and
bsslserver (BoringSSL (aws-lc) examples client and server), the
following library is required:

- libbrotli-dev >= 1.0.9

ngtcp2 crypto helper library, and client and server under examples
directory require at least one of the following TLS backends:

- `quictls
  <https://github.com/quictls/openssl/tree/OpenSSL_1_1_1w+quic>`_
- GnuTLS >= 3.7.5
- BoringSSL (commit 76968bb3d53982560bcf08bcd0ba3e1865fe15cd);
  or aws-lc >= 1.19.0
- Picotls (commit 89fe56f4d79200a5801a08ed3b6ac8322e01ccd5)
- wolfSSL >= 5.5.0
- LibreSSL >= v3.9.2

Before building from git
------------------------

When build from git, run the following command to pull submodules:

.. code-block:: shell

   $ git submodule update --init

Build with wolfSSL
------------------

.. code-block:: shell

   $ git clone --depth 1 -b v5.7.2-stable https://github.com/wolfSSL/wolfssl
   $ cd wolfssl
   $ autoreconf -i
   $ # For wolfSSL < v5.6.6, append --enable-quic.
   $ ./configure --prefix=$PWD/build \
       --enable-all --enable-aesni --enable-harden --enable-keylog-export \
       --disable-ech
   $ make -j$(nproc)
   $ make install
   $ cd ..
   $ git clone --recursive https://github.com/ngtcp2/nghttp3
   $ cd nghttp3
   $ autoreconf -i
   $ ./configure --prefix=$PWD/build --enable-lib-only
   $ make -j$(nproc) check
   $ make install
   $ cd ..
   $ git clone --recursive https://github.com/ngtcp2/ngtcp2
   $ cd ngtcp2
   $ autoreconf -i
   $ # For Mac users who have installed libev with MacPorts, append
   $ # LIBEV_CFLAGS="-I/opt/local/include" LIBEV_LIBS="-L/opt/local/lib -lev"
   $ ./configure PKG_CONFIG_PATH=$PWD/../wolfssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig \
       --with-wolfssl
   $ make -j$(nproc) check

Build with BoringSSL
--------------------

.. code-block:: shell

   $ git clone https://boringssl.googlesource.com/boringssl
   $ cd boringssl
   $ git checkout 76968bb3d53982560bcf08bcd0ba3e1865fe15cd
   $ cmake -B build -DCMAKE_POSITION_INDEPENDENT_CODE=ON
   $ make -j$(nproc) -C build
   $ cd ..
   $ git clone --recursive https://github.com/ngtcp2/nghttp3
   $ cd nghttp3
   $ autoreconf -i
   $ ./configure --prefix=$PWD/build --enable-lib-only
   $ make -j$(nproc) check
   $ make install
   $ cd ..
   $ git clone --recursive  https://github.com/ngtcp2/ngtcp2
   $ cd ngtcp2
   $ autoreconf -i
   $ # For Mac users who have installed libev with MacPorts, append
   $ # LIBEV_CFLAGS="-I/opt/local/include" LIBEV_LIBS="-L/opt/local/lib -lev"
   $ ./configure PKG_CONFIG_PATH=$PWD/../nghttp3/build/lib/pkgconfig \
       BORINGSSL_LIBS="-L$PWD/../boringssl/build/ssl -lssl -L$PWD/../boringssl/build/crypto -lcrypto" \
       BORINGSSL_CFLAGS="-I$PWD/../boringssl/include" \
       --with-boringssl
   $ make -j$(nproc) check

Build with aws-lc
-----------------

.. code-block:: shell

   $ git clone --depth 1 -b v1.36.1 https://github.com/aws/aws-lc
   $ cd aws-lc
   $ cmake -B build -DDISABLE_GO=ON
   $ make -j$(nproc) -C build
   $ cd ..
   $ git clone --recursive https://github.com/ngtcp2/nghttp3
   $ cd nghttp3
   $ autoreconf -i
   $ ./configure --prefix=$PWD/build --enable-lib-only
   $ make -j$(nproc) check
   $ make install
   $ cd ..
   $ git clone --recursive  https://github.com/ngtcp2/ngtcp2
   $ cd ngtcp2
   $ autoreconf -i
   $ # For Mac users who have installed libev with MacPorts, append
   $ # LIBEV_CFLAGS="-I/opt/local/include" LIBEV_LIBS="-L/opt/local/lib -lev"
   $ ./configure PKG_CONFIG_PATH=$PWD/../nghttp3/build/lib/pkgconfig \
       BORINGSSL_CFLAGS="-I$PWD/../aws-lc/include" \
       BORINGSSL_LIBS="-L$PWD/../aws-lc/build/ssl -lssl -L$PWD/../aws-lc/build/crypto -lcrypto" \
       --with-boringssl
   $ make -j$(nproc) check

Build with libressl
-----------------

.. code-block:: shell

   $ git clone --depth 1 -b v3.9.2 https://github.com/libressl/portable.git libressl
   $ cd libressl
   $ ./autogen.sh
   $ ./configure --prefix=$PWD/build
   $ make -j$(nproc) install
   $ cd ..
   $ git clone --recursive https://github.com/ngtcp2/nghttp3
   $ cd nghttp3
   $ autoreconf -i
   $ ./configure --prefix=$PWD/build --enable-lib-only
   $ make -j$(nproc) check
   $ make install
   $ cd ..
   $ git clone --recursive  https://github.com/ngtcp2/ngtcp2
   $ cd ngtcp2
   $ autoreconf -i
   $ # For Mac users who have installed libev with MacPorts, append
   $ # LIBEV_CFLAGS="-I/opt/homebrew/Cellar/libev/4.33/include" LIBEV_LIBS="-L/opt/homebrew/Cellar/libev/4.33/lib -lev"
   $ ./configure PKG_CONFIG_PATH=$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../libressl/build/lib/pkgconfig
   $ make -j$(nproc) check

Client/Server
-------------

After successful build, the client and server executable should be
found under examples directory.  They talk HTTP/3.

Client
~~~~~~

.. code-block:: shell

   $ examples/wsslclient [OPTIONS] <HOST> <PORT> [<URI>...]

The notable options are:

- ``-d``, ``--data=<PATH>``: Read data from <PATH> and send it to a
  peer.

Server
~~~~~~

.. code-block:: shell

   $ examples/wsslserver [OPTIONS] <ADDR> <PORT> <PRIVATE_KEY_FILE> <CERTIFICATE_FILE>

The notable options are:

- ``-V``, ``--validate-addr``: Enforce stateless address validation.

H09wsslclient/H09wsslserver
---------------------------

There are h09wsslclient and h09wsslserver which speak HTTP/0.9.  They
are written just for `quic-interop-runner
<https://github.com/marten-seemann/quic-interop-runner>`_.  They share
the basic functionalities with HTTP/3 client and server but have less
functions (e.g., h09wsslclient does not have a capability to send
request body, and h09wsslserver does not understand numeric request
path, like /1000).

Resumption and 0-RTT
--------------------

In order to resume a session, a session ticket, and a transport
parameters must be fetched from server.  First, run
examples/wsslclient with --session-file, and --tp-file options which
specify a path to session ticket, and transport parameter files
respectively to save them locally.

Once these files are available, run examples/wsslclient with the same
arguments again.  You will see that session is resumed in your log if
resumption succeeds.  Resuming session makes server's first Handshake
packet pretty small because it does not send its certificates.

To send 0-RTT data, after making sure that resumption works, use -d
option to specify a file which contains data to send.

Token (Not something included in Retry packet)
----------------------------------------------

QUIC server might send a token to client after connection has been
established.  Client can send this token in subsequent connection to
the server.  Server verifies the token and if it succeeds, the address
validation completes and lifts some restrictions on server which might
speed up transfer.  In order to save and/or load a token,
use --token-file option of examples/wsslclient.  The given file is
overwritten if it already exists when storing a token.

Crypto helper library
---------------------

In order to make TLS stack integration less painful, we provide a
crypto helper library which offers the basic crypto operations.

The header file exists under crypto/includes/ngtcp2 directory.

Each library file is built for a particular TLS backend.  The
available crypto helper libraries are:

- libngtcp2_crypto_quictls: Use quictls and libressl as TLS backend
- libngtcp2_crypto_gnutls: Use GnuTLS as TLS backend
- libngtcp2_crypto_boringssl: Use BoringSSL and aws-lc as TLS backend
- libngtcp2_crypto_picotls: Use Picotls as TLS backend
- libngtcp2_crypto_wolfssl: Use wolfSSL as TLS backend

Because BoringSSL and Picotls are an unversioned product, we only
tested their particular revision.  See Requirements section above.

We use Picotls with OpenSSL as crypto backend.

The examples directory contains client and server that are linked to
those crypto helper libraries and TLS backends.  They are only built
if their corresponding crypto helper library is built:

- qtlsclient: quictls(libressl) client
- qtlsserver: quictls(libressl) server
- gtlsclient: GnuTLS client
- gtlsserver: GnuTLS server
- bsslclient: BoringSSL(aws-lc) client
- bsslserver: BoringSSL(aws-lc) server
- ptlsclient: Picotls client
- ptlsserver: Picotls server
- wsslclient: wolfSSL client
- wsslserver: wolfSSL server

QUIC protocol extensions
-------------------------

The library implements the following QUIC protocol extensions:

- `An Unreliable Datagram Extension to QUIC
  <https://datatracker.ietf.org/doc/html/rfc9221>`_
- `Greasing the QUIC Bit
  <https://datatracker.ietf.org/doc/html/rfc9287>`_
- `Compatible Version Negotiation for QUIC
  <https://datatracker.ietf.org/doc/html/rfc9368>`_
- `QUIC Version 2
  <https://datatracker.ietf.org/doc/html/rfc9369>`_

Configuring Wireshark for QUIC
------------------------------

`Wireshark <https://www.wireshark.org/download.html>`_ can be configured to
analyze QUIC traffic using the following steps:

1. Set *SSLKEYLOGFILE* environment variable:

   .. code-block:: shell

      $ export SSLKEYLOGFILE=quic_keylog_file

2. Set the port that QUIC uses

   Go to *Preferences->Protocols->QUIC* and set the port the program
   listens to.  In the case of the example application this would be
   the port specified on the command line.

3. Set Pre-Master-Secret logfile

   Go to *Preferences->Protocols->TLS* and set the *Pre-Master-Secret
   log file* to the same value that was specified for *SSLKEYLOGFILE*.

4. Choose the correct network interface for capturing

   Make sure you choose the correct network interface for
   capturing. For example, if using localhost choose the *loopback*
   network interface on macos.

5. Create a filter

   Create A filter for the udp.port and set the port to the port the
   application is listening to. For example:

   .. code-block:: text

      udp.port == 7777

License
-------

The MIT License

Copyright (c) 2016 ngtcp2 contributors