mirror of
				https://gitea.invidious.io/iv-org/litespeed-quic.git
				synced 2024-08-15 00:53:43 +00:00 
			
		
		
		
	Release 2.12.0
- [FEATURE] QUIC timestamps extension. - [API] New: ea_alpn that is used when not in HTTP mode. - [BUGFIX] SNI is mandatory only for HTTP/3 and gQUIC. - [BUGFIX] Benign double-free -- issue #110. - [BUGFIX] Printing of transport parameters.
This commit is contained in:
		
							parent
							
								
									fa4561dcea
								
							
						
					
					
						commit
						afe3d36359
					
				
					 24 changed files with 279 additions and 34 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,11 @@
 | 
			
		|||
2020-03-02
 | 
			
		||||
    - 2.12.0
 | 
			
		||||
    - [FEATURE] QUIC timestamps extension.
 | 
			
		||||
    - [API] New: ea_alpn that is used when not in HTTP mode.
 | 
			
		||||
    - [BUGFIX] SNI is mandatory only for HTTP/3 and gQUIC.
 | 
			
		||||
    - [BUGFIX] Benign double-free -- issue #110.
 | 
			
		||||
    - [BUGFIX] Printing of transport parameters.
 | 
			
		||||
 | 
			
		||||
2020-02-24
 | 
			
		||||
    - 2.11.1
 | 
			
		||||
    - [FEATURE] QUIC and HTTP/3 Internet Draft 27 support.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -239,7 +239,7 @@ optional members.
 | 
			
		|||
    .. member:: struct ssl_ctx_st *                (*ea_get_ssl_ctx)(void *peer_ctx)
 | 
			
		||||
 | 
			
		||||
        Get SSL_CTX associated with a peer context.  Mandatory in server
 | 
			
		||||
        mode.
 | 
			
		||||
        mode.  This is use for default values for SSL instantiation.
 | 
			
		||||
 | 
			
		||||
    .. member:: const struct lsquic_hset_if         *ea_hsi_if
 | 
			
		||||
    .. member:: void                                *ea_hsi_ctx
 | 
			
		||||
| 
						 | 
				
			
			@ -268,6 +268,8 @@ optional members.
 | 
			
		|||
        In a multi-process setup, it may be useful to observe the CID
 | 
			
		||||
        lifecycle.  This optional set of callbacks makes it possible.
 | 
			
		||||
 | 
			
		||||
.. _apiref-engine-settings:
 | 
			
		||||
 | 
			
		||||
Engine Settings
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +350,7 @@ settings structure:
 | 
			
		|||
    .. member:: unsigned        es_max_header_list_size
 | 
			
		||||
 | 
			
		||||
       This corresponds to SETTINGS_MAX_HEADER_LIST_SIZE
 | 
			
		||||
       (RFC 7540, Section 6.5.2).  0 means no limit.  Defaults
 | 
			
		||||
       (:rfc:`7540#section-6.5.2`).  0 means no limit.  Defaults
 | 
			
		||||
       to :func:`LSQUIC_DF_MAX_HEADER_LIST_SIZE`.
 | 
			
		||||
 | 
			
		||||
    .. member:: const char     *es_ua
 | 
			
		||||
| 
						 | 
				
			
			@ -685,6 +687,12 @@ settings structure:
 | 
			
		|||
 | 
			
		||||
       Default value is :macro:`LSQUIC_DF_DELAYED_ACKS`
 | 
			
		||||
 | 
			
		||||
    .. member:: int             es_timestamps
 | 
			
		||||
 | 
			
		||||
       Enable timestamps extension.  Allowed values are 0 and 1.
 | 
			
		||||
 | 
			
		||||
       Default value is @ref LSQUIC_DF_TIMESTAMPS
 | 
			
		||||
 | 
			
		||||
To initialize the settings structure to library defaults, use the following
 | 
			
		||||
convenience function:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -940,7 +948,7 @@ that the library uses to send packets.
 | 
			
		|||
 | 
			
		||||
    .. member:: int                    ecn
 | 
			
		||||
 | 
			
		||||
        ECN: Valid values are 0 - 3. See RFC 3168.
 | 
			
		||||
        ECN: Valid values are 0 - 3. See :rfc:`3168`.
 | 
			
		||||
 | 
			
		||||
        ECN may be set by IETF QUIC connections if ``es_ecn`` is set.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1465,7 +1473,7 @@ fields yourself.  In that case, the header set must be "read" from the stream vi
 | 
			
		|||
 | 
			
		||||
    Get header set associated with the stream.  The header set is created by
 | 
			
		||||
    ``hsi_create_header_set()`` callback.  After this call, the ownership of
 | 
			
		||||
    the header set is trasnferred to the caller.
 | 
			
		||||
    the header set is transferred to the caller.
 | 
			
		||||
 | 
			
		||||
    This call must precede calls to :func:`lsquic_stream_read()`,
 | 
			
		||||
    :func:`lsquic_stream_readv()`, and :func:`lsquic_stream_readf()`.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,9 @@ copyright = u'2020, LiteSpeed Technologies'
 | 
			
		|||
author = u'LiteSpeed Technologies'
 | 
			
		||||
 | 
			
		||||
# The short X.Y version
 | 
			
		||||
version = u'2.11'
 | 
			
		||||
version = u'2.12'
 | 
			
		||||
# The full version, including alpha/beta/rc tags
 | 
			
		||||
release = u'2.11.1'
 | 
			
		||||
release = u'2.12.0'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# -- General configuration ---------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,2 +1,71 @@
 | 
			
		|||
Getting Started with LSQUIC
 | 
			
		||||
===========================
 | 
			
		||||
Getting Started
 | 
			
		||||
===============
 | 
			
		||||
 | 
			
		||||
Supported Platforms
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
LSQUIC compiles and runs on Linux, FreeBSD, and Mac OS.  It has been
 | 
			
		||||
tested on i386, x86_64, as well as Raspberry Pi.
 | 
			
		||||
 | 
			
		||||
Windows support is on the TODO list.
 | 
			
		||||
 | 
			
		||||
Dependencies
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
LSQUIC library uses:
 | 
			
		||||
 | 
			
		||||
- zlib_;
 | 
			
		||||
- BoringSSL_; and
 | 
			
		||||
- `ls-qpack`_ (as a Git submodule).
 | 
			
		||||
 | 
			
		||||
The accompanying demo command-line tools use libevent_.
 | 
			
		||||
 | 
			
		||||
What's in the box
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
- ``src/liblsquic`` -- the library
 | 
			
		||||
- ``test`` -- demo client and server programs
 | 
			
		||||
- ``test/unittests`` -- unit tests
 | 
			
		||||
 | 
			
		||||
Building
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
To build the library, follow instructions in the README_ file.
 | 
			
		||||
 | 
			
		||||
Demo Examples
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
Fetch Google home page:
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    ./http_client -s www.google.com -p / -o version=Q050
 | 
			
		||||
 | 
			
		||||
Run your own server (it does not touch the filesystem, don't worry):
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    ./http_server -c www.example.com,fullchain.pem,privkey.pem -s 0.0.0.0:4433
 | 
			
		||||
 | 
			
		||||
Grab a page from your server:
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    ./http_client -H www.example.com -s 127.0.0.1:4433 -p /
 | 
			
		||||
 | 
			
		||||
You can play with various options, of which there are many.  Use
 | 
			
		||||
the ``-h`` command-line flag to see them.
 | 
			
		||||
 | 
			
		||||
Next steps
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
If you want to use LSQUIC in your program, check out the :doc:`tutorial` and
 | 
			
		||||
the :doc:`apiref`.
 | 
			
		||||
 | 
			
		||||
:doc:`internals` covers some library internals.
 | 
			
		||||
 | 
			
		||||
.. _zlib: https://www.zlib.net/
 | 
			
		||||
.. _BoringSSL: https://boringssl.googlesource.com/boringssl/
 | 
			
		||||
.. _`ls-qpack`: https://github.com/litespeedtech/ls-qpack
 | 
			
		||||
.. _libevent: https://libevent.org/
 | 
			
		||||
.. _README: https://github.com/litespeedtech/lsquic/blob/master/README.md
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,9 +3,6 @@ LSQUIC Documentation
 | 
			
		|||
 | 
			
		||||
This is the documentation for LSQUIC_ |release|, last updated |today|.
 | 
			
		||||
 | 
			
		||||
Introduction
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
LiteSpeed QUIC (LSQUIC) Library is an open-source implementation of QUIC
 | 
			
		||||
and HTTP/3 functionality for servers and clients.  LSQUIC is:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +35,9 @@ Contents
 | 
			
		|||
   :maxdepth: 2
 | 
			
		||||
 | 
			
		||||
   gettingstarted
 | 
			
		||||
   tutorial
 | 
			
		||||
   apiref
 | 
			
		||||
   internals
 | 
			
		||||
 | 
			
		||||
Indices and tables
 | 
			
		||||
==================
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								docs/internals.rst
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								docs/internals.rst
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
*********
 | 
			
		||||
Internals
 | 
			
		||||
*********
 | 
			
		||||
 | 
			
		||||
Connection Management
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
References to connections can exist in six different places in an
 | 
			
		||||
engine.
 | 
			
		||||
 | 
			
		||||
.. image:: lsquic-engine-conns.png
 | 
			
		||||
							
								
								
									
										1
									
								
								docs/lsquic-engine-conns.drawio
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/lsquic-engine-conns.drawio
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
<mxfile host="www.draw.io" modified="2020-02-21T20:56:15.366Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0" etag="X7KTg7RjNxutHAnzRWEE" version="12.7.3"><diagram id="g-XUBOnqw-Le0S7dI5B8" name="Page-1">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</diagram></mxfile>
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/lsquic-engine-conns.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/lsquic-engine-conns.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 95 KiB  | 
| 
						 | 
				
			
			@ -24,8 +24,8 @@ extern "C" {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#define LSQUIC_MAJOR_VERSION 2
 | 
			
		||||
#define LSQUIC_MINOR_VERSION 11
 | 
			
		||||
#define LSQUIC_PATCH_VERSION 1
 | 
			
		||||
#define LSQUIC_MINOR_VERSION 12
 | 
			
		||||
#define LSQUIC_PATCH_VERSION 0
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Engine flags:
 | 
			
		||||
| 
						 | 
				
			
			@ -205,6 +205,9 @@ struct ssl_st;
 | 
			
		|||
 * constructor.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* `sni' may be NULL if engine is not HTTP mode and client TLS transport
 | 
			
		||||
 * parameters did not include the SNI.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct ssl_ctx_st * (*lsquic_lookup_cert_f)(
 | 
			
		||||
    void *lsquic_cert_lookup_ctx, const struct sockaddr *local, const char *sni);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -330,6 +333,9 @@ typedef struct ssl_ctx_st * (*lsquic_lookup_cert_f)(
 | 
			
		|||
/** Turn off delayed ACKs extension by default */
 | 
			
		||||
#define LSQUIC_DF_DELAYED_ACKS 0
 | 
			
		||||
 | 
			
		||||
/** Turn on timestamp extension by default */
 | 
			
		||||
#define LSQUIC_DF_TIMESTAMPS 1
 | 
			
		||||
 | 
			
		||||
/* 1: Cubic; 2: BBR */
 | 
			
		||||
#define LSQUIC_DF_CC_ALGO 1
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -724,6 +730,13 @@ struct lsquic_engine_settings {
 | 
			
		|||
     * Default value is @ref LSQUIC_DF_DELAYED_ACKS
 | 
			
		||||
     */
 | 
			
		||||
    int             es_delayed_acks;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Enable timestamps extension.  Allowed values are 0 and 1.
 | 
			
		||||
     *
 | 
			
		||||
     * Default value is @ref LSQUIC_DF_TIMESTAMPS
 | 
			
		||||
     */
 | 
			
		||||
    int             es_timestamps;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Initialize `settings' to default values */
 | 
			
		||||
| 
						 | 
				
			
			@ -1312,7 +1325,7 @@ lsquic_stream_send_headers (lsquic_stream_t *s,
 | 
			
		|||
/**
 | 
			
		||||
 * Get header set associated with the stream.  The header set is created by
 | 
			
		||||
 * @ref hsi_create_header_set() callback.  After this call, the ownership of
 | 
			
		||||
 * the header set is trasnferred to the caller.
 | 
			
		||||
 * the header set is transferred to the caller.
 | 
			
		||||
 *
 | 
			
		||||
 * This call must precede calls to @ref lsquic_stream_read() and
 | 
			
		||||
 * @ref lsquic_stream_readv().
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -558,6 +558,8 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
 | 
			
		|||
        params.tp_numerics[TPI_MIN_ACK_DELAY] = 10000;    /* TODO: make into a constant? make configurable? */
 | 
			
		||||
        params.tp_set |= 1 << TPI_MIN_ACK_DELAY;
 | 
			
		||||
    }
 | 
			
		||||
    if (settings->es_timestamps)
 | 
			
		||||
        params.tp_set |= 1 << TPI_TIMESTAMPS;
 | 
			
		||||
 | 
			
		||||
    len = (enc_sess->esi_conn->cn_version == LSQVER_ID25 ? lsquic_tp_encode_id25 :
 | 
			
		||||
        lsquic_tp_encode)(¶ms, enc_sess->esi_flags & ESI_SERVER, buf, bufsz);
 | 
			
		||||
| 
						 | 
				
			
			@ -1035,8 +1037,10 @@ iquic_lookup_cert (SSL *ssl, void *arg)
 | 
			
		|||
#endif
 | 
			
		||||
    if (!server_name)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("cert lookup: server name is not set, skip");
 | 
			
		||||
        return 1;
 | 
			
		||||
        LSQ_DEBUG("cert lookup: server name is not set");
 | 
			
		||||
        /* SNI is required in HTTP/3 */
 | 
			
		||||
        if (enc_sess->esi_enpub->enp_flags & ENPUB_HTTP)
 | 
			
		||||
            return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    path = enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -1049,7 +1053,8 @@ iquic_lookup_cert (SSL *ssl, void *arg)
 | 
			
		|||
    {
 | 
			
		||||
        if (SSL_set_SSL_CTX(enc_sess->esi_ssl, ssl_ctx))
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_DEBUG("looked up cert for %s", server_name);
 | 
			
		||||
            LSQ_DEBUG("looked up cert for %s", server_name
 | 
			
		||||
                                                ? server_name : "<no SNI>");
 | 
			
		||||
            if (enc_sess->esi_enpub->enp_kli)
 | 
			
		||||
                SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
 | 
			
		||||
            SSL_set_verify(enc_sess->esi_ssl,
 | 
			
		||||
| 
						 | 
				
			
			@ -1070,7 +1075,8 @@ iquic_lookup_cert (SSL *ssl, void *arg)
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("could not look up cert for %s", server_name);
 | 
			
		||||
        LSQ_DEBUG("could not look up cert for %s", server_name
 | 
			
		||||
                                                ? server_name : "<no SNI>");
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -335,6 +335,7 @@ lsquic_engine_init_settings (struct lsquic_engine_settings *settings,
 | 
			
		|||
    settings->es_ql_bits         = LSQUIC_DF_QL_BITS;
 | 
			
		||||
    settings->es_spin            = LSQUIC_DF_SPIN;
 | 
			
		||||
    settings->es_delayed_acks    = LSQUIC_DF_DELAYED_ACKS;
 | 
			
		||||
    settings->es_timestamps      = LSQUIC_DF_TIMESTAMPS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1636,7 +1637,7 @@ remove_conn_from_hash (lsquic_engine_t *engine, lsquic_conn_t *conn)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
refflags2str (enum lsquic_conn_flags flags, char s[6])
 | 
			
		||||
refflags2str (enum lsquic_conn_flags flags, char s[7])
 | 
			
		||||
{
 | 
			
		||||
    *s = 'C'; s += !!(flags & LSCONN_CLOSING);
 | 
			
		||||
    *s = 'H'; s += !!(flags & LSCONN_HASHED);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,6 +133,7 @@ enum ifull_conn_flags
 | 
			
		|||
    IFC_MIGRA         = 1 << 27,
 | 
			
		||||
    IFC_SPIN          = 1 << 28, /* Spin bits are enabled */
 | 
			
		||||
    IFC_DELAYED_ACKS  = 1 << 29, /* Delayed ACKs are enabled */
 | 
			
		||||
    IFC_TIMESTAMPS    = 1 << 30, /* Timestamps are enabled */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -334,6 +335,7 @@ struct ietf_full_conn
 | 
			
		|||
    struct transport_params     ifc_peer_param;
 | 
			
		||||
    STAILQ_HEAD(, stream_id_to_ss)
 | 
			
		||||
                                ifc_stream_ids_to_ss;
 | 
			
		||||
    lsquic_time_t               ifc_created;
 | 
			
		||||
    lsquic_time_t               ifc_saved_ack_received;
 | 
			
		||||
    lsquic_packno_t             ifc_max_ack_packno[N_PNS];
 | 
			
		||||
    lsquic_packno_t             ifc_max_non_probing;
 | 
			
		||||
| 
						 | 
				
			
			@ -1215,6 +1217,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
 | 
			
		|||
    LSQ_DEBUG("negotiating version %s",
 | 
			
		||||
                        lsquic_ver2str[conn->ifc_u.cli.ifcli_ver_neg.vn_ver]);
 | 
			
		||||
    conn->ifc_process_incoming_packet = process_incoming_packet_verneg;
 | 
			
		||||
    conn->ifc_created = now;
 | 
			
		||||
    LSQ_DEBUG("logging using %s SCID",
 | 
			
		||||
        LSQUIC_LOG_CONN_ID == CN_SCID(&conn->ifc_conn) ? "client" : "server");
 | 
			
		||||
    return &conn->ifc_conn;
 | 
			
		||||
| 
						 | 
				
			
			@ -1431,6 +1434,7 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
 | 
			
		|||
    if (0 != handshake_ok(&conn->ifc_conn))
 | 
			
		||||
        goto err3;
 | 
			
		||||
 | 
			
		||||
    conn->ifc_created = imc->imc_created;
 | 
			
		||||
    if (conn->ifc_idle_to)
 | 
			
		||||
        lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE,
 | 
			
		||||
                                        imc->imc_created + conn->ifc_idle_to);
 | 
			
		||||
| 
						 | 
				
			
			@ -1506,6 +1510,33 @@ ietf_full_conn_ci_cancel_pending_streams (struct lsquic_conn *lconn, unsigned n)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Best effort.  If timestamp frame does not fit, oh well */
 | 
			
		||||
static void
 | 
			
		||||
generate_timestamp_frame (struct ietf_full_conn *conn,
 | 
			
		||||
                    struct lsquic_packet_out *packet_out, lsquic_time_t now)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t timestamp;
 | 
			
		||||
    int w;
 | 
			
		||||
 | 
			
		||||
    timestamp = (now - conn->ifc_created) >> TP_DEF_ACK_DELAY_EXP;
 | 
			
		||||
    w = conn->ifc_conn.cn_pf->pf_gen_timestamp_frame(
 | 
			
		||||
            packet_out->po_data + packet_out->po_data_sz,
 | 
			
		||||
            lsquic_packet_out_avail(packet_out), timestamp);
 | 
			
		||||
    if (w < 0)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("could not generate TIMESTAMP frame");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    LSQ_DEBUG("generated TIMESTAMP(%"PRIu64" us) frame",
 | 
			
		||||
                                        timestamp << TP_DEF_ACK_DELAY_EXP);
 | 
			
		||||
    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "generated TIMESTAMP(%"
 | 
			
		||||
                    PRIu64" us) frame", timestamp << TP_DEF_ACK_DELAY_EXP);
 | 
			
		||||
    packet_out->po_frame_types |= 1 << QUIC_FRAME_TIMESTAMP;
 | 
			
		||||
    lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, w);
 | 
			
		||||
    packet_out->po_regen_sz += w;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
generate_ack_frame_for_pns (struct ietf_full_conn *conn,
 | 
			
		||||
                struct lsquic_packet_out *packet_out, enum packnum_space pns,
 | 
			
		||||
| 
						 | 
				
			
			@ -1561,6 +1592,9 @@ generate_ack_frame_for_pns (struct ietf_full_conn *conn,
 | 
			
		|||
    lsquic_send_ctl_sanity_check(&conn->ifc_send_ctl);
 | 
			
		||||
    LSQ_DEBUG("%s ACK state reset", lsquic_pns2str[pns]);
 | 
			
		||||
 | 
			
		||||
    if (pns == PNS_APP && (conn->ifc_flags & IFC_TIMESTAMPS))
 | 
			
		||||
        generate_timestamp_frame(conn, packet_out, now);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3013,6 +3047,12 @@ handshake_ok (struct lsquic_conn *lconn)
 | 
			
		|||
        LSQ_DEBUG("delayed ACKs enabled");
 | 
			
		||||
        conn->ifc_flags |= IFC_DELAYED_ACKS;
 | 
			
		||||
    }
 | 
			
		||||
    if (conn->ifc_settings->es_timestamps
 | 
			
		||||
            && (params->tp_set & (1 << TPI_TIMESTAMPS)))
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("timestamps enabled");
 | 
			
		||||
        conn->ifc_flags |= IFC_TIMESTAMPS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    conn->ifc_max_peer_ack_usec = params->tp_max_ack_delay * 1000;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5583,6 +5623,36 @@ process_ack_frequency_frame (struct ietf_full_conn *conn,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned
 | 
			
		||||
process_timestamp_frame (struct ietf_full_conn *conn,
 | 
			
		||||
    struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t timestamp;
 | 
			
		||||
    int parsed_len;
 | 
			
		||||
 | 
			
		||||
    if (!(conn->ifc_flags & IFC_TIMESTAMPS))
 | 
			
		||||
    {
 | 
			
		||||
        ABORT_QUIETLY(0, TEC_PROTOCOL_VIOLATION,
 | 
			
		||||
            "Received unexpected TIMESTAMP frame (not negotiated)");
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    parsed_len = conn->ifc_conn.cn_pf->pf_parse_timestamp_frame(p, len,
 | 
			
		||||
                                                                ×tamp);
 | 
			
		||||
    if (parsed_len < 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    timestamp <<= conn->ifc_cfg.ack_exp;
 | 
			
		||||
    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "TIMESTAMP(%"PRIu64" us)", timestamp);
 | 
			
		||||
    LSQ_DEBUG("TIMESTAMP(%"PRIu64" us) (%"PRIu64" << %"PRIu8")", timestamp,
 | 
			
		||||
        timestamp >> conn->ifc_cfg.ack_exp, conn->ifc_cfg.ack_exp);
 | 
			
		||||
 | 
			
		||||
    /* We don't do anything with the timestamp */
 | 
			
		||||
 | 
			
		||||
    return parsed_len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef unsigned (*process_frame_f)(
 | 
			
		||||
    struct ietf_full_conn *, struct lsquic_packet_in *,
 | 
			
		||||
    const unsigned char *p, size_t);
 | 
			
		||||
| 
						 | 
				
			
			@ -5611,6 +5681,7 @@ static process_frame_f const process_frames[N_QUIC_FRAMES] =
 | 
			
		|||
    [QUIC_FRAME_CRYPTO]             =  process_crypto_frame,
 | 
			
		||||
    [QUIC_FRAME_HANDSHAKE_DONE]     =  process_handshake_done_frame,
 | 
			
		||||
    [QUIC_FRAME_ACK_FREQUENCY]      =  process_ack_frequency_frame,
 | 
			
		||||
    [QUIC_FRAME_TIMESTAMP]          =  process_timestamp_frame,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1049,6 +1049,8 @@ static unsigned (*const imico_process_frames[N_QUIC_FRAMES])
 | 
			
		|||
    /* STREAM frame can only come in the App PNS and we delay those packets: */
 | 
			
		||||
    [QUIC_FRAME_STREAM]             =  imico_process_invalid_frame,
 | 
			
		||||
    [QUIC_FRAME_HANDSHAKE_DONE]     =  imico_process_invalid_frame,
 | 
			
		||||
    [QUIC_FRAME_ACK_FREQUENCY]      =  imico_process_invalid_frame,
 | 
			
		||||
    [QUIC_FRAME_TIMESTAMP]          =  imico_process_invalid_frame,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -384,8 +384,6 @@ lsquic_mm_put_packet_out (struct lsquic_mm *mm,
 | 
			
		|||
    poolst_freed(&mm->packet_out_bstats[idx]);
 | 
			
		||||
    if (poolst_has_new_sample(&mm->packet_out_bstats[idx]))
 | 
			
		||||
        maybe_shrink_packet_out_bufs(mm, idx);
 | 
			
		||||
    if (packet_out->po_bwp_state)
 | 
			
		||||
        lsquic_malo_put(packet_out->po_bwp_state);
 | 
			
		||||
#else
 | 
			
		||||
    free(packet_out->po_data);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@ enum quic_frame_type
 | 
			
		|||
    QUIC_FRAME_NEW_TOKEN,           /* I */
 | 
			
		||||
    QUIC_FRAME_HANDSHAKE_DONE,      /* I */
 | 
			
		||||
    QUIC_FRAME_ACK_FREQUENCY,       /* I */
 | 
			
		||||
    QUIC_FRAME_TIMESTAMP,           /* I */
 | 
			
		||||
    N_QUIC_FRAMES
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,6 +65,7 @@ enum quic_ft_bit {
 | 
			
		|||
    QUIC_FTBIT_RETIRE_CONNECTION_ID = 1 << QUIC_FRAME_RETIRE_CONNECTION_ID,
 | 
			
		||||
    QUIC_FTBIT_HANDSHAKE_DONE    = 1 << QUIC_FRAME_HANDSHAKE_DONE,
 | 
			
		||||
    QUIC_FTBIT_ACK_FREQUENCY     = 1 << QUIC_FRAME_ACK_FREQUENCY,
 | 
			
		||||
    QUIC_FTBIT_TIMESTAMP         = 1 << QUIC_FRAME_TIMESTAMP,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +94,7 @@ static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
 | 
			
		|||
    [QUIC_FRAME_RETIRE_CONNECTION_ID]  =  "QUIC_FRAME_RETIRE_CONNECTION_ID",
 | 
			
		||||
    [QUIC_FRAME_HANDSHAKE_DONE]    =  "QUIC_FRAME_HANDSHAKE_DONE",
 | 
			
		||||
    [QUIC_FRAME_ACK_FREQUENCY]     =  "QUIC_FRAME_ACK_FREQUENCY",
 | 
			
		||||
    [QUIC_FRAME_TIMESTAMP]         =  "QUIC_FRAME_TIMESTAMP",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define QUIC_FRAME_PRELEN   (sizeof("QUIC_FRAME_"))
 | 
			
		||||
| 
						 | 
				
			
			@ -128,6 +131,7 @@ static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
 | 
			
		|||
    QUIC_FRAME_SLEN(QUIC_FRAME_NEW_TOKEN)         + 1 + \
 | 
			
		||||
    QUIC_FRAME_SLEN(QUIC_FRAME_HANDSHAKE_DONE)    + 1 + \
 | 
			
		||||
    QUIC_FRAME_SLEN(QUIC_FRAME_ACK_FREQUENCY)     + 1 + \
 | 
			
		||||
    QUIC_FRAME_SLEN(QUIC_FRAME_TIMESTAMP)         + 1 + \
 | 
			
		||||
    0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -217,6 +221,7 @@ extern const char *const lsquic_pns2str[];
 | 
			
		|||
    |  QUIC_FTBIT_NEW_TOKEN          \
 | 
			
		||||
    |  QUIC_FTBIT_HANDSHAKE_DONE     \
 | 
			
		||||
    |  QUIC_FTBIT_ACK_FREQUENCY      \
 | 
			
		||||
    |  QUIC_FTBIT_TIMESTAMP          \
 | 
			
		||||
    |  QUIC_FTBIT_CRYPTO             )
 | 
			
		||||
 | 
			
		||||
/* [draft-ietf-quic-transport-24] Section 1.2 */
 | 
			
		||||
| 
						 | 
				
			
			@ -231,7 +236,7 @@ extern const char *const lsquic_pns2str[];
 | 
			
		|||
 */
 | 
			
		||||
#define IQUIC_FRAME_RETX_MASK (  \
 | 
			
		||||
    ALL_IQUIC_FRAMES & ~(QUIC_FTBIT_PADDING|QUIC_FTBIT_PATH_RESPONSE    \
 | 
			
		||||
                |QUIC_FTBIT_PATH_CHALLENGE|QUIC_FTBIT_ACK))
 | 
			
		||||
            |QUIC_FTBIT_PATH_CHALLENGE|QUIC_FTBIT_ACK|QUIC_FTBIT_TIMESTAMP))
 | 
			
		||||
 | 
			
		||||
extern const enum quic_ft_bit lsquic_legal_frames_by_level[];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ enum PACKET_PUBLIC_FLAGS
 | 
			
		|||
 | 
			
		||||
#define GQUIC_FRAME_REGEN_MASK ((1 << QUIC_FRAME_ACK)                \
 | 
			
		||||
  | (1 << QUIC_FRAME_PATH_CHALLENGE) | (1 << QUIC_FRAME_PATH_RESPONSE) \
 | 
			
		||||
  | (1 << QUIC_FRAME_STOP_WAITING))
 | 
			
		||||
  | (1 << QUIC_FRAME_STOP_WAITING) | (1 << QUIC_FRAME_TIMESTAMP))
 | 
			
		||||
 | 
			
		||||
#define GQUIC_FRAME_REGENERATE(frame_type) ((1 << (frame_type)) & GQUIC_FRAME_REGEN_MASK)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -310,6 +310,10 @@ struct parse_funcs
 | 
			
		|||
    unsigned
 | 
			
		||||
    (*pf_ack_frequency_frame_size) (uint64_t seqno, uint64_t pack_tol,
 | 
			
		||||
        uint64_t upd_mad);
 | 
			
		||||
    int
 | 
			
		||||
    (*pf_gen_timestamp_frame) (unsigned char *buf, size_t buf_len, uint64_t);
 | 
			
		||||
    int
 | 
			
		||||
    (*pf_parse_timestamp_frame) (const unsigned char *buf, size_t, uint64_t *);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -243,5 +243,7 @@ const enum quic_ft_bit lsquic_legal_frames_by_level[N_ENC_LEVS] =
 | 
			
		|||
                    | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
 | 
			
		||||
                    | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
 | 
			
		||||
                    | QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
 | 
			
		||||
                    | QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN,
 | 
			
		||||
                    | QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN
 | 
			
		||||
                    | QUIC_FTBIT_TIMESTAMP
 | 
			
		||||
                    ,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,9 @@
 | 
			
		|||
#define CHECK_SPACE(need, pstart, pend)  \
 | 
			
		||||
    do { if ((intptr_t) (need) > ((pend) - (pstart))) { return -1; } } while (0)
 | 
			
		||||
 | 
			
		||||
#define FRAME_TYPE_ACK_FREQUENCY    0xAF
 | 
			
		||||
#define FRAME_TYPE_TIMESTAMP        0x2F5
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
ietf_v1_gen_one_varint (unsigned char *, size_t, unsigned char, uint64_t);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1109,7 +1112,8 @@ ietf_v1_parse_frame_type (const unsigned char *buf, size_t len)
 | 
			
		|||
    if (s > 0 && (unsigned) s == (1u << vint_val2bits(val)))
 | 
			
		||||
        switch (val)
 | 
			
		||||
        {
 | 
			
		||||
        case 0xAF:  return QUIC_FRAME_ACK_FREQUENCY;
 | 
			
		||||
        case FRAME_TYPE_ACK_FREQUENCY:  return QUIC_FRAME_ACK_FREQUENCY;
 | 
			
		||||
        case FRAME_TYPE_TIMESTAMP:      return QUIC_FRAME_TIMESTAMP;
 | 
			
		||||
        default:    break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2059,7 +2063,7 @@ ietf_v1_gen_ack_frequency_frame (unsigned char *buf, size_t buf_len,
 | 
			
		|||
    uint64_t seqno, uint64_t pack_tol, uint64_t upd_mad)
 | 
			
		||||
{
 | 
			
		||||
    return ietf_v1_gen_frame_with_varints(buf, buf_len, 4,
 | 
			
		||||
                            (uint64_t[]){ 0xAF, seqno, pack_tol, upd_mad });
 | 
			
		||||
        (uint64_t[]){ FRAME_TYPE_ACK_FREQUENCY, seqno, pack_tol, upd_mad });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2068,7 +2072,8 @@ ietf_v1_parse_ack_frequency_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
    uint64_t *seqno, uint64_t *pack_tol, uint64_t *upd_mad)
 | 
			
		||||
{
 | 
			
		||||
    return ietf_v1_parse_frame_with_varints(buf, buf_len,
 | 
			
		||||
                0xAF, 3, (uint64_t *[]) { seqno, pack_tol, upd_mad });
 | 
			
		||||
                FRAME_TYPE_ACK_FREQUENCY,
 | 
			
		||||
                3, (uint64_t *[]) { seqno, pack_tol, upd_mad });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2077,7 +2082,7 @@ ietf_v1_ack_frequency_frame_size (uint64_t seqno, uint64_t pack_tol,
 | 
			
		|||
    uint64_t upd_mad)
 | 
			
		||||
{
 | 
			
		||||
    return ietf_v1_frame_with_varints_size(4,
 | 
			
		||||
                            (uint64_t[]){ 0xAF, seqno, pack_tol, upd_mad });
 | 
			
		||||
            (uint64_t[]){ FRAME_TYPE_ACK_FREQUENCY, seqno, pack_tol, upd_mad });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2088,6 +2093,24 @@ ietf_v1_handshake_done_frame_size (void)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
ietf_v1_gen_timestamp_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
                                                            uint64_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    return ietf_v1_gen_frame_with_varints(buf, buf_len, 2,
 | 
			
		||||
                            (uint64_t[]){ FRAME_TYPE_TIMESTAMP, timestamp });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
ietf_v1_parse_timestamp_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                                                            uint64_t *timestamp)
 | 
			
		||||
{
 | 
			
		||||
    return ietf_v1_parse_frame_with_varints(buf, buf_len,
 | 
			
		||||
                FRAME_TYPE_TIMESTAMP, 1, (uint64_t *[]) { timestamp });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const struct parse_funcs lsquic_parse_funcs_ietf_v1 =
 | 
			
		||||
{
 | 
			
		||||
    .pf_gen_reg_pkt_header            =  ietf_v1_gen_reg_pkt_header,
 | 
			
		||||
| 
						 | 
				
			
			@ -2156,4 +2179,6 @@ const struct parse_funcs lsquic_parse_funcs_ietf_v1 =
 | 
			
		|||
    .pf_gen_ack_frequency_frame       =  ietf_v1_gen_ack_frequency_frame,
 | 
			
		||||
    .pf_parse_ack_frequency_frame     =  ietf_v1_parse_ack_frequency_frame,
 | 
			
		||||
    .pf_ack_frequency_frame_size      =  ietf_v1_ack_frequency_frame_size,
 | 
			
		||||
    .pf_gen_timestamp_frame           =  ietf_v1_gen_timestamp_frame,
 | 
			
		||||
    .pf_parse_timestamp_frame         =  ietf_v1_parse_timestamp_frame,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,7 @@ tpi_val_2_enum (uint64_t tpi_val)
 | 
			
		|||
#endif
 | 
			
		||||
    case 0x1057:    return TPI_LOSS_BITS;
 | 
			
		||||
    case 0xDE1A:    return TPI_MIN_ACK_DELAY;
 | 
			
		||||
    case 0x7157:    return TPI_TIMESTAMPS;
 | 
			
		||||
    default:        return INT_MAX;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +80,7 @@ static const unsigned enum_2_tpi_val[LAST_TPI + 1] =
 | 
			
		|||
#endif
 | 
			
		||||
    [TPI_LOSS_BITS]                         =  0x1057,
 | 
			
		||||
    [TPI_MIN_ACK_DELAY]                     =  0xDE1A,
 | 
			
		||||
    [TPI_TIMESTAMPS]                        =  0x7157,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +106,7 @@ static const char * const tpi2str[LAST_TPI + 1] =
 | 
			
		|||
#endif
 | 
			
		||||
    [TPI_LOSS_BITS]                         =  "loss_bits",
 | 
			
		||||
    [TPI_MIN_ACK_DELAY]                     =  "min_ack_delay",
 | 
			
		||||
    [TPI_TIMESTAMPS]                        =  "timestamps",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -378,6 +381,7 @@ lsquic_tp_encode (const struct transport_params *params, int is_server,
 | 
			
		|||
                                sizeof(params->tp_preferred_address.srst));
 | 
			
		||||
                break;
 | 
			
		||||
            case TPI_DISABLE_ACTIVE_MIGRATION:
 | 
			
		||||
            case TPI_TIMESTAMPS:
 | 
			
		||||
                *p++ = 0;
 | 
			
		||||
                break;
 | 
			
		||||
#if LSQUIC_TEST_QUANTUM_READINESS
 | 
			
		||||
| 
						 | 
				
			
			@ -500,6 +504,7 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
 | 
			
		|||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case TPI_DISABLE_ACTIVE_MIGRATION:
 | 
			
		||||
        case TPI_TIMESTAMPS:
 | 
			
		||||
            EXPECT_LEN(0);
 | 
			
		||||
            break;
 | 
			
		||||
        case TPI_STATELESS_RESET_TOKEN:
 | 
			
		||||
| 
						 | 
				
			
			@ -615,7 +620,7 @@ lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
 | 
			
		|||
                return;
 | 
			
		||||
        }
 | 
			
		||||
    for (; tpi <= MAX_EMPTY_TPI; ++tpi)
 | 
			
		||||
        if (params->tp_set & (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL))
 | 
			
		||||
        if (params->tp_set & (1 << tpi))
 | 
			
		||||
        {
 | 
			
		||||
            nw = snprintf(buf, end - buf, "%.*s%s",
 | 
			
		||||
                                    (buf + sz > end) << 1, "; ", tpi2str[tpi]);
 | 
			
		||||
| 
						 | 
				
			
			@ -825,6 +830,7 @@ lsquic_tp_encode_id25 (const struct transport_params *params, int is_server,
 | 
			
		|||
                                sizeof(params->tp_preferred_address.srst));
 | 
			
		||||
                break;
 | 
			
		||||
            case TPI_DISABLE_ACTIVE_MIGRATION:
 | 
			
		||||
            case TPI_TIMESTAMPS:
 | 
			
		||||
                WRITE_UINT_TO_P(0, 16);
 | 
			
		||||
                break;
 | 
			
		||||
#if LSQUIC_TEST_QUANTUM_READINESS
 | 
			
		||||
| 
						 | 
				
			
			@ -948,6 +954,7 @@ lsquic_tp_decode_id25 (const unsigned char *const buf, size_t bufsz,
 | 
			
		|||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case TPI_DISABLE_ACTIVE_MIGRATION:
 | 
			
		||||
        case TPI_TIMESTAMPS:
 | 
			
		||||
            EXPECT_LEN(0);
 | 
			
		||||
            break;
 | 
			
		||||
        case TPI_STATELESS_RESET_TOKEN:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ enum transport_param_id
 | 
			
		|||
    /*
 | 
			
		||||
     * Empty transport parameters:
 | 
			
		||||
     */
 | 
			
		||||
    TPI_TIMESTAMPS,
 | 
			
		||||
    TPI_DISABLE_ACTIVE_MIGRATION,           MAX_EMPTY_TPI = TPI_DISABLE_ACTIVE_MIGRATION,
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -371,7 +371,10 @@ prog_connect (struct prog *prog, unsigned char *zero_rtt, size_t zero_rtt_len)
 | 
			
		|||
    if (NULL == lsquic_engine_connect(prog->prog_engine, N_LSQVER,
 | 
			
		||||
                    (struct sockaddr *) &sport->sp_local_addr,
 | 
			
		||||
                    (struct sockaddr *) &sport->sas, sport, NULL,
 | 
			
		||||
                    prog->prog_hostname ? prog->prog_hostname : sport->host,
 | 
			
		||||
                    prog->prog_hostname ? prog->prog_hostname
 | 
			
		||||
                    /* SNI is required for HTTP */
 | 
			
		||||
                  : prog->prog_engine_flags & LSENG_HTTP ? sport->host
 | 
			
		||||
                  : NULL,
 | 
			
		||||
                    prog->prog_max_packet_size, zero_rtt, zero_rtt_len,
 | 
			
		||||
                    sport->sp_token_buf, sport->sp_token_sz))
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,21 +134,27 @@ struct ssl_ctx_st *
 | 
			
		|||
lookup_cert (void *cert_lu_ctx, const struct sockaddr *sa_UNUSED,
 | 
			
		||||
             const char *sni)
 | 
			
		||||
{
 | 
			
		||||
    struct lsquic_hash_elem *el;
 | 
			
		||||
    struct server_cert *server_cert;
 | 
			
		||||
 | 
			
		||||
    if (!cert_lu_ctx)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    if (!sni)
 | 
			
		||||
 | 
			
		||||
    if (sni)
 | 
			
		||||
        el = lsquic_hash_find(cert_lu_ctx, sni, strlen(sni));
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("SNI is not set");
 | 
			
		||||
        return NULL;
 | 
			
		||||
        el = lsquic_hash_first(cert_lu_ctx);
 | 
			
		||||
    }
 | 
			
		||||
    struct lsquic_hash_elem *el = lsquic_hash_find(cert_lu_ctx, sni, strlen(sni));
 | 
			
		||||
    struct server_cert *server_cert = NULL;
 | 
			
		||||
 | 
			
		||||
    if (el)
 | 
			
		||||
    {
 | 
			
		||||
        server_cert = lsquic_hashelem_getdata(el);
 | 
			
		||||
        if (server_cert)
 | 
			
		||||
            return server_cert->ce_ssl_ctx;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1802,6 +1802,11 @@ set_engine_option (struct lsquic_engine_settings *settings,
 | 
			
		|||
            settings->es_honor_prst = atoi(val);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (0 == strncmp(name, "timestamps", 10))
 | 
			
		||||
        {
 | 
			
		||||
            settings->es_timestamps = atoi(val);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 11:
 | 
			
		||||
        if (0 == strncmp(name, "ping_period", 11))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue