From afe3d36359a0bc5d011071d4abd502589f52ae82 Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Mon, 2 Mar 2020 08:53:41 -0500 Subject: [PATCH] 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. --- CHANGELOG | 8 +++ docs/apiref.rst | 16 ++++-- docs/conf.py | 4 +- docs/gettingstarted.rst | 73 +++++++++++++++++++++++++- docs/index.rst | 5 +- docs/internals.rst | 11 ++++ docs/lsquic-engine-conns.drawio | 1 + docs/lsquic-engine-conns.png | Bin 0 -> 97346 bytes include/lsquic.h | 19 +++++-- src/liblsquic/lsquic_enc_sess_ietf.c | 14 +++-- src/liblsquic/lsquic_engine.c | 3 +- src/liblsquic/lsquic_full_conn_ietf.c | 71 +++++++++++++++++++++++++ src/liblsquic/lsquic_mini_conn_ietf.c | 2 + src/liblsquic/lsquic_mm.c | 2 - src/liblsquic/lsquic_packet_common.h | 7 ++- src/liblsquic/lsquic_packet_gquic.h | 2 +- src/liblsquic/lsquic_parse.h | 4 ++ src/liblsquic/lsquic_parse_common.c | 4 +- src/liblsquic/lsquic_parse_ietf_v1.c | 33 ++++++++++-- src/liblsquic/lsquic_trans_params.c | 9 +++- src/liblsquic/lsquic_trans_params.h | 1 + test/prog.c | 5 +- test/test_cert.c | 14 +++-- test/test_common.c | 5 ++ 24 files changed, 279 insertions(+), 34 deletions(-) create mode 100644 docs/internals.rst create mode 100644 docs/lsquic-engine-conns.drawio create mode 100644 docs/lsquic-engine-conns.png diff --git a/CHANGELOG b/CHANGELOG index 21574be..6d4e95f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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. diff --git a/docs/apiref.rst b/docs/apiref.rst index b88a66b..2457351 100644 --- a/docs/apiref.rst +++ b/docs/apiref.rst @@ -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()`. diff --git a/docs/conf.py b/docs/conf.py index 030f4cb..b6a6442 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -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 --------------------------------------------------- diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst index 7e81d92..41fb09b 100644 --- a/docs/gettingstarted.rst +++ b/docs/gettingstarted.rst @@ -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 diff --git a/docs/index.rst b/docs/index.rst index 8f80be9..872b3cd 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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 ================== diff --git a/docs/internals.rst b/docs/internals.rst new file mode 100644 index 0000000..8613260 --- /dev/null +++ b/docs/internals.rst @@ -0,0 +1,11 @@ +********* +Internals +********* + +Connection Management +===================== + +References to connections can exist in six different places in an +engine. + +.. image:: lsquic-engine-conns.png diff --git a/docs/lsquic-engine-conns.drawio b/docs/lsquic-engine-conns.drawio new file mode 100644 index 0000000..a5ad8ed --- /dev/null +++ b/docs/lsquic-engine-conns.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/lsquic-engine-conns.png b/docs/lsquic-engine-conns.png new file mode 100644 index 0000000000000000000000000000000000000000..1852d4e9fb0a556c31b6387bac9ddec39148d5c0 GIT binary patch literal 97346 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 literal 0 HcmV?d00001 diff --git a/include/lsquic.h b/include/lsquic.h index 37974c0..b98203e 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -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(). diff --git a/src/liblsquic/lsquic_enc_sess_ietf.c b/src/liblsquic/lsquic_enc_sess_ietf.c index a632bc3..f3ed5cb 100644 --- a/src/liblsquic/lsquic_enc_sess_ietf.c +++ b/src/liblsquic/lsquic_enc_sess_ietf.c @@ -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 : ""); 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 : ""); return 0; } } diff --git a/src/liblsquic/lsquic_engine.c b/src/liblsquic/lsquic_engine.c index 49edaf3..eabc925 100644 --- a/src/liblsquic/lsquic_engine.c +++ b/src/liblsquic/lsquic_engine.c @@ -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); diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index 47cae70..f53925b 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -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, }; diff --git a/src/liblsquic/lsquic_mini_conn_ietf.c b/src/liblsquic/lsquic_mini_conn_ietf.c index 207fe0e..b27152f 100644 --- a/src/liblsquic/lsquic_mini_conn_ietf.c +++ b/src/liblsquic/lsquic_mini_conn_ietf.c @@ -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, }; diff --git a/src/liblsquic/lsquic_mm.c b/src/liblsquic/lsquic_mm.c index ff8f483..de87ca6 100644 --- a/src/liblsquic/lsquic_mm.c +++ b/src/liblsquic/lsquic_mm.c @@ -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 diff --git a/src/liblsquic/lsquic_packet_common.h b/src/liblsquic/lsquic_packet_common.h index 119aed1..5f2bd1b 100644 --- a/src/liblsquic/lsquic_packet_common.h +++ b/src/liblsquic/lsquic_packet_common.h @@ -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[]; diff --git a/src/liblsquic/lsquic_packet_gquic.h b/src/liblsquic/lsquic_packet_gquic.h index 02a75cd..54ded33 100644 --- a/src/liblsquic/lsquic_packet_gquic.h +++ b/src/liblsquic/lsquic_packet_gquic.h @@ -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) diff --git a/src/liblsquic/lsquic_parse.h b/src/liblsquic/lsquic_parse.h index 0bccef0..b807e31 100644 --- a/src/liblsquic/lsquic_parse.h +++ b/src/liblsquic/lsquic_parse.h @@ -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 *); }; diff --git a/src/liblsquic/lsquic_parse_common.c b/src/liblsquic/lsquic_parse_common.c index ffc7b7a..4fc6347 100644 --- a/src/liblsquic/lsquic_parse_common.c +++ b/src/liblsquic/lsquic_parse_common.c @@ -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 + , }; diff --git a/src/liblsquic/lsquic_parse_ietf_v1.c b/src/liblsquic/lsquic_parse_ietf_v1.c index 5d86658..8759091 100644 --- a/src/liblsquic/lsquic_parse_ietf_v1.c +++ b/src/liblsquic/lsquic_parse_ietf_v1.c @@ -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, }; diff --git a/src/liblsquic/lsquic_trans_params.c b/src/liblsquic/lsquic_trans_params.c index ae5b428..e5dcaec 100644 --- a/src/liblsquic/lsquic_trans_params.c +++ b/src/liblsquic/lsquic_trans_params.c @@ -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: diff --git a/src/liblsquic/lsquic_trans_params.h b/src/liblsquic/lsquic_trans_params.h index 1769a35..d170144 100644 --- a/src/liblsquic/lsquic_trans_params.h +++ b/src/liblsquic/lsquic_trans_params.h @@ -38,6 +38,7 @@ enum transport_param_id /* * Empty transport parameters: */ + TPI_TIMESTAMPS, TPI_DISABLE_ACTIVE_MIGRATION, MAX_EMPTY_TPI = TPI_DISABLE_ACTIVE_MIGRATION, /* diff --git a/test/prog.c b/test/prog.c index 24df4dd..93ab35e 100644 --- a/test/prog.c +++ b/test/prog.c @@ -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; diff --git a/test/test_cert.c b/test/test_cert.c index 90cc279..7eed240 100644 --- a/test/test_cert.c +++ b/test/test_cert.c @@ -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; } diff --git a/test/test_common.c b/test/test_common.c index 37313ac..cff4584 100644 --- a/test/test_common.c +++ b/test/test_common.c @@ -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))