mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.18.0
- [API] Rename "0-RTT" to "session resumption." In IETF QUIC, "0-RTT" always refers to early data, meaning a request that the server can reply to in the very first return flight. A more appropriate name for what we support on the client site is "session resumption," which is standard TLS terminology. Later, when we add support for 0-RTT (early data), we can use the 0-RTT terminology again, this time in proper context. - [BUGFIX] Do not set certificate callback if ea_lookup_cert is NULL. - [BUGFIX] Make connection tickable when it's marked as closed. - [BUGFIX] Fail certificate lookup if SNI is not present in HTTP mode. - Several documentation fixes and improvements. - Minor code cleanup.
This commit is contained in:
parent
da99665b1c
commit
7483dee074
26 changed files with 359 additions and 273 deletions
15
CHANGELOG
15
CHANGELOG
|
@ -1,3 +1,18 @@
|
||||||
|
2020-07-06
|
||||||
|
- 2.18.0
|
||||||
|
- [API] Rename "0-RTT" to "session resumption." In IETF QUIC, "0-RTT"
|
||||||
|
always refers to early data, meaning a request that the server can
|
||||||
|
reply to in the very first return flight. A more appropriate name
|
||||||
|
for what we support on the client site is "session resumption," which
|
||||||
|
is standard TLS terminology. Later, when we add support for 0-RTT
|
||||||
|
(early data), we can use the 0-RTT terminology again, this time in
|
||||||
|
proper context.
|
||||||
|
- [BUGFIX] Do not set certificate callback if ea_lookup_cert is NULL.
|
||||||
|
- [BUGFIX] Make connection tickable when it's marked as closed.
|
||||||
|
- [BUGFIX] Fail certificate lookup if SNI is not present in HTTP mode.
|
||||||
|
- Several documentation fixes and improvements.
|
||||||
|
- Minor code cleanup.
|
||||||
|
|
||||||
2020-06-24
|
2020-06-24
|
||||||
- 2.17.2
|
- 2.17.2
|
||||||
- [BUGFIX] Infinite loop in stream: advance read offset when discarding
|
- [BUGFIX] Infinite loop in stream: advance read offset when discarding
|
||||||
|
|
|
@ -15,7 +15,7 @@ and OpenLiteSpeed. We think it is free of major problems. Nevertheless, do
|
||||||
not hesitate to report bugs back to us. Even better, send us fixes and
|
not hesitate to report bugs back to us. Even better, send us fixes and
|
||||||
improvements!
|
improvements!
|
||||||
|
|
||||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-27, and ID-28.
|
Currently supported QUIC versions are Q043, Q046, Q050, ID-27, ID-28, and ID-29.
|
||||||
Support for newer versions will be added soon after they are released.
|
Support for newer versions will be added soon after they are released.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
|
|
|
@ -187,10 +187,10 @@ struct http_client_ctx {
|
||||||
unsigned hcc_reset_after_nbytes;
|
unsigned hcc_reset_after_nbytes;
|
||||||
unsigned hcc_retire_cid_after_nbytes;
|
unsigned hcc_retire_cid_after_nbytes;
|
||||||
|
|
||||||
char *hcc_zero_rtt_file_name;
|
char *hcc_sess_resume_file_name;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HCC_SKIP_0RTT = (1 << 0),
|
HCC_SKIP_SESS_RESUME = (1 << 0),
|
||||||
HCC_SEEN_FIN = (1 << 1),
|
HCC_SEEN_FIN = (1 << 1),
|
||||||
HCC_ABORT_ON_INCOMPLETE = (1 << 2),
|
HCC_ABORT_ON_INCOMPLETE = (1 << 2),
|
||||||
} hcc_flags;
|
} hcc_flags;
|
||||||
|
@ -212,7 +212,7 @@ struct lsquic_conn_ctx {
|
||||||
* never exceed hcc_cc_reqs_per_conn in client_ctx.
|
* never exceed hcc_cc_reqs_per_conn in client_ctx.
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
CH_ZERO_RTT_SAVED = 1 << 0,
|
CH_SESSION_RESUME_SAVED = 1 << 0,
|
||||||
} ch_flags;
|
} ch_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -240,31 +240,31 @@ create_connections (struct http_client_ctx *client_ctx)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
unsigned char zero_rtt[0x2000];
|
unsigned char sess_resume[0x2000];
|
||||||
|
|
||||||
if (0 == (client_ctx->hcc_flags & HCC_SKIP_0RTT)
|
if (0 == (client_ctx->hcc_flags & HCC_SKIP_SESS_RESUME)
|
||||||
&& client_ctx->hcc_zero_rtt_file_name)
|
&& client_ctx->hcc_sess_resume_file_name)
|
||||||
{
|
{
|
||||||
file = fopen(client_ctx->hcc_zero_rtt_file_name, "rb");
|
file = fopen(client_ctx->hcc_sess_resume_file_name, "rb");
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("cannot open %s for reading: %s",
|
LSQ_DEBUG("cannot open %s for reading: %s",
|
||||||
client_ctx->hcc_zero_rtt_file_name, strerror(errno));
|
client_ctx->hcc_sess_resume_file_name, strerror(errno));
|
||||||
goto no_file;
|
goto no_file;
|
||||||
}
|
}
|
||||||
len = fread(zero_rtt, 1, sizeof(zero_rtt), file);
|
len = fread(sess_resume, 1, sizeof(sess_resume), file);
|
||||||
if (0 == len && !feof(file))
|
if (0 == len && !feof(file))
|
||||||
LSQ_WARN("error reading %s: %s",
|
LSQ_WARN("error reading %s: %s",
|
||||||
client_ctx->hcc_zero_rtt_file_name, strerror(errno));
|
client_ctx->hcc_sess_resume_file_name, strerror(errno));
|
||||||
fclose(file);
|
fclose(file);
|
||||||
LSQ_INFO("create connection zero_rtt %zu bytes", len);
|
LSQ_INFO("create connection sess_resume %zu bytes", len);
|
||||||
}
|
}
|
||||||
else no_file:
|
else no_file:
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|
||||||
while (client_ctx->hcc_n_open_conns < client_ctx->hcc_concurrency &&
|
while (client_ctx->hcc_n_open_conns < client_ctx->hcc_concurrency &&
|
||||||
client_ctx->hcc_total_n_reqs > 0)
|
client_ctx->hcc_total_n_reqs > 0)
|
||||||
if (0 != prog_connect(client_ctx->prog, len ? zero_rtt : NULL, len))
|
if (0 != prog_connect(client_ctx->prog, len ? sess_resume : NULL, len))
|
||||||
{
|
{
|
||||||
LSQ_ERROR("connection failed");
|
LSQ_ERROR("connection failed");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -377,7 +377,7 @@ http_client_on_conn_closed (lsquic_conn_t *conn)
|
||||||
static int
|
static int
|
||||||
hsk_status_ok (enum lsquic_hsk_status status)
|
hsk_status_ok (enum lsquic_hsk_status status)
|
||||||
{
|
{
|
||||||
return status == LSQ_HSK_OK || status == LSQ_HSK_0RTT_OK;
|
return status == LSQ_HSK_OK || status == LSQ_HSK_RESUMED_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -389,13 +389,14 @@ http_client_on_hsk_done (lsquic_conn_t *conn, enum lsquic_hsk_status status)
|
||||||
|
|
||||||
if (hsk_status_ok(status))
|
if (hsk_status_ok(status))
|
||||||
LSQ_INFO("handshake success %s",
|
LSQ_INFO("handshake success %s",
|
||||||
status == LSQ_HSK_0RTT_OK ? "with 0-RTT" : "");
|
status == LSQ_HSK_RESUMED_OK ? "(session resumed)" : "");
|
||||||
else if (status == LSQ_HSK_FAIL)
|
else if (status == LSQ_HSK_FAIL)
|
||||||
LSQ_INFO("handshake failed");
|
LSQ_INFO("handshake failed");
|
||||||
else if (status == LSQ_HSK_0RTT_FAIL)
|
else if (status == LSQ_HSK_RESUMED_FAIL)
|
||||||
{
|
{
|
||||||
LSQ_INFO("handshake failed because of 0-RTT, will retry without it");
|
LSQ_INFO("handshake failed because of session resumption, will retry "
|
||||||
client_ctx->hcc_flags |= HCC_SKIP_0RTT;
|
"without it");
|
||||||
|
client_ctx->hcc_flags |= HCC_SKIP_SESS_RESUME;
|
||||||
++client_ctx->hcc_concurrency;
|
++client_ctx->hcc_concurrency;
|
||||||
++client_ctx->hcc_total_n_reqs;
|
++client_ctx->hcc_total_n_reqs;
|
||||||
}
|
}
|
||||||
|
@ -423,7 +424,7 @@ http_client_on_hsk_done (lsquic_conn_t *conn, enum lsquic_hsk_status status)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
http_client_on_zero_rtt_info (lsquic_conn_t *conn, const unsigned char *buf,
|
http_client_on_sess_resume_info (lsquic_conn_t *conn, const unsigned char *buf,
|
||||||
size_t bufsz)
|
size_t bufsz)
|
||||||
{
|
{
|
||||||
lsquic_conn_ctx_t *const conn_h = lsquic_conn_get_ctx(conn);
|
lsquic_conn_ctx_t *const conn_h = lsquic_conn_get_ctx(conn);
|
||||||
|
@ -431,35 +432,36 @@ http_client_on_zero_rtt_info (lsquic_conn_t *conn, const unsigned char *buf,
|
||||||
FILE *file;
|
FILE *file;
|
||||||
size_t nw;
|
size_t nw;
|
||||||
|
|
||||||
assert(client_ctx->hcc_zero_rtt_file_name);
|
assert(client_ctx->hcc_sess_resume_file_name);
|
||||||
|
|
||||||
/* Our client is rather limited: only one file and only one ticket per
|
/* Our client is rather limited: only one file and only one ticket per
|
||||||
* connection can be saved.
|
* connection can be saved.
|
||||||
*/
|
*/
|
||||||
if (conn_h->ch_flags & CH_ZERO_RTT_SAVED)
|
if (conn_h->ch_flags & CH_SESSION_RESUME_SAVED)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("zero-rtt already saved for this connection");
|
LSQ_DEBUG("session resumption information already saved for this "
|
||||||
|
"connection");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = fopen(client_ctx->hcc_zero_rtt_file_name, "wb");
|
file = fopen(client_ctx->hcc_sess_resume_file_name, "wb");
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
LSQ_WARN("cannot open %s for writing: %s",
|
LSQ_WARN("cannot open %s for writing: %s",
|
||||||
client_ctx->hcc_zero_rtt_file_name, strerror(errno));
|
client_ctx->hcc_sess_resume_file_name, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nw = fwrite(buf, 1, bufsz, file);
|
nw = fwrite(buf, 1, bufsz, file);
|
||||||
if (nw == bufsz)
|
if (nw == bufsz)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("wrote %zd bytes of zero-rtt information to %s",
|
LSQ_DEBUG("wrote %zd bytes of session resumption information to %s",
|
||||||
nw, client_ctx->hcc_zero_rtt_file_name);
|
nw, client_ctx->hcc_sess_resume_file_name);
|
||||||
conn_h->ch_flags |= CH_ZERO_RTT_SAVED;
|
conn_h->ch_flags |= CH_SESSION_RESUME_SAVED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LSQ_WARN("error: fwrite(%s) returns %zd instead of %zd: %s",
|
LSQ_WARN("error: fwrite(%s) returns %zd instead of %zd: %s",
|
||||||
client_ctx->hcc_zero_rtt_file_name, nw, bufsz, strerror(errno));
|
client_ctx->hcc_sess_resume_file_name, nw, bufsz, strerror(errno));
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
@ -1536,8 +1538,8 @@ main (int argc, char **argv)
|
||||||
client_ctx.hcc_retire_cid_after_nbytes = atoi(optarg);
|
client_ctx.hcc_retire_cid_after_nbytes = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case '0':
|
case '0':
|
||||||
http_client_if.on_zero_rtt_info = http_client_on_zero_rtt_info;
|
http_client_if.on_sess_resume_info = http_client_on_sess_resume_info;
|
||||||
client_ctx.hcc_zero_rtt_file_name = optarg;
|
client_ctx.hcc_sess_resume_file_name = optarg;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (0 != prog_set_opt(&prog, opt, optarg))
|
if (0 != prog_set_opt(&prog, opt, optarg))
|
||||||
|
|
|
@ -376,7 +376,7 @@ prog_eb (struct prog *prog)
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
prog_connect (struct prog *prog, unsigned char *zero_rtt, size_t zero_rtt_len)
|
prog_connect (struct prog *prog, unsigned char *sess_resume, size_t sess_resume_len)
|
||||||
{
|
{
|
||||||
struct service_port *sport;
|
struct service_port *sport;
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ prog_connect (struct prog *prog, unsigned char *zero_rtt, size_t zero_rtt_len)
|
||||||
/* SNI is required for HTTP */
|
/* SNI is required for HTTP */
|
||||||
: prog->prog_engine_flags & LSENG_HTTP ? sport->host
|
: prog->prog_engine_flags & LSENG_HTTP ? sport->host
|
||||||
: NULL,
|
: NULL,
|
||||||
prog->prog_max_packet_size, zero_rtt, zero_rtt_len,
|
prog->prog_max_packet_size, sess_resume, sess_resume_len,
|
||||||
sport->sp_token_buf, sport->sp_token_sz))
|
sport->sp_token_buf, sport->sp_token_sz))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
115
docs/apiref.rst
115
docs/apiref.rst
|
@ -54,6 +54,10 @@ developed by the IETF. Both types are included in a single enum:
|
||||||
|
|
||||||
IETF QUIC version ID 28
|
IETF QUIC version ID 28
|
||||||
|
|
||||||
|
.. member:: LSQVER_ID29
|
||||||
|
|
||||||
|
IETF QUIC version ID 29
|
||||||
|
|
||||||
.. member:: N_LSQVER
|
.. member:: N_LSQVER
|
||||||
|
|
||||||
Special value indicating the number of versions in the enum. It
|
Special value indicating the number of versions in the enum. It
|
||||||
|
@ -73,7 +77,7 @@ List of versions in which the server never includes CID in short packets.
|
||||||
|
|
||||||
Experimental versions.
|
Experimental versions.
|
||||||
|
|
||||||
.. macro: LSQUIC_DEPRECATED_VERSIONS
|
.. macro:: LSQUIC_DEPRECATED_VERSIONS
|
||||||
|
|
||||||
Deprecated versions.
|
Deprecated versions.
|
||||||
|
|
||||||
|
@ -114,7 +118,7 @@ LSQUIC declares several types used by many of its public functions. They are:
|
||||||
|
|
||||||
.. type:: lsquic_conn_ctx_t
|
.. type:: lsquic_conn_ctx_t
|
||||||
|
|
||||||
Connection context. This is the return value of :func:`on_new_conn()`.
|
Connection context. This is the return value of :member:`lsquic_stream_if.on_new_conn`.
|
||||||
To LSQUIC, this is just an opaque pointer. User code is expected to
|
To LSQUIC, this is just an opaque pointer. User code is expected to
|
||||||
use it for its own purposes.
|
use it for its own purposes.
|
||||||
|
|
||||||
|
@ -186,7 +190,8 @@ created:
|
||||||
|
|
||||||
Create a new engine.
|
Create a new engine.
|
||||||
|
|
||||||
:param flags: This is is a bitmask of ``LSENG_SERVER``` and ``LSENG_HTTP``.
|
:param flags: This is is a bitmask of :macro:`LSENG_SERVER` and
|
||||||
|
:macro:`LSENG_HTTP`.
|
||||||
:param api: Pointer to an initialized :type:`lsquic_engine_api`.
|
:param api: Pointer to an initialized :type:`lsquic_engine_api`.
|
||||||
|
|
||||||
The engine can be instantiated either in server mode (when ``LSENG_SERVER``
|
The engine can be instantiated either in server mode (when ``LSENG_SERVER``
|
||||||
|
@ -197,6 +202,18 @@ created:
|
||||||
for Google QUIC connections and HTTP/3 functionality for IETF QUIC
|
for Google QUIC connections and HTTP/3 functionality for IETF QUIC
|
||||||
connections.
|
connections.
|
||||||
|
|
||||||
|
.. macro:: LSENG_SERVER
|
||||||
|
|
||||||
|
One of possible bitmask values passed as first argument to
|
||||||
|
:type:`lsquic_engine_new`. When set, the engine instance
|
||||||
|
will be in the server mode.
|
||||||
|
|
||||||
|
.. macro:: LSENG_HTTP
|
||||||
|
|
||||||
|
One of possible bitmask values passed as first argument to
|
||||||
|
:type:`lsquic_engine_new`. When set, the engine instance
|
||||||
|
will enable HTTP functionality.
|
||||||
|
|
||||||
.. function:: void lsquic_engine_cooldown (lsquic_engine_t *engine)
|
.. function:: void lsquic_engine_cooldown (lsquic_engine_t *engine)
|
||||||
|
|
||||||
This function closes all mini connections and marks all full connections
|
This function closes all mini connections and marks all full connections
|
||||||
|
@ -268,6 +285,11 @@ optional members.
|
||||||
In a multi-process setup, it may be useful to observe the CID
|
In a multi-process setup, it may be useful to observe the CID
|
||||||
lifecycle. This optional set of callbacks makes it possible.
|
lifecycle. This optional set of callbacks makes it possible.
|
||||||
|
|
||||||
|
.. member:: const char *ea_alpn
|
||||||
|
|
||||||
|
The optional ALPN string is used by the client if :macro:`LSENG_HTTP`
|
||||||
|
is not set.
|
||||||
|
|
||||||
.. _apiref-engine-settings:
|
.. _apiref-engine-settings:
|
||||||
|
|
||||||
Engine Settings
|
Engine Settings
|
||||||
|
@ -307,17 +329,27 @@ settings structure:
|
||||||
|
|
||||||
.. member:: unsigned es_max_cfcw
|
.. member:: unsigned es_max_cfcw
|
||||||
|
|
||||||
This value is used to specify maximum allowed value connection flow
|
This value is used to specify maximum allowed value CFCW is allowed
|
||||||
control window is allowed to reach due to window auto-tuning. By
|
to reach due to window auto-tuning. By default, this value is zero,
|
||||||
default, this value is zero, which means that CFCW is not allowed
|
which means that CFCW is not allowed to increase from its initial
|
||||||
to increase from its initial value.
|
value.
|
||||||
|
|
||||||
|
This setting is applicable to both gQUIC and IETF QUIC.
|
||||||
|
|
||||||
|
See :member:`lsquic_engine_settings.es_cfcw`,
|
||||||
|
:member:`lsquic_engine_settings.es_init_max_data`.
|
||||||
|
|
||||||
.. member:: unsigned es_max_sfcw
|
.. member:: unsigned es_max_sfcw
|
||||||
|
|
||||||
This value is used to specify maximum allowed value stream flow
|
This value is used to specify the maximum value stream flow control
|
||||||
control window is allowed to reach due to window auto-tuning. By
|
window is allowed to reach due to auto-tuning. By default, this
|
||||||
default, this value is zero, which means that CFCW is not allowed
|
value is zero, meaning that auto-tuning is turned off.
|
||||||
to increase from its initial value.
|
|
||||||
|
This setting is applicable to both gQUIC and IETF QUIC.
|
||||||
|
|
||||||
|
See :member:`lsquic_engine_settings.es_sfcw`,
|
||||||
|
:member:`lsquic_engine_settings.es_init_max_stream_data_bidi_local`,
|
||||||
|
:member:`lsquic_engine_settings.es_init_max_stream_data_bidi_remote`.
|
||||||
|
|
||||||
.. member:: unsigned es_max_streams_in
|
.. member:: unsigned es_max_streams_in
|
||||||
|
|
||||||
|
@ -397,9 +429,11 @@ settings structure:
|
||||||
(source-addr, dest-addr) tuple, thereby making it necessary to create
|
(source-addr, dest-addr) tuple, thereby making it necessary to create
|
||||||
a socket for each connection.
|
a socket for each connection.
|
||||||
|
|
||||||
This option has no effect in Q046, as the server never includes
|
This option has no effect in Q046 and Q050, as the server never includes
|
||||||
CIDs in the short packets.
|
CIDs in the short packets.
|
||||||
|
|
||||||
|
This setting is applicable to gQUIC only.
|
||||||
|
|
||||||
The default is :func:`LSQUIC_DF_SUPPORT_TCID0`.
|
The default is :func:`LSQUIC_DF_SUPPORT_TCID0`.
|
||||||
|
|
||||||
.. member:: int es_support_nstp
|
.. member:: int es_support_nstp
|
||||||
|
@ -421,6 +455,8 @@ settings structure:
|
||||||
receives corresponding Public Reset packet. The default is to
|
receives corresponding Public Reset packet. The default is to
|
||||||
ignore these packets.
|
ignore these packets.
|
||||||
|
|
||||||
|
The default is :macro:`LSQUIC_DF_HONOR_PRST`.
|
||||||
|
|
||||||
.. member:: int es_send_prst
|
.. member:: int es_send_prst
|
||||||
|
|
||||||
If set to true value, the library will send Public Reset packets
|
If set to true value, the library will send Public Reset packets
|
||||||
|
@ -457,7 +493,7 @@ settings structure:
|
||||||
|
|
||||||
.. member:: unsigned es_proc_time_thresh
|
.. member:: unsigned es_proc_time_thresh
|
||||||
|
|
||||||
If set, this value specifies that number of microseconds that
|
If set, this value specifies the number of microseconds that
|
||||||
:func:`lsquic_engine_process_conns()` and
|
:func:`lsquic_engine_process_conns()` and
|
||||||
:func:`lsquic_engine_send_unsent_packets()` are allowed to spend
|
:func:`lsquic_engine_send_unsent_packets()` are allowed to spend
|
||||||
before returning.
|
before returning.
|
||||||
|
@ -842,7 +878,7 @@ out of date. Please check your :file:`lsquic.h` for actual values.*
|
||||||
|
|
||||||
Default clock granularity is 1000 microseconds.
|
Default clock granularity is 1000 microseconds.
|
||||||
|
|
||||||
.. macro:: LSQUIC_DF_SCID_LEN 8
|
.. macro:: LSQUIC_DF_SCID_LEN
|
||||||
|
|
||||||
The default value is 8 for simplicity and speed.
|
The default value is 8 for simplicity and speed.
|
||||||
|
|
||||||
|
@ -987,7 +1023,7 @@ that the library uses to send packets.
|
||||||
|
|
||||||
ECN may be set by IETF QUIC connections if ``es_ecn`` is set.
|
ECN may be set by IETF QUIC connections if ``es_ecn`` is set.
|
||||||
|
|
||||||
.. type: typedef int (*lsquic_packets_out_f)(void *packets_out_ctx, const struct lsquic_out_spec *out_spec, unsigned n_packets_out)
|
.. type:: typedef int (*lsquic_packets_out_f)(void *packets_out_ctx, const struct lsquic_out_spec *out_spec, unsigned n_packets_out)
|
||||||
|
|
||||||
Returns number of packets successfully sent out or -1 on error. -1 should
|
Returns number of packets successfully sent out or -1 on error. -1 should
|
||||||
only be returned if no packets were sent out. If -1 is returned or if the
|
only be returned if no packets were sent out. If -1 is returned or if the
|
||||||
|
@ -1010,7 +1046,9 @@ that the library uses to send packets.
|
||||||
.. function:: int lsquic_engine_has_unsent_packets (lsquic_engine_t *engine)
|
.. function:: int lsquic_engine_has_unsent_packets (lsquic_engine_t *engine)
|
||||||
|
|
||||||
Returns true if engine has some unsent packets. This happens if
|
Returns true if engine has some unsent packets. This happens if
|
||||||
``ea_packets_out()`` could not send everything out.
|
:member:`lsquic_engine_api.ea_packets_out` could not send everything out
|
||||||
|
or if processing deadline was exceeded (see
|
||||||
|
:member:`lsquic_engine_settings.es_proc_time_thresh`).
|
||||||
|
|
||||||
.. function:: void lsquic_engine_send_unsent_packets (lsquic_engine_t *engine)
|
.. function:: void lsquic_engine_send_unsent_packets (lsquic_engine_t *engine)
|
||||||
|
|
||||||
|
@ -1028,8 +1066,7 @@ the engine to communicate with the user code:
|
||||||
|
|
||||||
.. type:: struct lsquic_stream_if
|
.. type:: struct lsquic_stream_if
|
||||||
|
|
||||||
.. member:: lsquic_conn_ctx_t *(*on_new_conn)(void *stream_if_ctx,
|
.. member:: lsquic_conn_ctx_t *(*on_new_conn)(void *stream_if_ctx, lsquic_conn_t *)
|
||||||
lsquic_conn_t *);
|
|
||||||
|
|
||||||
Called when a new connection has been created. In server mode,
|
Called when a new connection has been created. In server mode,
|
||||||
this means that the handshake has been successful. In client mode,
|
this means that the handshake has been successful. In client mode,
|
||||||
|
@ -1104,10 +1141,10 @@ the engine to communicate with the user code:
|
||||||
|
|
||||||
This callback is optional.
|
This callback is optional.
|
||||||
|
|
||||||
.. member:: void (*on_zero_rtt_info)(lsquic_conn_t *c, const unsigned char *, size_t)
|
.. member:: void (*on_sess_resume_info)(lsquic_conn_t *c, const unsigned char *, size_t)
|
||||||
|
|
||||||
This callback lets client record information needed to
|
This callback lets client record information needed to
|
||||||
perform a zero-RTT handshake next time around.
|
perform session resumption next time around.
|
||||||
|
|
||||||
This callback is optional.
|
This callback is optional.
|
||||||
|
|
||||||
|
@ -1115,19 +1152,19 @@ Creating Connections
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
In server mode, the connections are created by the library based on incoming
|
In server mode, the connections are created by the library based on incoming
|
||||||
packets. After handshake is completed, the library calls :func:`on_new_conn()`
|
packets. After handshake is completed, the library calls :member:`lsquic_stream_if.on_new_conn`
|
||||||
callback.
|
callback.
|
||||||
|
|
||||||
In client mode, a new connection is created by
|
In client mode, a new connection is created by
|
||||||
|
|
||||||
.. function:: lsquic_conn_t * lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version, const struct sockaddr *local_sa, const struct sockaddr *peer_sa, void *peer_ctx, lsquic_conn_ctx_t *conn_ctx, const char *sni, unsigned short max_udp_payload_size, const unsigned char *zero_rtt, size_t zero_rtt_len, const unsigned char *token, size_t token_sz)
|
.. function:: lsquic_conn_t * lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version, const struct sockaddr *local_sa, const struct sockaddr *peer_sa, void *peer_ctx, lsquic_conn_ctx_t *conn_ctx, const char *sni, unsigned short max_udp_payload_size, const unsigned char *sess_resume, size_t sess_resume_len, const unsigned char *token, size_t token_sz)
|
||||||
|
|
||||||
:param engine: Engine to use.
|
:param engine: Engine to use.
|
||||||
|
|
||||||
:param version:
|
:param version:
|
||||||
|
|
||||||
To let the engine specify QUIC version, use N_LSQVER. If zero-rtt info is
|
To let the engine specify QUIC version, use N_LSQVER. If session resumption
|
||||||
supplied, version is picked from there instead.
|
information is supplied, version is picked from there instead.
|
||||||
|
|
||||||
:param local_sa:
|
:param local_sa:
|
||||||
|
|
||||||
|
@ -1139,7 +1176,7 @@ In client mode, a new connection is created by
|
||||||
|
|
||||||
:param peer_ctx:
|
:param peer_ctx:
|
||||||
|
|
||||||
Context associated with the connection. This is what gets passed to TODO.
|
Context associated with the peer. This is what gets passed to TODO.
|
||||||
|
|
||||||
:param conn_ctx:
|
:param conn_ctx:
|
||||||
|
|
||||||
|
@ -1158,14 +1195,14 @@ In client mode, a new connection is created by
|
||||||
Maximum packet size. If set to zero, it is inferred based on `peer_sa`
|
Maximum packet size. If set to zero, it is inferred based on `peer_sa`
|
||||||
and `version`.
|
and `version`.
|
||||||
|
|
||||||
:param zero_rtt:
|
:param sess_resume:
|
||||||
|
|
||||||
Pointer to previously saved zero-RTT data needed for TLS resumption.
|
Pointer to previously saved session resumption data needed for
|
||||||
May be NULL.
|
TLS resumption. May be NULL.
|
||||||
|
|
||||||
:param zero_rtt_len:
|
:param sess_resume_len:
|
||||||
|
|
||||||
Size of zero-RTT data.
|
Size of session resumption data.
|
||||||
|
|
||||||
:param token:
|
:param token:
|
||||||
|
|
||||||
|
@ -1173,7 +1210,7 @@ In client mode, a new connection is created by
|
||||||
packet. Tokens are used by IETF QUIC to pre-validate client
|
packet. Tokens are used by IETF QUIC to pre-validate client
|
||||||
connections, potentially avoiding a retry.
|
connections, potentially avoiding a retry.
|
||||||
|
|
||||||
See ``on_new_token`` callback in :type:`lsquic_stream_if`:
|
See :member:`lsquic_stream_if.on_new_token` callback.
|
||||||
|
|
||||||
May be NULL.
|
May be NULL.
|
||||||
|
|
||||||
|
@ -1193,7 +1230,8 @@ Closing Connections
|
||||||
|
|
||||||
.. function:: void lsquic_conn_close (lsquic_conn_t *conn)
|
.. function:: void lsquic_conn_close (lsquic_conn_t *conn)
|
||||||
|
|
||||||
This closes the connection. ``on_conn_closed()`` and ``on_close()`` callbacks will be called.
|
This closes the connection. :member:`lsquic_stream_if.on_conn_closed`
|
||||||
|
and :member:`lsquic_stream_if.on_close` callbacks will be called.
|
||||||
|
|
||||||
Creating Streams
|
Creating Streams
|
||||||
----------------
|
----------------
|
||||||
|
@ -1390,10 +1428,6 @@ more information.
|
||||||
|
|
||||||
the buffer for headers
|
the buffer for headers
|
||||||
|
|
||||||
.. member:: const char *name_ptr
|
|
||||||
|
|
||||||
the name pointer can be optionally set for encoding
|
|
||||||
|
|
||||||
.. member:: uint32_t name_hash
|
.. member:: uint32_t name_hash
|
||||||
|
|
||||||
hash value for name
|
hash value for name
|
||||||
|
@ -1593,7 +1627,7 @@ Push Promises
|
||||||
Only makes sense in server mode: the client cannot push a stream and this
|
Only makes sense in server mode: the client cannot push a stream and this
|
||||||
function always returns false in client mode.
|
function always returns false in client mode.
|
||||||
|
|
||||||
.. function: int lsquic_stream_is_pushed (const lsquic_stream_t *stream)
|
.. function:: int lsquic_stream_is_pushed (const lsquic_stream_t *stream)
|
||||||
|
|
||||||
:return: Boolean value indicating whether this is a pushed stream.
|
:return: Boolean value indicating whether this is a pushed stream.
|
||||||
|
|
||||||
|
@ -1621,6 +1655,7 @@ Stream Priorities
|
||||||
.. function:: int lsquic_stream_set_priority (lsquic_stream_t *stream, unsigned priority)
|
.. function:: int lsquic_stream_set_priority (lsquic_stream_t *stream, unsigned priority)
|
||||||
|
|
||||||
Set stream priority. Valid priority values are 1 through 256, inclusive.
|
Set stream priority. Valid priority values are 1 through 256, inclusive.
|
||||||
|
Lower value means higher priority.
|
||||||
|
|
||||||
:return: 0 on success of -1 on failure (this happens if priority value is invalid).
|
:return: 0 on success of -1 on failure (this happens if priority value is invalid).
|
||||||
|
|
||||||
|
@ -1799,16 +1834,16 @@ Miscellaneous Types
|
||||||
|
|
||||||
If not specified, malloc() and free() are used.
|
If not specified, malloc() and free() are used.
|
||||||
|
|
||||||
.. member:: void * (*pmi_allocate) (void *pmi_ctx, void *conn_ctx, unsigned short sz, char is_ipv6)
|
.. member:: void * (*pmi_allocate) (void *pmi_ctx, void *peer_ctx, unsigned short sz, char is_ipv6)
|
||||||
|
|
||||||
Allocate buffer for sending.
|
Allocate buffer for sending.
|
||||||
|
|
||||||
.. member:: void (*pmi_release) (void *pmi_ctx, void *conn_ctx, void *buf, char is_ipv6)
|
.. member:: void (*pmi_release) (void *pmi_ctx, void *peer_ctx, void *buf, char is_ipv6)
|
||||||
|
|
||||||
This function is used to release the allocated buffer after it is
|
This function is used to release the allocated buffer after it is
|
||||||
sent via ``ea_packets_out()``.
|
sent via ``ea_packets_out()``.
|
||||||
|
|
||||||
.. member:: void (*pmi_return) (void *pmi_ctx, void *conn_ctx, void *buf, char is_ipv6)
|
.. member:: void (*pmi_return) (void *pmi_ctx, void *peer_ctx, void *buf, char is_ipv6)
|
||||||
|
|
||||||
If allocated buffer is not going to be sent, return it to the
|
If allocated buffer is not going to be sent, return it to the
|
||||||
caller using this function.
|
caller using this function.
|
||||||
|
|
|
@ -24,9 +24,9 @@ copyright = u'2020, LiteSpeed Technologies'
|
||||||
author = u'LiteSpeed Technologies'
|
author = u'LiteSpeed Technologies'
|
||||||
|
|
||||||
# The short X.Y version
|
# The short X.Y version
|
||||||
version = u'2.17'
|
version = u'2.18'
|
||||||
# The full version, including alpha/beta/rc tags
|
# The full version, including alpha/beta/rc tags
|
||||||
release = u'2.17.2'
|
release = u'2.18.0'
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|
|
@ -91,11 +91,12 @@ Engine instantiation is performed by :func:`lsquic_engine_new()`:
|
||||||
lsquic_engine_t *engine
|
lsquic_engine_t *engine
|
||||||
= lsquic_engine_new(LSENG_SERVER|LSENG_HTTP, &engine_api);
|
= lsquic_engine_new(LSENG_SERVER|LSENG_HTTP, &engine_api);
|
||||||
|
|
||||||
The engine mode is selected by using the ``LSENG_SERVER`` flag. If
|
The engine mode is selected by using the :macro:`LSENG_SERVER` flag.
|
||||||
present, the engine will be in server mode; if not, the engine will
|
If present, the engine will be in server mode; if not, the engine will
|
||||||
be in client mode.
|
be in client mode. If you need both server and client functionality
|
||||||
|
in your program, instantiate two engines (or as many as you like).
|
||||||
|
|
||||||
Using the ``LSENG_HTTP`` flag enables the HTTP behavior: The library
|
Using the :macro:`LSENG_HTTP` flag enables the HTTP behavior: The library
|
||||||
hides the interaction between the HTTP application layer and the QUIC
|
hides the interaction between the HTTP application layer and the QUIC
|
||||||
transport layer and presents a simple, unified (between Google QUIC and
|
transport layer and presents a simple, unified (between Google QUIC and
|
||||||
HTTP/3) way of sending and receiving HTTP messages. Behind the scenes,
|
HTTP/3) way of sending and receiving HTTP messages. Behind the scenes,
|
||||||
|
|
132
include/lsquic.h
132
include/lsquic.h
|
@ -24,8 +24,8 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LSQUIC_MAJOR_VERSION 2
|
#define LSQUIC_MAJOR_VERSION 2
|
||||||
#define LSQUIC_MINOR_VERSION 17
|
#define LSQUIC_MINOR_VERSION 18
|
||||||
#define LSQUIC_PATCH_VERSION 2
|
#define LSQUIC_PATCH_VERSION 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Engine flags:
|
* Engine flags:
|
||||||
|
@ -131,18 +131,18 @@ enum lsquic_hsk_status
|
||||||
*/
|
*/
|
||||||
LSQ_HSK_FAIL,
|
LSQ_HSK_FAIL,
|
||||||
/**
|
/**
|
||||||
* The handshake succeeded without 0-RTT.
|
* The handshake succeeded without session resumption.
|
||||||
*/
|
*/
|
||||||
LSQ_HSK_OK,
|
LSQ_HSK_OK,
|
||||||
/**
|
/**
|
||||||
* The handshake succeeded with 0-RTT.
|
* The handshake succeeded with session resumption.
|
||||||
*/
|
*/
|
||||||
LSQ_HSK_0RTT_OK,
|
LSQ_HSK_RESUMED_OK,
|
||||||
/**
|
/**
|
||||||
* The handshake failed because of 0-RTT (early data rejected). Retry
|
* Session resumption failed. Retry the connection without session
|
||||||
* the connection without 0-RTT.
|
* resumption.
|
||||||
*/
|
*/
|
||||||
LSQ_HSK_0RTT_FAIL,
|
LSQ_HSK_RESUMED_FAIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -181,11 +181,7 @@ struct lsquic_stream_if {
|
||||||
void (*on_close) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
|
void (*on_close) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
|
||||||
/* This callback in only called in client mode */
|
/* This callback in only called in client mode */
|
||||||
/**
|
/**
|
||||||
* When handshake is completed, this callback is called. `ok' is set
|
* When handshake is completed, this optional callback is called.
|
||||||
* to true if handshake was successful; otherwise, `ok' is set to
|
|
||||||
* false.
|
|
||||||
*
|
|
||||||
* This callback is optional.
|
|
||||||
*/
|
*/
|
||||||
void (*on_hsk_done)(lsquic_conn_t *c, enum lsquic_hsk_status s);
|
void (*on_hsk_done)(lsquic_conn_t *c, enum lsquic_hsk_status s);
|
||||||
/**
|
/**
|
||||||
|
@ -196,9 +192,9 @@ struct lsquic_stream_if {
|
||||||
size_t token_size);
|
size_t token_size);
|
||||||
/**
|
/**
|
||||||
* This optional callback lets client record information needed to
|
* This optional callback lets client record information needed to
|
||||||
* perform a zero-RTT handshake next time around.
|
* perform a session resumption next time around.
|
||||||
*/
|
*/
|
||||||
void (*on_zero_rtt_info)(lsquic_conn_t *c, const unsigned char *, size_t);
|
void (*on_sess_resume_info)(lsquic_conn_t *c, const unsigned char *, size_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssl_ctx_st;
|
struct ssl_ctx_st;
|
||||||
|
@ -206,7 +202,7 @@ struct ssl_st;
|
||||||
struct lsxpack_header;
|
struct lsxpack_header;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QUIC engine in server role needs access to certificates. This is
|
* QUIC engine in server mode needs access to certificates. This is
|
||||||
* accomplished by providing a callback and a context to the engine
|
* accomplished by providing a callback and a context to the engine
|
||||||
* constructor.
|
* constructor.
|
||||||
*/
|
*/
|
||||||
|
@ -397,10 +393,22 @@ struct lsquic_engine_settings {
|
||||||
* which means that CFCW is not allowed to increase from its initial
|
* which means that CFCW is not allowed to increase from its initial
|
||||||
* value.
|
* value.
|
||||||
*
|
*
|
||||||
* @see es_cfcw
|
* This setting is applicable to both gQUIC and IETF QUIC.
|
||||||
|
*
|
||||||
|
* @see es_cfcw, @see es_init_max_data.
|
||||||
*/
|
*/
|
||||||
unsigned es_max_cfcw;
|
unsigned es_max_cfcw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This value is used to specify the maximum value stream flow control
|
||||||
|
* window is allowed to reach due to auto-tuning. By default, this
|
||||||
|
* value is zero, meaning that auto-tuning is turned off.
|
||||||
|
*
|
||||||
|
* This setting is applicable to both gQUIC and IETF QUIC.
|
||||||
|
*
|
||||||
|
* @see es_sfcw, @see es_init_max_stream_data_bidi_remote,
|
||||||
|
* @see es_init_max_stream_data_bidi_local.
|
||||||
|
*/
|
||||||
unsigned es_max_sfcw;
|
unsigned es_max_sfcw;
|
||||||
|
|
||||||
/** MIDS */
|
/** MIDS */
|
||||||
|
@ -470,9 +478,11 @@ struct lsquic_engine_settings {
|
||||||
* (source-addr, dest-addr) tuple, thereby making it necessary to create
|
* (source-addr, dest-addr) tuple, thereby making it necessary to create
|
||||||
* a socket for each connection.
|
* a socket for each connection.
|
||||||
*
|
*
|
||||||
* This option has no effect in Q046, as the server never includes
|
* This option has no effect in Q046 and Q050, as the server never includes
|
||||||
* CIDs in the short packets.
|
* CIDs in the short packets.
|
||||||
*
|
*
|
||||||
|
* This setting is applicable to gQUIC only.
|
||||||
|
*
|
||||||
* The default is @ref LSQUIC_DF_SUPPORT_TCID0.
|
* The default is @ref LSQUIC_DF_SUPPORT_TCID0.
|
||||||
*/
|
*/
|
||||||
int es_support_tcid0;
|
int es_support_tcid0;
|
||||||
|
@ -486,6 +496,8 @@ struct lsquic_engine_settings {
|
||||||
*
|
*
|
||||||
* This option does not affect the server, as it must support NSTP mode
|
* This option does not affect the server, as it must support NSTP mode
|
||||||
* if it was specified by the client.
|
* if it was specified by the client.
|
||||||
|
*
|
||||||
|
* This setting is applicable to gQUIC only.
|
||||||
*/
|
*/
|
||||||
int es_support_nstp;
|
int es_support_nstp;
|
||||||
|
|
||||||
|
@ -493,6 +505,8 @@ struct lsquic_engine_settings {
|
||||||
* If set to true value, the library will drop connections when it
|
* If set to true value, the library will drop connections when it
|
||||||
* receives corresponding Public Reset packet. The default is to
|
* receives corresponding Public Reset packet. The default is to
|
||||||
* ignore these packets.
|
* ignore these packets.
|
||||||
|
*
|
||||||
|
* The default is @ref LSQUIC_DF_HONOR_PRST.
|
||||||
*/
|
*/
|
||||||
int es_honor_prst;
|
int es_honor_prst;
|
||||||
|
|
||||||
|
@ -533,7 +547,7 @@ struct lsquic_engine_settings {
|
||||||
int es_rw_once;
|
int es_rw_once;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set, this value specifies that number of microseconds that
|
* If set, this value specifies the number of microseconds that
|
||||||
* @ref lsquic_engine_process_conns() and
|
* @ref lsquic_engine_process_conns() and
|
||||||
* @ref lsquic_engine_send_unsent_packets() are allowed to spend
|
* @ref lsquic_engine_send_unsent_packets() are allowed to spend
|
||||||
* before returning.
|
* before returning.
|
||||||
|
@ -563,6 +577,29 @@ struct lsquic_engine_settings {
|
||||||
*/
|
*/
|
||||||
unsigned es_clock_granularity;
|
unsigned es_clock_granularity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Congestion control algorithm to use.
|
||||||
|
*
|
||||||
|
* 0: Use default (@ref LSQUIC_DF_CC_ALGO)
|
||||||
|
* 1: Cubic
|
||||||
|
* 2: BBR
|
||||||
|
*/
|
||||||
|
unsigned es_cc_algo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No progress timeout.
|
||||||
|
*
|
||||||
|
* If connection does not make progress for this number of seconds, the
|
||||||
|
* connection is dropped. Here, progress is defined as user streams
|
||||||
|
* being written to or read from.
|
||||||
|
*
|
||||||
|
* If this value is zero, this timeout is disabled.
|
||||||
|
*
|
||||||
|
* Default value is @ref LSQUIC_DF_NOPROGRESS_TIMEOUT_SERVER in server
|
||||||
|
* mode and @ref LSQUIC_DF_NOPROGRESS_TIMEOUT_CLIENT in client mode.
|
||||||
|
*/
|
||||||
|
unsigned es_noprogress_timeout;
|
||||||
|
|
||||||
/* The following settings are specific to IETF QUIC. */
|
/* The following settings are specific to IETF QUIC. */
|
||||||
/* vvvvvvvvvvv */
|
/* vvvvvvvvvvv */
|
||||||
|
|
||||||
|
@ -578,15 +615,27 @@ struct lsquic_engine_settings {
|
||||||
unsigned es_init_max_data;
|
unsigned es_init_max_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initial max stream data.
|
* Initial maximum amount of stream data allowed to be sent on streams
|
||||||
|
* created by remote end (peer).
|
||||||
*
|
*
|
||||||
* This is a transport parameter.
|
* This is a transport parameter.
|
||||||
*
|
*
|
||||||
* Depending on the engine mode, the default value is either
|
* Depending on the engine mode, the default value is either
|
||||||
* @ref LSQUIC_DF_INIT_MAX_STREAM_DATA_CLIENT or
|
* @ref LSQUIC_DF_INIT_MAX_STREAM_DATA_BIDI_REMOTE_CLIENT or
|
||||||
* @ref LSQUIC_DF_INIT_MAX_STREAM_DATA_BIDI_REMOTE_SERVER.
|
* @ref LSQUIC_DF_INIT_MAX_STREAM_DATA_BIDI_REMOTE_SERVER.
|
||||||
*/
|
*/
|
||||||
unsigned es_init_max_stream_data_bidi_remote;
|
unsigned es_init_max_stream_data_bidi_remote;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initial maximum amount of stream data allowed to be sent on streams
|
||||||
|
* created by remote end (peer).
|
||||||
|
*
|
||||||
|
* This is a transport parameter.
|
||||||
|
*
|
||||||
|
* Depending on the engine mode, the default value is either
|
||||||
|
* @ref LSQUIC_DF_INIT_MAX_STREAM_DATA_BIDI_LOCAL_CLIENT or
|
||||||
|
* @ref LSQUIC_DF_INIT_MAX_STREAM_DATA_BIDI_LOCAL_SERVER.
|
||||||
|
*/
|
||||||
unsigned es_init_max_stream_data_bidi_local;
|
unsigned es_init_max_stream_data_bidi_local;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -710,15 +759,6 @@ struct lsquic_engine_settings {
|
||||||
*/
|
*/
|
||||||
int es_allow_migration;
|
int es_allow_migration;
|
||||||
|
|
||||||
/**
|
|
||||||
* Congestion control algorithm to use.
|
|
||||||
*
|
|
||||||
* 0: Use default (@ref LSQUIC_DF_CC_ALGO)
|
|
||||||
* 1: Cubic
|
|
||||||
* 2: BBR
|
|
||||||
*/
|
|
||||||
unsigned es_cc_algo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use QL loss bits. Allowed values are:
|
* Use QL loss bits. Allowed values are:
|
||||||
* 0: Do not use loss bits
|
* 0: Do not use loss bits
|
||||||
|
@ -763,20 +803,6 @@ struct lsquic_engine_settings {
|
||||||
* Default value is @ref LSQUIC_DF_MAX_UDP_PAYLOAD_SIZE_RX
|
* Default value is @ref LSQUIC_DF_MAX_UDP_PAYLOAD_SIZE_RX
|
||||||
*/
|
*/
|
||||||
unsigned short es_max_udp_payload_size_rx;
|
unsigned short es_max_udp_payload_size_rx;
|
||||||
|
|
||||||
/**
|
|
||||||
* No progress timeout.
|
|
||||||
*
|
|
||||||
* If connection does not make progress for this number of seconds, the
|
|
||||||
* connection is dropped. Here, progress is defined as user streams
|
|
||||||
* being written to or read from.
|
|
||||||
*
|
|
||||||
* If this value is zero, this timeout is disabled.
|
|
||||||
*
|
|
||||||
* Default value is @ref LSQUIC_DF_NOPROGRESS_TIMEOUT_SERVER in server
|
|
||||||
* mode and @ref LSQUIC_DF_NOPROGRESS_TIMEOUT_CLIENT in client mode.
|
|
||||||
*/
|
|
||||||
unsigned es_noprogress_timeout;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize `settings' to default values */
|
/* Initialize `settings' to default values */
|
||||||
|
@ -881,19 +907,19 @@ struct lsquic_packout_mem_if
|
||||||
/**
|
/**
|
||||||
* Allocate buffer for sending.
|
* Allocate buffer for sending.
|
||||||
*/
|
*/
|
||||||
void * (*pmi_allocate) (void *pmi_ctx, void *conn_ctx, unsigned short sz,
|
void * (*pmi_allocate) (void *pmi_ctx, void *peer_ctx, unsigned short sz,
|
||||||
char is_ipv6);
|
char is_ipv6);
|
||||||
/**
|
/**
|
||||||
* This function is used to release the allocated buffer after it is
|
* This function is used to release the allocated buffer after it is
|
||||||
* sent via @ref ea_packets_out.
|
* sent via @ref ea_packets_out.
|
||||||
*/
|
*/
|
||||||
void (*pmi_release) (void *pmi_ctx, void *conn_ctx, void *buf,
|
void (*pmi_release) (void *pmi_ctx, void *peer_ctx, void *buf,
|
||||||
char is_ipv6);
|
char is_ipv6);
|
||||||
/**
|
/**
|
||||||
* If allocated buffer is not going to be sent, return it to the caller
|
* If allocated buffer is not going to be sent, return it to the caller
|
||||||
* using this function.
|
* using this function.
|
||||||
*/
|
*/
|
||||||
void (*pmi_return) (void *pmi_ctx, void *conn_ctx, void *buf,
|
void (*pmi_return) (void *pmi_ctx, void *peer_ctx, void *buf,
|
||||||
char is_ipv6);
|
char is_ipv6);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1076,7 +1102,7 @@ struct lsquic_engine_api
|
||||||
void *ea_keylog_ctx;
|
void *ea_keylog_ctx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The optional ALPN string is used by the client @ref LSENG_HTTP
|
* The optional ALPN string is used by the client if @ref LSENG_HTTP
|
||||||
* is not set.
|
* is not set.
|
||||||
*/
|
*/
|
||||||
const char *ea_alpn;
|
const char *ea_alpn;
|
||||||
|
@ -1102,8 +1128,8 @@ lsquic_engine_new (unsigned lsquic_engine_flags,
|
||||||
/**
|
/**
|
||||||
* Create a client connection to peer identified by `peer_ctx'.
|
* Create a client connection to peer identified by `peer_ctx'.
|
||||||
*
|
*
|
||||||
* To let the engine specify QUIC version, use N_LSQVER. If zero-rtt info
|
* To let the engine specify QUIC version, use N_LSQVER. If session resumption
|
||||||
* is supplied, version is picked from there instead.
|
* information is supplied, version is picked from there instead.
|
||||||
*
|
*
|
||||||
* If `max_udp_payload_size' is set to zero, it is inferred based on `peer_sa':
|
* If `max_udp_payload_size' is set to zero, it is inferred based on `peer_sa':
|
||||||
* 1350 for IPv6 and 1370 for IPv4.
|
* 1350 for IPv6 and 1370 for IPv4.
|
||||||
|
@ -1114,7 +1140,7 @@ lsquic_engine_connect (lsquic_engine_t *, enum lsquic_version,
|
||||||
const struct sockaddr *peer_sa,
|
const struct sockaddr *peer_sa,
|
||||||
void *peer_ctx, lsquic_conn_ctx_t *conn_ctx,
|
void *peer_ctx, lsquic_conn_ctx_t *conn_ctx,
|
||||||
const char *hostname, unsigned short max_udp_payload_size,
|
const char *hostname, unsigned short max_udp_payload_size,
|
||||||
const unsigned char *zero_rtt, size_t zero_rtt_len,
|
const unsigned char *sess_resume, size_t sess_resume_len,
|
||||||
/** Resumption token: optional */
|
/** Resumption token: optional */
|
||||||
const unsigned char *token, size_t token_sz);
|
const unsigned char *token, size_t token_sz);
|
||||||
|
|
||||||
|
@ -1147,7 +1173,8 @@ lsquic_engine_process_conns (lsquic_engine_t *engine);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if engine has some unsent packets. This happens if
|
* Returns true if engine has some unsent packets. This happens if
|
||||||
* @ref ea_packets_out() could not send everything out.
|
* @ref ea_packets_out() could not send everything out or if processing
|
||||||
|
* deadline was exceeded (see @ref es_proc_time_thresh).
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
lsquic_engine_has_unsent_packets (lsquic_engine_t *engine);
|
lsquic_engine_has_unsent_packets (lsquic_engine_t *engine);
|
||||||
|
@ -1452,6 +1479,7 @@ unsigned lsquic_stream_priority (const lsquic_stream_t *s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set stream priority. Valid priority values are 1 through 256, inclusive.
|
* Set stream priority. Valid priority values are 1 through 256, inclusive.
|
||||||
|
* Lower value means higher priority.
|
||||||
*
|
*
|
||||||
* @retval 0 Success.
|
* @retval 0 Success.
|
||||||
* @retval -1 Priority value is invalid.
|
* @retval -1 Priority value is invalid.
|
||||||
|
|
|
@ -110,8 +110,8 @@ hsk_client_on_read (lsquic_stream_t *stream, struct lsquic_stream_ctx *sh)
|
||||||
if (c_hsk->lconn->cn_esf.g->esf_is_hsk_done(c_hsk->lconn->cn_enc_session))
|
if (c_hsk->lconn->cn_esf.g->esf_is_hsk_done(c_hsk->lconn->cn_enc_session))
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("handshake is successful, inform connection");
|
LSQ_DEBUG("handshake is successful, inform connection");
|
||||||
status = (c_hsk->lconn->cn_esf_c->esf_did_zero_rtt_succeed(
|
status = (c_hsk->lconn->cn_esf_c->esf_did_sess_resume_succeed(
|
||||||
c_hsk->lconn->cn_enc_session)) ? LSQ_HSK_0RTT_OK : LSQ_HSK_OK;
|
c_hsk->lconn->cn_enc_session)) ? LSQ_HSK_RESUMED_OK : LSQ_HSK_OK;
|
||||||
c_hsk->lconn->cn_if->ci_hsk_done(c_hsk->lconn, status);
|
c_hsk->lconn->cn_if->ci_hsk_done(c_hsk->lconn, status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -115,10 +115,10 @@ struct enc_session_funcs_common
|
||||||
(*esf_verify_reset_token) (enc_session_t *, const unsigned char *, size_t);
|
(*esf_verify_reset_token) (enc_session_t *, const unsigned char *, size_t);
|
||||||
|
|
||||||
int
|
int
|
||||||
(*esf_did_zero_rtt_succeed) (enc_session_t *);
|
(*esf_did_sess_resume_succeed) (enc_session_t *);
|
||||||
|
|
||||||
int
|
int
|
||||||
(*esf_is_zero_rtt_enabled) (enc_session_t *);
|
(*esf_is_sess_resume_enabled) (enc_session_t *);
|
||||||
|
|
||||||
void
|
void
|
||||||
(*esf_set_conn) (enc_session_t *, struct lsquic_conn *);
|
(*esf_set_conn) (enc_session_t *, struct lsquic_conn *);
|
||||||
|
@ -231,11 +231,12 @@ struct enc_session_funcs_gquic
|
||||||
size_t
|
size_t
|
||||||
(*esf_mem_used)(enc_session_t *);
|
(*esf_mem_used)(enc_session_t *);
|
||||||
|
|
||||||
/* Zero-rtt serialization needs the knowledge of the QUIC version, that's
|
/* Session resumption serialization needs the knowledge of the QUIC
|
||||||
* why there is a separate method for thus. Plus, we want to be able to
|
* version, that's why there is a separate method for thus. Plus, we
|
||||||
* call it after the "handshake is done" callback is called.
|
* want to be able to call it after the "handshake is done" callback
|
||||||
|
* is called.
|
||||||
*/
|
*/
|
||||||
void (*esf_maybe_dispatch_zero_rtt) (enc_session_t *,
|
void (*esf_maybe_dispatch_sess_resume) (enc_session_t *,
|
||||||
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t));
|
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t));
|
||||||
|
|
||||||
void (*esf_reset_cid) (enc_session_t *, const lsquic_cid_t *);
|
void (*esf_reset_cid) (enc_session_t *, const lsquic_cid_t *);
|
||||||
|
@ -361,7 +362,7 @@ extern const struct lsquic_stream_if lsquic_mini_cry_sm_if;
|
||||||
#define ALERT_NO_APPLICATION_PROTOCOL 120
|
#define ALERT_NO_APPLICATION_PROTOCOL 120
|
||||||
|
|
||||||
enum lsquic_version
|
enum lsquic_version
|
||||||
lsquic_zero_rtt_version (const unsigned char *, size_t);
|
lsquic_sess_resume_version (const unsigned char *, size_t);
|
||||||
|
|
||||||
/* This is seems to be true for all of the ciphers used by IETF QUIC.
|
/* This is seems to be true for all of the ciphers used by IETF QUIC.
|
||||||
* XXX: Perhaps add a check?
|
* XXX: Perhaps add a check?
|
||||||
|
|
|
@ -20,7 +20,7 @@ const char *const lsquic_enclev2str[] =
|
||||||
|
|
||||||
|
|
||||||
enum lsquic_version
|
enum lsquic_version
|
||||||
lsquic_zero_rtt_version (const unsigned char *buf, size_t bufsz)
|
lsquic_sess_resume_version (const unsigned char *buf, size_t bufsz)
|
||||||
{
|
{
|
||||||
lsquic_ver_tag_t tag;
|
lsquic_ver_tag_t tag;
|
||||||
|
|
||||||
|
|
|
@ -247,8 +247,8 @@ struct enc_sess_iquic
|
||||||
char *esi_sni_bypass;
|
char *esi_sni_bypass;
|
||||||
#endif
|
#endif
|
||||||
const unsigned char *esi_alpn;
|
const unsigned char *esi_alpn;
|
||||||
unsigned char *esi_zero_rtt_buf;
|
unsigned char *esi_sess_resume_buf;
|
||||||
size_t esi_zero_rtt_sz;
|
size_t esi_sess_resume_sz;
|
||||||
/* Need MD and AEAD for key rotation */
|
/* Need MD and AEAD for key rotation */
|
||||||
const EVP_MD *esi_md;
|
const EVP_MD *esi_md;
|
||||||
const EVP_AEAD *esi_aead;
|
const EVP_AEAD *esi_aead;
|
||||||
|
@ -649,7 +649,7 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
||||||
* uint8_t trapa_buf[ trapa_size ]
|
* uint8_t trapa_buf[ trapa_size ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ZERO_RTT_VERSION 1
|
#define SESS_RESUME_VERSION 1
|
||||||
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
#define READ_NUM(var_, ptr_) do { \
|
#define READ_NUM(var_, ptr_) do { \
|
||||||
|
@ -674,31 +674,33 @@ maybe_create_SSL_SESSION (struct enc_sess_iquic *enc_sess,
|
||||||
uint32_t rtt_ver, ticket_sz, trapa_sz;
|
uint32_t rtt_ver, ticket_sz, trapa_sz;
|
||||||
const unsigned char *ticket_buf, *trapa_buf, *p;
|
const unsigned char *ticket_buf, *trapa_buf, *p;
|
||||||
const unsigned char *const end
|
const unsigned char *const end
|
||||||
= enc_sess->esi_zero_rtt_buf + enc_sess->esi_zero_rtt_sz;
|
= enc_sess->esi_sess_resume_buf + enc_sess->esi_sess_resume_sz;
|
||||||
|
|
||||||
if (enc_sess->esi_zero_rtt_sz
|
if (enc_sess->esi_sess_resume_sz
|
||||||
< sizeof(ver_tag) + sizeof(rtt_ver) + sizeof(ticket_sz))
|
< sizeof(ver_tag) + sizeof(rtt_ver) + sizeof(ticket_sz))
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("rtt buf too short");
|
LSQ_DEBUG("rtt buf too short");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = enc_sess->esi_zero_rtt_buf;
|
p = enc_sess->esi_sess_resume_buf;
|
||||||
memcpy(&ver_tag, p, sizeof(ver_tag));
|
memcpy(&ver_tag, p, sizeof(ver_tag));
|
||||||
p += sizeof(ver_tag);
|
p += sizeof(ver_tag);
|
||||||
quic_ver = lsquic_tag2ver(ver_tag);
|
quic_ver = lsquic_tag2ver(ver_tag);
|
||||||
if (quic_ver != enc_sess->esi_ver_neg->vn_ver)
|
if (quic_ver != enc_sess->esi_ver_neg->vn_ver)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("negotiated version %s does not match that in the zero-rtt "
|
LSQ_DEBUG("negotiated version %s does not match that in the session "
|
||||||
"info buffer", lsquic_ver2str[enc_sess->esi_ver_neg->vn_ver]);
|
"resumption nfo buffer",
|
||||||
|
lsquic_ver2str[enc_sess->esi_ver_neg->vn_ver]);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
READ_NUM(rtt_ver, p);
|
READ_NUM(rtt_ver, p);
|
||||||
if (rtt_ver != ZERO_RTT_VERSION)
|
if (rtt_ver != SESS_RESUME_VERSION)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("cannot use zero-rtt buffer: encoded using %"PRIu32", "
|
LSQ_DEBUG("cannot use session resumption buffer: encoded using "
|
||||||
"while current version is %u", rtt_ver, ZERO_RTT_VERSION);
|
"%"PRIu32", while current version is %u",
|
||||||
|
rtt_ver, SESS_RESUME_VERSION);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,7 +761,7 @@ iquic_esfi_create_client (const char *hostname,
|
||||||
struct lsquic_engine_public *enpub, struct lsquic_conn *lconn,
|
struct lsquic_engine_public *enpub, struct lsquic_conn *lconn,
|
||||||
const lsquic_cid_t *dcid, const struct ver_neg *ver_neg,
|
const lsquic_cid_t *dcid, const struct ver_neg *ver_neg,
|
||||||
void *crypto_streams[4], const struct crypto_stream_if *cryst_if,
|
void *crypto_streams[4], const struct crypto_stream_if *cryst_if,
|
||||||
const unsigned char *zero_rtt, size_t zero_rtt_sz,
|
const unsigned char *sess_resume, size_t sess_resume_sz,
|
||||||
struct lsquic_alarmset *alset, unsigned max_streams_uni)
|
struct lsquic_alarmset *alset, unsigned max_streams_uni)
|
||||||
{
|
{
|
||||||
struct enc_sess_iquic *enc_sess;
|
struct enc_sess_iquic *enc_sess;
|
||||||
|
@ -814,24 +816,24 @@ iquic_esfi_create_client (const char *hostname,
|
||||||
/* Have to wait until the call to init_client() -- this is when the
|
/* Have to wait until the call to init_client() -- this is when the
|
||||||
* result of version negotiation is known.
|
* result of version negotiation is known.
|
||||||
*/
|
*/
|
||||||
if (zero_rtt && zero_rtt_sz)
|
if (sess_resume && sess_resume_sz)
|
||||||
{
|
{
|
||||||
enc_sess->esi_zero_rtt_buf = malloc(zero_rtt_sz);
|
enc_sess->esi_sess_resume_buf = malloc(sess_resume_sz);
|
||||||
if (enc_sess->esi_zero_rtt_buf)
|
if (enc_sess->esi_sess_resume_buf)
|
||||||
{
|
{
|
||||||
memcpy(enc_sess->esi_zero_rtt_buf, zero_rtt, zero_rtt_sz);
|
memcpy(enc_sess->esi_sess_resume_buf, sess_resume, sess_resume_sz);
|
||||||
enc_sess->esi_zero_rtt_sz = zero_rtt_sz;
|
enc_sess->esi_sess_resume_sz = sess_resume_sz;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
enc_sess->esi_zero_rtt_sz = 0;
|
enc_sess->esi_sess_resume_sz = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
enc_sess->esi_zero_rtt_buf = NULL;
|
enc_sess->esi_sess_resume_buf = NULL;
|
||||||
enc_sess->esi_zero_rtt_sz = 0;
|
enc_sess->esi_sess_resume_sz = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info)
|
if (enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info)
|
||||||
enc_sess->esi_flags |= ESI_WANT_TICKET;
|
enc_sess->esi_flags |= ESI_WANT_TICKET;
|
||||||
enc_sess->esi_alset = alset;
|
enc_sess->esi_alset = alset;
|
||||||
lsquic_alarmset_init_alarm(enc_sess->esi_alset, AL_SESS_TICKET,
|
lsquic_alarmset_init_alarm(enc_sess->esi_alset, AL_SESS_TICKET,
|
||||||
|
@ -1145,10 +1147,14 @@ iquic_lookup_cert (SSL *ssl, void *arg)
|
||||||
#endif
|
#endif
|
||||||
if (!server_name)
|
if (!server_name)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("cert lookup: server name is not set");
|
|
||||||
/* SNI is required in HTTP/3 */
|
|
||||||
if (enc_sess->esi_enpub->enp_flags & ENPUB_HTTP)
|
if (enc_sess->esi_enpub->enp_flags & ENPUB_HTTP)
|
||||||
return 1;
|
{
|
||||||
|
LSQ_DEBUG("SNI is not set, but is required in HTTP/3: "
|
||||||
|
"fail certificate lookup");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LSQ_DEBUG("cert lookup: server name is not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
path = enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
|
path = enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
|
||||||
|
@ -1268,6 +1274,7 @@ iquic_esfi_init_server (enc_session_t *enc_session_p)
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_clear_options(enc_sess->esi_ssl, SSL_OP_NO_TLSv1_3);
|
SSL_clear_options(enc_sess->esi_ssl, SSL_OP_NO_TLSv1_3);
|
||||||
|
if (enc_sess->esi_enpub->enp_lookup_cert)
|
||||||
SSL_set_cert_cb(enc_sess->esi_ssl, iquic_lookup_cert, enc_sess);
|
SSL_set_cert_cb(enc_sess->esi_ssl, iquic_lookup_cert, enc_sess);
|
||||||
SSL_set_ex_data(enc_sess->esi_ssl, s_idx, enc_sess);
|
SSL_set_ex_data(enc_sess->esi_ssl, s_idx, enc_sess);
|
||||||
SSL_set_accept_state(enc_sess->esi_ssl);
|
SSL_set_accept_state(enc_sess->esi_ssl);
|
||||||
|
@ -1305,13 +1312,14 @@ iquic_new_session_cb (SSL *ssl, SSL_SESSION *session)
|
||||||
size_t trapa_sz, buf_sz;
|
size_t trapa_sz, buf_sz;
|
||||||
|
|
||||||
enc_sess = SSL_get_ex_data(ssl, s_idx);
|
enc_sess = SSL_get_ex_data(ssl, s_idx);
|
||||||
assert(enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info);
|
assert(enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info);
|
||||||
|
|
||||||
SSL_get_peer_quic_transport_params(enc_sess->esi_ssl, &trapa_buf,
|
SSL_get_peer_quic_transport_params(enc_sess->esi_ssl, &trapa_buf,
|
||||||
&trapa_sz);
|
&trapa_sz);
|
||||||
if (!(trapa_buf + trapa_sz))
|
if (!(trapa_buf + trapa_sz))
|
||||||
{
|
{
|
||||||
LSQ_WARN("no transport parameters: cannot generate zero-rtt info");
|
LSQ_WARN("no transport parameters: cannot generate session "
|
||||||
|
"resumption info");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (trapa_sz > UINT32_MAX)
|
if (trapa_sz > UINT32_MAX)
|
||||||
|
@ -1347,7 +1355,7 @@ iquic_new_session_cb (SSL *ssl, SSL_SESSION *session)
|
||||||
memcpy(p, &tag, sizeof(tag));
|
memcpy(p, &tag, sizeof(tag));
|
||||||
p += sizeof(tag);
|
p += sizeof(tag);
|
||||||
|
|
||||||
WRITE_NUM(num, ZERO_RTT_VERSION, p);
|
WRITE_NUM(num, SESS_RESUME_VERSION, p);
|
||||||
WRITE_NUM(num, ticket_sz, p);
|
WRITE_NUM(num, ticket_sz, p);
|
||||||
memcpy(p, ticket_buf, ticket_sz);
|
memcpy(p, ticket_buf, ticket_sz);
|
||||||
p += ticket_sz;
|
p += ticket_sz;
|
||||||
|
@ -1358,9 +1366,9 @@ iquic_new_session_cb (SSL *ssl, SSL_SESSION *session)
|
||||||
assert(buf + buf_sz == p);
|
assert(buf + buf_sz == p);
|
||||||
OPENSSL_free(ticket_buf);
|
OPENSSL_free(ticket_buf);
|
||||||
|
|
||||||
LSQ_DEBUG("generated %zu bytes of zero-rtt buffer", buf_sz);
|
LSQ_DEBUG("generated %zu bytes of session resumption buffer", buf_sz);
|
||||||
|
|
||||||
enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info(enc_sess->esi_conn,
|
enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info(enc_sess->esi_conn,
|
||||||
buf, buf_sz);
|
buf, buf_sz);
|
||||||
free(buf);
|
free(buf);
|
||||||
enc_sess->esi_flags &= ~ESI_WANT_TICKET;
|
enc_sess->esi_flags &= ~ESI_WANT_TICKET;
|
||||||
|
@ -1410,7 +1418,7 @@ init_client (struct enc_sess_iquic *const enc_sess)
|
||||||
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
|
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
SSL_CTX_set_default_verify_paths(ssl_ctx);
|
SSL_CTX_set_default_verify_paths(ssl_ctx);
|
||||||
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT);
|
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT);
|
||||||
if (enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info)
|
if (enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info)
|
||||||
SSL_CTX_sess_set_new_cb(ssl_ctx, iquic_new_session_cb);
|
SSL_CTX_sess_set_new_cb(ssl_ctx, iquic_new_session_cb);
|
||||||
if (enc_sess->esi_enpub->enp_kli)
|
if (enc_sess->esi_enpub->enp_kli)
|
||||||
SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
|
SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
|
||||||
|
@ -1465,7 +1473,7 @@ init_client (struct enc_sess_iquic *const enc_sess)
|
||||||
}
|
}
|
||||||
free(enc_sess->esi_hostname);
|
free(enc_sess->esi_hostname);
|
||||||
enc_sess->esi_hostname = NULL;
|
enc_sess->esi_hostname = NULL;
|
||||||
if (enc_sess->esi_zero_rtt_buf)
|
if (enc_sess->esi_sess_resume_buf)
|
||||||
{
|
{
|
||||||
ssl_session = maybe_create_SSL_SESSION(enc_sess, ssl_ctx);
|
ssl_session = maybe_create_SSL_SESSION(enc_sess, ssl_ctx);
|
||||||
if (ssl_session)
|
if (ssl_session)
|
||||||
|
@ -1744,7 +1752,7 @@ iquic_esfi_handshake (struct enc_sess_iquic *enc_sess)
|
||||||
return IHS_WANT_WRITE;
|
return IHS_WANT_WRITE;
|
||||||
case SSL_ERROR_EARLY_DATA_REJECTED:
|
case SSL_ERROR_EARLY_DATA_REJECTED:
|
||||||
LSQ_DEBUG("early data rejected");
|
LSQ_DEBUG("early data rejected");
|
||||||
hsk_status = LSQ_HSK_0RTT_FAIL;
|
hsk_status = LSQ_HSK_RESUMED_FAIL;
|
||||||
goto err;
|
goto err;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
|
@ -1767,14 +1775,14 @@ iquic_esfi_handshake (struct enc_sess_iquic *enc_sess)
|
||||||
hsk_status = LSQ_HSK_OK;
|
hsk_status = LSQ_HSK_OK;
|
||||||
LSQ_DEBUG("handshake reported complete");
|
LSQ_DEBUG("handshake reported complete");
|
||||||
EV_LOG_HSK_COMPLETED(LSQUIC_LOG_CONN_ID);
|
EV_LOG_HSK_COMPLETED(LSQUIC_LOG_CONN_ID);
|
||||||
/* The ESI_USE_SSL_TICKET flag indicates if the client attempted 0-RTT.
|
/* The ESI_USE_SSL_TICKET flag indicates if the client attempted session
|
||||||
* If the handshake is complete, and the client attempted 0-RTT, it
|
* resumption. If the handshake is complete, and the client attempted
|
||||||
* must have succeeded.
|
* session resumption, it must have succeeded.
|
||||||
*/
|
*/
|
||||||
if (enc_sess->esi_flags & ESI_USE_SSL_TICKET)
|
if (enc_sess->esi_flags & ESI_USE_SSL_TICKET)
|
||||||
{
|
{
|
||||||
hsk_status = LSQ_HSK_0RTT_OK;
|
hsk_status = LSQ_HSK_RESUMED_OK;
|
||||||
EV_LOG_ZERO_RTT(LSQUIC_LOG_CONN_ID);
|
EV_LOG_SESSION_RESUMPTION(LSQUIC_LOG_CONN_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != maybe_get_peer_transport_params(enc_sess))
|
if (0 != maybe_get_peer_transport_params(enc_sess))
|
||||||
|
@ -1844,7 +1852,7 @@ iquic_esfi_destroy (enc_session_t *enc_session_p)
|
||||||
free_handshake_keys(enc_sess);
|
free_handshake_keys(enc_sess);
|
||||||
cleanup_hp(&enc_sess->esi_hp);
|
cleanup_hp(&enc_sess->esi_hp);
|
||||||
|
|
||||||
free(enc_sess->esi_zero_rtt_buf);
|
free(enc_sess->esi_sess_resume_buf);
|
||||||
free(enc_sess->esi_hostname);
|
free(enc_sess->esi_hostname);
|
||||||
free(enc_sess);
|
free(enc_sess);
|
||||||
}
|
}
|
||||||
|
@ -2407,10 +2415,10 @@ iquic_esf_alg_keysize (enc_session_t *enc_session_p)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
iquic_esf_zero_rtt_enabled (enc_session_t *enc_session_p)
|
iquic_esf_sess_resume_enabled (enc_session_t *enc_session_p)
|
||||||
{
|
{
|
||||||
struct enc_sess_iquic *const enc_sess = enc_session_p;
|
struct enc_sess_iquic *const enc_sess = enc_session_p;
|
||||||
return enc_sess->esi_zero_rtt_buf != NULL;
|
return enc_sess->esi_sess_resume_buf != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2555,7 +2563,7 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1 =
|
||||||
.esf_cipher = iquic_esf_cipher,
|
.esf_cipher = iquic_esf_cipher,
|
||||||
.esf_keysize = iquic_esf_keysize,
|
.esf_keysize = iquic_esf_keysize,
|
||||||
.esf_alg_keysize = iquic_esf_alg_keysize,
|
.esf_alg_keysize = iquic_esf_alg_keysize,
|
||||||
.esf_is_zero_rtt_enabled = iquic_esf_zero_rtt_enabled,
|
.esf_is_sess_resume_enabled = iquic_esf_sess_resume_enabled,
|
||||||
.esf_set_conn = iquic_esf_set_conn,
|
.esf_set_conn = iquic_esf_set_conn,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2573,7 +2581,7 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1_no_flush
|
||||||
.esf_cipher = iquic_esf_cipher,
|
.esf_cipher = iquic_esf_cipher,
|
||||||
.esf_keysize = iquic_esf_keysize,
|
.esf_keysize = iquic_esf_keysize,
|
||||||
.esf_alg_keysize = iquic_esf_alg_keysize,
|
.esf_alg_keysize = iquic_esf_alg_keysize,
|
||||||
.esf_is_zero_rtt_enabled = iquic_esf_zero_rtt_enabled,
|
.esf_is_sess_resume_enabled = iquic_esf_sess_resume_enabled,
|
||||||
.esf_set_conn = iquic_esf_set_conn,
|
.esf_set_conn = iquic_esf_set_conn,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1580,7 +1580,7 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version,
|
||||||
const struct sockaddr *peer_sa,
|
const struct sockaddr *peer_sa,
|
||||||
void *peer_ctx, lsquic_conn_ctx_t *conn_ctx,
|
void *peer_ctx, lsquic_conn_ctx_t *conn_ctx,
|
||||||
const char *hostname, unsigned short max_packet_size,
|
const char *hostname, unsigned short max_packet_size,
|
||||||
const unsigned char *zero_rtt, size_t zero_rtt_len,
|
const unsigned char *sess_resume, size_t sess_resume_len,
|
||||||
const unsigned char *token, size_t token_sz)
|
const unsigned char *token, size_t token_sz)
|
||||||
{
|
{
|
||||||
lsquic_conn_t *conn;
|
lsquic_conn_t *conn;
|
||||||
|
@ -1606,14 +1606,14 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version,
|
||||||
return NULL;
|
return NULL;
|
||||||
flags = engine->flags & (ENG_SERVER|ENG_HTTP);
|
flags = engine->flags & (ENG_SERVER|ENG_HTTP);
|
||||||
is_ipv4 = peer_sa->sa_family == AF_INET;
|
is_ipv4 = peer_sa->sa_family == AF_INET;
|
||||||
if (zero_rtt && zero_rtt_len)
|
if (sess_resume && sess_resume_len)
|
||||||
{
|
{
|
||||||
version = lsquic_zero_rtt_version(zero_rtt, zero_rtt_len);
|
version = lsquic_sess_resume_version(sess_resume, sess_resume_len);
|
||||||
if (version >= N_LSQVER)
|
if (version >= N_LSQVER)
|
||||||
{
|
{
|
||||||
LSQ_INFO("zero-rtt version is bad, won't use");
|
LSQ_INFO("session resumption version is bad, won't use");
|
||||||
zero_rtt = NULL;
|
sess_resume = NULL;
|
||||||
zero_rtt_len = 0;
|
sess_resume_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (version >= N_LSQVER)
|
if (version >= N_LSQVER)
|
||||||
|
@ -1627,11 +1627,11 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version,
|
||||||
if (versions & LSQUIC_IETF_VERSIONS)
|
if (versions & LSQUIC_IETF_VERSIONS)
|
||||||
conn = lsquic_ietf_full_conn_client_new(&engine->pub, versions,
|
conn = lsquic_ietf_full_conn_client_new(&engine->pub, versions,
|
||||||
flags, hostname, max_packet_size,
|
flags, hostname, max_packet_size,
|
||||||
is_ipv4, zero_rtt, zero_rtt_len, token, token_sz);
|
is_ipv4, sess_resume, sess_resume_len, token, token_sz);
|
||||||
else
|
else
|
||||||
conn = lsquic_gquic_full_conn_client_new(&engine->pub, versions,
|
conn = lsquic_gquic_full_conn_client_new(&engine->pub, versions,
|
||||||
flags, hostname, max_packet_size, is_ipv4,
|
flags, hostname, max_packet_size, is_ipv4,
|
||||||
zero_rtt, zero_rtt_len);
|
sess_resume, sess_resume_len);
|
||||||
if (!conn)
|
if (!conn)
|
||||||
goto err;
|
goto err;
|
||||||
EV_LOG_CREATE_CONN(lsquic_conn_log_cid(conn), local_sa, peer_sa);
|
EV_LOG_CREATE_CONN(lsquic_conn_log_cid(conn), local_sa, peer_sa);
|
||||||
|
|
|
@ -554,9 +554,9 @@ lsquic_ev_log_hsk_completed (const lsquic_cid_t *cid)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lsquic_ev_log_zero_rtt (const lsquic_cid_t *cid)
|
lsquic_ev_log_sess_resume (const lsquic_cid_t *cid)
|
||||||
{
|
{
|
||||||
LCID("zero_rtt successful");
|
LCID("sess_resume successful");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -311,13 +311,13 @@ lsquic_ev_log_hsk_completed (const lsquic_cid_t *);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lsquic_ev_log_zero_rtt (const lsquic_cid_t *);
|
lsquic_ev_log_sess_resume (const lsquic_cid_t *);
|
||||||
|
|
||||||
#define EV_LOG_ZERO_RTT(...) do { \
|
#define EV_LOG_SESSION_RESUMPTION(...) do { \
|
||||||
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
|
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
|
||||||
lsquic_ev_log_zero_rtt(__VA_ARGS__); \
|
lsquic_ev_log_sess_resume(__VA_ARGS__); \
|
||||||
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_QLOG)) \
|
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_QLOG)) \
|
||||||
lsquic_qlog_zero_rtt(__VA_ARGS__); \
|
lsquic_qlog_sess_resume(__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -717,21 +717,21 @@ lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *enpub,
|
||||||
unsigned versions, unsigned flags,
|
unsigned versions, unsigned flags,
|
||||||
const char *hostname, unsigned short max_packet_size,
|
const char *hostname, unsigned short max_packet_size,
|
||||||
int is_ipv4,
|
int is_ipv4,
|
||||||
const unsigned char *zero_rtt, size_t zero_rtt_len)
|
const unsigned char *sess_resume, size_t sess_resume_len)
|
||||||
{
|
{
|
||||||
struct full_conn *conn;
|
struct full_conn *conn;
|
||||||
enum lsquic_version version, zero_rtt_version;
|
enum lsquic_version version, sess_resume_version;
|
||||||
lsquic_cid_t cid;
|
lsquic_cid_t cid;
|
||||||
const struct enc_session_funcs_gquic *esf_g;
|
const struct enc_session_funcs_gquic *esf_g;
|
||||||
|
|
||||||
versions &= (~LSQUIC_IETF_VERSIONS & LSQUIC_SUPPORTED_VERSIONS);
|
versions &= (~LSQUIC_IETF_VERSIONS & LSQUIC_SUPPORTED_VERSIONS);
|
||||||
assert(versions);
|
assert(versions);
|
||||||
version = highest_bit_set(versions);
|
version = highest_bit_set(versions);
|
||||||
if (zero_rtt)
|
if (sess_resume)
|
||||||
{
|
{
|
||||||
zero_rtt_version = lsquic_zero_rtt_version(zero_rtt, zero_rtt_len);
|
sess_resume_version = lsquic_sess_resume_version(sess_resume, sess_resume_len);
|
||||||
if (zero_rtt_version < N_LSQVER && ((1 << zero_rtt_version) & versions))
|
if (sess_resume_version < N_LSQVER && ((1 << sess_resume_version) & versions))
|
||||||
version = zero_rtt_version;
|
version = sess_resume_version;
|
||||||
}
|
}
|
||||||
esf_g = select_esf_gquic_by_ver(version);
|
esf_g = select_esf_gquic_by_ver(version);
|
||||||
lsquic_generate_cid_gquic(&cid);
|
lsquic_generate_cid_gquic(&cid);
|
||||||
|
@ -751,7 +751,7 @@ lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *enpub,
|
||||||
conn->fc_conn.cn_esf.g = esf_g;
|
conn->fc_conn.cn_esf.g = esf_g;
|
||||||
conn->fc_conn.cn_enc_session =
|
conn->fc_conn.cn_enc_session =
|
||||||
conn->fc_conn.cn_esf.g->esf_create_client(&conn->fc_conn, hostname,
|
conn->fc_conn.cn_esf.g->esf_create_client(&conn->fc_conn, hostname,
|
||||||
cid, conn->fc_enpub, zero_rtt, zero_rtt_len);
|
cid, conn->fc_enpub, sess_resume, sess_resume_len);
|
||||||
if (!conn->fc_conn.cn_enc_session)
|
if (!conn->fc_conn.cn_enc_session)
|
||||||
{
|
{
|
||||||
LSQ_WARN("could not create enc session: %s", strerror(errno));
|
LSQ_WARN("could not create enc session: %s", strerror(errno));
|
||||||
|
@ -1368,10 +1368,10 @@ full_conn_ci_n_avail_streams (const lsquic_conn_t *lconn)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_done_or_doing_zero_rtt (const struct full_conn *conn)
|
handshake_done_or_doing_sess_resume (const struct full_conn *conn)
|
||||||
{
|
{
|
||||||
return (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|
return (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|
||||||
|| conn->fc_conn.cn_esf_c->esf_is_zero_rtt_enabled(
|
|| conn->fc_conn.cn_esf_c->esf_is_sess_resume_enabled(
|
||||||
conn->fc_conn.cn_enc_session);
|
conn->fc_conn.cn_enc_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1380,7 +1380,7 @@ static void
|
||||||
full_conn_ci_make_stream (struct lsquic_conn *lconn)
|
full_conn_ci_make_stream (struct lsquic_conn *lconn)
|
||||||
{
|
{
|
||||||
struct full_conn *conn = (struct full_conn *) lconn;
|
struct full_conn *conn = (struct full_conn *) lconn;
|
||||||
if (handshake_done_or_doing_zero_rtt(conn)
|
if (handshake_done_or_doing_sess_resume(conn)
|
||||||
&& full_conn_ci_n_avail_streams(lconn) > 0)
|
&& full_conn_ci_n_avail_streams(lconn) > 0)
|
||||||
{
|
{
|
||||||
if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW))
|
if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW))
|
||||||
|
@ -3463,7 +3463,7 @@ full_conn_ci_tick (lsquic_conn_t *lconn, lsquic_time_t now)
|
||||||
}
|
}
|
||||||
|
|
||||||
lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 0);
|
lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 0);
|
||||||
if (!handshake_done_or_doing_zero_rtt(conn))
|
if (!handshake_done_or_doing_sess_resume(conn))
|
||||||
{
|
{
|
||||||
process_hsk_stream_write_events(conn);
|
process_hsk_stream_write_events(conn);
|
||||||
goto end_write;
|
goto end_write;
|
||||||
|
@ -3639,12 +3639,12 @@ full_conn_ci_hsk_done (lsquic_conn_t *lconn, enum lsquic_hsk_status status)
|
||||||
lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE);
|
lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE);
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case LSQ_HSK_0RTT_FAIL:
|
case LSQ_HSK_RESUMED_FAIL:
|
||||||
case LSQ_HSK_FAIL:
|
case LSQ_HSK_FAIL:
|
||||||
conn->fc_flags |= FC_HSK_FAILED;
|
conn->fc_flags |= FC_HSK_FAILED;
|
||||||
break;
|
break;
|
||||||
case LSQ_HSK_OK:
|
case LSQ_HSK_OK:
|
||||||
case LSQ_HSK_0RTT_OK:
|
case LSQ_HSK_RESUMED_OK:
|
||||||
if (0 == apply_peer_settings(conn))
|
if (0 == apply_peer_settings(conn))
|
||||||
{
|
{
|
||||||
if (conn->fc_flags & FC_HTTP)
|
if (conn->fc_flags & FC_HTTP)
|
||||||
|
@ -3658,12 +3658,12 @@ full_conn_ci_hsk_done (lsquic_conn_t *lconn, enum lsquic_hsk_status status)
|
||||||
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done)
|
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done)
|
||||||
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done(lconn,
|
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done(lconn,
|
||||||
status);
|
status);
|
||||||
if (status == LSQ_HSK_OK || status == LSQ_HSK_0RTT_OK)
|
if (status == LSQ_HSK_OK || status == LSQ_HSK_RESUMED_OK)
|
||||||
{
|
{
|
||||||
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_zero_rtt_info)
|
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_sess_resume_info)
|
||||||
conn->fc_conn.cn_esf.g->esf_maybe_dispatch_zero_rtt(
|
conn->fc_conn.cn_esf.g->esf_maybe_dispatch_sess_resume(
|
||||||
conn->fc_conn.cn_enc_session,
|
conn->fc_conn.cn_enc_session,
|
||||||
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_zero_rtt_info);
|
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_sess_resume_info);
|
||||||
if (conn->fc_n_delayed_streams)
|
if (conn->fc_n_delayed_streams)
|
||||||
create_delayed_streams(conn);
|
create_delayed_streams(conn);
|
||||||
if (!(conn->fc_flags & FC_SERVER))
|
if (!(conn->fc_flags & FC_SERVER))
|
||||||
|
@ -3721,6 +3721,7 @@ full_conn_ci_close (struct lsquic_conn *lconn)
|
||||||
conn->fc_flags |= FC_CLOSING;
|
conn->fc_flags |= FC_CLOSING;
|
||||||
if (!(conn->fc_flags & FC_GOAWAY_SENT))
|
if (!(conn->fc_flags & FC_GOAWAY_SENT))
|
||||||
conn->fc_flags |= FC_SEND_GOAWAY;
|
conn->fc_flags |= FC_SEND_GOAWAY;
|
||||||
|
lsquic_engine_add_conn_to_tickable(conn->fc_enpub, lconn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4204,7 +4205,7 @@ full_conn_ci_is_tickable (lsquic_conn_t *lconn)
|
||||||
LSQ_DEBUG("tickable: there are sending streams");
|
LSQ_DEBUG("tickable: there are sending streams");
|
||||||
goto check_can_send;
|
goto check_can_send;
|
||||||
}
|
}
|
||||||
if (handshake_done_or_doing_zero_rtt(conn))
|
if (handshake_done_or_doing_sess_resume(conn))
|
||||||
{
|
{
|
||||||
TAILQ_FOREACH(stream, &conn->fc_pub.write_streams,
|
TAILQ_FOREACH(stream, &conn->fc_pub.write_streams,
|
||||||
next_write_stream)
|
next_write_stream)
|
||||||
|
@ -4302,7 +4303,7 @@ lsquic_gquic_full_conn_srej (struct lsquic_conn *lconn)
|
||||||
struct lsquic_stream *stream;
|
struct lsquic_stream *stream;
|
||||||
enum lsquic_version version;
|
enum lsquic_version version;
|
||||||
|
|
||||||
if (lconn->cn_esf_c->esf_is_zero_rtt_enabled(conn->fc_conn.cn_enc_session))
|
if (lconn->cn_esf_c->esf_is_sess_resume_enabled(conn->fc_conn.cn_enc_session))
|
||||||
{
|
{
|
||||||
/* We need to do this because we do not clean up any data that may
|
/* We need to do this because we do not clean up any data that may
|
||||||
* have been already sent. This is left an optimization for the
|
* have been already sent. This is left an optimization for the
|
||||||
|
@ -4310,7 +4311,7 @@ lsquic_gquic_full_conn_srej (struct lsquic_conn *lconn)
|
||||||
*/
|
*/
|
||||||
LSQ_DEBUG("received SREJ when 0RTT was on: fail handshake and let "
|
LSQ_DEBUG("received SREJ when 0RTT was on: fail handshake and let "
|
||||||
"caller retry");
|
"caller retry");
|
||||||
full_conn_ci_hsk_done(lconn, LSQ_HSK_0RTT_FAIL);
|
full_conn_ci_hsk_done(lconn, LSQ_HSK_RESUMED_FAIL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,14 +11,14 @@ lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *,
|
||||||
unsigned flags /* Only FC_SERVER and FC_HTTP */,
|
unsigned flags /* Only FC_SERVER and FC_HTTP */,
|
||||||
const char *hostname, unsigned short max_packet_size,
|
const char *hostname, unsigned short max_packet_size,
|
||||||
int is_ipv4,
|
int is_ipv4,
|
||||||
const unsigned char *zero_rtt, size_t zero_rtt_len);
|
const unsigned char *sess_resume, size_t sess_resume_len);
|
||||||
|
|
||||||
struct lsquic_conn *
|
struct lsquic_conn *
|
||||||
lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *,
|
lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *,
|
||||||
unsigned versions,
|
unsigned versions,
|
||||||
unsigned flags /* Only FC_SERVER and FC_HTTP */,
|
unsigned flags /* Only FC_SERVER and FC_HTTP */,
|
||||||
const char *hostname, unsigned short max_packet_size, int is_ipv4,
|
const char *hostname, unsigned short max_packet_size, int is_ipv4,
|
||||||
const unsigned char *zero_rtt, size_t,
|
const unsigned char *sess_resume, size_t,
|
||||||
const unsigned char *token, size_t);
|
const unsigned char *token, size_t);
|
||||||
|
|
||||||
typedef struct lsquic_conn *
|
typedef struct lsquic_conn *
|
||||||
|
|
|
@ -1158,12 +1158,12 @@ struct lsquic_conn *
|
||||||
lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
|
lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
|
||||||
unsigned versions, unsigned flags,
|
unsigned versions, unsigned flags,
|
||||||
const char *hostname, unsigned short max_packet_size, int is_ipv4,
|
const char *hostname, unsigned short max_packet_size, int is_ipv4,
|
||||||
const unsigned char *zero_rtt, size_t zero_rtt_sz,
|
const unsigned char *sess_resume, size_t sess_resume_sz,
|
||||||
const unsigned char *token, size_t token_sz)
|
const unsigned char *token, size_t token_sz)
|
||||||
{
|
{
|
||||||
const struct enc_session_funcs_iquic *esfi;
|
const struct enc_session_funcs_iquic *esfi;
|
||||||
struct ietf_full_conn *conn;
|
struct ietf_full_conn *conn;
|
||||||
enum lsquic_version ver, zero_rtt_version;
|
enum lsquic_version ver, sess_resume_version;
|
||||||
lsquic_time_t now;
|
lsquic_time_t now;
|
||||||
|
|
||||||
conn = calloc(1, sizeof(*conn));
|
conn = calloc(1, sizeof(*conn));
|
||||||
|
@ -1181,11 +1181,11 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
|
||||||
assert(versions);
|
assert(versions);
|
||||||
versions &= LSQUIC_IETF_VERSIONS;
|
versions &= LSQUIC_IETF_VERSIONS;
|
||||||
ver = highest_bit_set(versions);
|
ver = highest_bit_set(versions);
|
||||||
if (zero_rtt)
|
if (sess_resume)
|
||||||
{
|
{
|
||||||
zero_rtt_version = lsquic_zero_rtt_version(zero_rtt, zero_rtt_sz);
|
sess_resume_version = lsquic_sess_resume_version(sess_resume, sess_resume_sz);
|
||||||
if (zero_rtt_version < N_LSQVER && ((1 << zero_rtt_version) & versions))
|
if (sess_resume_version < N_LSQVER && ((1 << sess_resume_version) & versions))
|
||||||
ver = zero_rtt_version;
|
ver = sess_resume_version;
|
||||||
}
|
}
|
||||||
esfi = select_esf_iquic_by_ver(ver);
|
esfi = select_esf_iquic_by_ver(ver);
|
||||||
|
|
||||||
|
@ -1252,7 +1252,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
|
||||||
conn->ifc_enpub, &conn->ifc_conn, CUR_DCID(conn),
|
conn->ifc_enpub, &conn->ifc_conn, CUR_DCID(conn),
|
||||||
&conn->ifc_u.cli.ifcli_ver_neg,
|
&conn->ifc_u.cli.ifcli_ver_neg,
|
||||||
(void **) conn->ifc_u.cli.crypto_streams, &crypto_stream_if,
|
(void **) conn->ifc_u.cli.crypto_streams, &crypto_stream_if,
|
||||||
zero_rtt, zero_rtt_sz, &conn->ifc_alset,
|
sess_resume, sess_resume_sz, &conn->ifc_alset,
|
||||||
conn->ifc_max_streams_in[SD_UNI]);
|
conn->ifc_max_streams_in[SD_UNI]);
|
||||||
if (!conn->ifc_conn.cn_enc_session)
|
if (!conn->ifc_conn.cn_enc_session)
|
||||||
goto err2;
|
goto err2;
|
||||||
|
@ -2560,6 +2560,7 @@ ietf_full_conn_ci_close (struct lsquic_conn *lconn)
|
||||||
}
|
}
|
||||||
conn->ifc_flags |= IFC_CLOSING;
|
conn->ifc_flags |= IFC_CLOSING;
|
||||||
conn->ifc_send_flags |= SF_SEND_CONN_CLOSE;
|
conn->ifc_send_flags |= SF_SEND_CONN_CLOSE;
|
||||||
|
lsquic_engine_add_conn_to_tickable(conn->ifc_enpub, lconn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3279,7 +3280,7 @@ ietf_full_conn_ci_hsk_done (struct lsquic_conn *lconn,
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case LSQ_HSK_OK:
|
case LSQ_HSK_OK:
|
||||||
case LSQ_HSK_0RTT_OK:
|
case LSQ_HSK_RESUMED_OK:
|
||||||
if (0 == handshake_ok(lconn))
|
if (0 == handshake_ok(lconn))
|
||||||
{
|
{
|
||||||
if (!(conn->ifc_flags & IFC_SERVER))
|
if (!(conn->ifc_flags & IFC_SERVER))
|
||||||
|
@ -3297,7 +3298,7 @@ ietf_full_conn_ci_hsk_done (struct lsquic_conn *lconn,
|
||||||
assert(0);
|
assert(0);
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case LSQ_HSK_FAIL:
|
case LSQ_HSK_FAIL:
|
||||||
case LSQ_HSK_0RTT_FAIL:
|
case LSQ_HSK_RESUMED_FAIL:
|
||||||
handshake_failed(lconn);
|
handshake_failed(lconn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7102,10 +7103,10 @@ ietf_full_conn_ci_n_avail_streams (const struct lsquic_conn *lconn)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_done_or_doing_zero_rtt (const struct ietf_full_conn *conn)
|
handshake_done_or_doing_sess_resume (const struct ietf_full_conn *conn)
|
||||||
{
|
{
|
||||||
return (conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|
return (conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|
||||||
|| conn->ifc_conn.cn_esf_c->esf_is_zero_rtt_enabled(
|
|| conn->ifc_conn.cn_esf_c->esf_is_sess_resume_enabled(
|
||||||
conn->ifc_conn.cn_enc_session);
|
conn->ifc_conn.cn_enc_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7115,7 +7116,7 @@ ietf_full_conn_ci_make_stream (struct lsquic_conn *lconn)
|
||||||
{
|
{
|
||||||
struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn;
|
struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn;
|
||||||
|
|
||||||
if (handshake_done_or_doing_zero_rtt(conn)
|
if (handshake_done_or_doing_sess_resume(conn)
|
||||||
&& ietf_full_conn_ci_n_avail_streams(lconn) > 0)
|
&& ietf_full_conn_ci_n_avail_streams(lconn) > 0)
|
||||||
{
|
{
|
||||||
if (0 != create_bidi_stream_out(conn))
|
if (0 != create_bidi_stream_out(conn))
|
||||||
|
|
|
@ -201,7 +201,7 @@ typedef struct c_cert_item_st
|
||||||
} c_cert_item_t;
|
} c_cert_item_t;
|
||||||
|
|
||||||
|
|
||||||
struct lsquic_zero_rtt_storage
|
struct lsquic_sess_resume_storage
|
||||||
{
|
{
|
||||||
uint32_t quic_version_tag;
|
uint32_t quic_version_tag;
|
||||||
uint32_t serializer_version;
|
uint32_t serializer_version;
|
||||||
|
@ -592,7 +592,7 @@ enum rtt_deserialize_return_type
|
||||||
#define RTT_SERIALIZER_VERSION (1 << 0)
|
#define RTT_SERIALIZER_VERSION (1 << 0)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lsquic_enc_session_serialize_zero_rtt(struct lsquic_zero_rtt_storage *storage,
|
lsquic_enc_session_serialize_sess_resume(struct lsquic_sess_resume_storage *storage,
|
||||||
enum lsquic_version version,
|
enum lsquic_version version,
|
||||||
const lsquic_session_cache_info_t *info,
|
const lsquic_session_cache_info_t *info,
|
||||||
const c_cert_item_t *cert_item)
|
const c_cert_item_t *cert_item)
|
||||||
|
@ -643,8 +643,8 @@ lsquic_enc_session_serialize_zero_rtt(struct lsquic_zero_rtt_storage *storage,
|
||||||
} while (0) \
|
} while (0) \
|
||||||
|
|
||||||
static enum rtt_deserialize_return_type
|
static enum rtt_deserialize_return_type
|
||||||
lsquic_enc_session_deserialize_zero_rtt(
|
lsquic_enc_session_deserialize_sess_resume(
|
||||||
const struct lsquic_zero_rtt_storage *storage,
|
const struct lsquic_sess_resume_storage *storage,
|
||||||
size_t storage_size,
|
size_t storage_size,
|
||||||
const struct lsquic_engine_settings *settings,
|
const struct lsquic_engine_settings *settings,
|
||||||
lsquic_session_cache_info_t *info,
|
lsquic_session_cache_info_t *info,
|
||||||
|
@ -824,12 +824,12 @@ maybe_log_secrets (struct lsquic_enc_session *enc_session)
|
||||||
static enc_session_t *
|
static enc_session_t *
|
||||||
lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
|
lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
|
||||||
lsquic_cid_t cid, const struct lsquic_engine_public *enpub,
|
lsquic_cid_t cid, const struct lsquic_engine_public *enpub,
|
||||||
const unsigned char *zero_rtt, size_t zero_rtt_len)
|
const unsigned char *sess_resume, size_t sess_resume_len)
|
||||||
{
|
{
|
||||||
lsquic_session_cache_info_t *info;
|
lsquic_session_cache_info_t *info;
|
||||||
struct lsquic_enc_session *enc_session;
|
struct lsquic_enc_session *enc_session;
|
||||||
c_cert_item_t *item;
|
c_cert_item_t *item;
|
||||||
const struct lsquic_zero_rtt_storage *zero_rtt_storage;
|
const struct lsquic_sess_resume_storage *sess_resume_storage;
|
||||||
|
|
||||||
if (!domain)
|
if (!domain)
|
||||||
{
|
{
|
||||||
|
@ -849,7 +849,7 @@ lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zero_rtt && zero_rtt_len > sizeof(struct lsquic_zero_rtt_storage))
|
if (sess_resume && sess_resume_len > sizeof(struct lsquic_sess_resume_storage))
|
||||||
{
|
{
|
||||||
item = calloc(1, sizeof(*item));
|
item = calloc(1, sizeof(*item));
|
||||||
if (!item)
|
if (!item)
|
||||||
|
@ -858,22 +858,22 @@ lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
|
||||||
free(info);
|
free(info);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
zero_rtt_storage = (const struct lsquic_zero_rtt_storage *)zero_rtt;
|
sess_resume_storage = (const struct lsquic_sess_resume_storage *)sess_resume;
|
||||||
switch (lsquic_enc_session_deserialize_zero_rtt(zero_rtt_storage,
|
switch (lsquic_enc_session_deserialize_sess_resume(sess_resume_storage,
|
||||||
zero_rtt_len,
|
sess_resume_len,
|
||||||
&enpub->enp_settings,
|
&enpub->enp_settings,
|
||||||
info, item))
|
info, item))
|
||||||
{
|
{
|
||||||
case RTT_DESERIALIZE_BAD_QUIC_VER:
|
case RTT_DESERIALIZE_BAD_QUIC_VER:
|
||||||
LSQ_ERROR("provided zero_rtt has unsupported QUIC version");
|
LSQ_ERROR("provided sess_resume has unsupported QUIC version");
|
||||||
free(item);
|
free(item);
|
||||||
break;
|
break;
|
||||||
case RTT_DESERIALIZE_BAD_SERIAL_VER:
|
case RTT_DESERIALIZE_BAD_SERIAL_VER:
|
||||||
LSQ_ERROR("provided zero_rtt has bad serializer version");
|
LSQ_ERROR("provided sess_resume has bad serializer version");
|
||||||
free(item);
|
free(item);
|
||||||
break;
|
break;
|
||||||
case RTT_DESERIALIZE_BAD_CERT_SIZE:
|
case RTT_DESERIALIZE_BAD_CERT_SIZE:
|
||||||
LSQ_ERROR("provided zero_rtt has bad cert size");
|
LSQ_ERROR("provided sess_resume has bad cert size");
|
||||||
free(item);
|
free(item);
|
||||||
break;
|
break;
|
||||||
case RTT_DESERIALIZE_OK:
|
case RTT_DESERIALIZE_OK:
|
||||||
|
@ -2728,7 +2728,7 @@ lsquic_enc_session_handle_chlo_reply (enc_session_t *enc_session_p,
|
||||||
enc_session->hsk_state = HSK_COMPLETED;
|
enc_session->hsk_state = HSK_COMPLETED;
|
||||||
EV_LOG_HSK_COMPLETED(&enc_session->cid);
|
EV_LOG_HSK_COMPLETED(&enc_session->cid);
|
||||||
if (!(enc_session->es_flags & ES_RECV_REJ))
|
if (!(enc_session->es_flags & ES_RECV_REJ))
|
||||||
EV_LOG_ZERO_RTT(&enc_session->cid);
|
EV_LOG_SESSION_RESUMPTION(&enc_session->cid);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = 1; /* XXX Why 1? */
|
ret = 1; /* XXX Why 1? */
|
||||||
|
@ -3599,7 +3599,7 @@ lsquic_enc_session_verify_reset_token (enc_session_t *enc_session_p,
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lsquic_enc_session_did_zero_rtt_succeed (enc_session_t *enc_session_p)
|
lsquic_enc_session_did_sess_resume_succeed (enc_session_t *enc_session_p)
|
||||||
{
|
{
|
||||||
struct lsquic_enc_session *const enc_session = enc_session_p;
|
struct lsquic_enc_session *const enc_session = enc_session_p;
|
||||||
return !(enc_session->es_flags & ES_RECV_REJ);
|
return !(enc_session->es_flags & ES_RECV_REJ);
|
||||||
|
@ -3607,7 +3607,7 @@ lsquic_enc_session_did_zero_rtt_succeed (enc_session_t *enc_session_p)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lsquic_enc_session_is_zero_rtt_enabled (enc_session_t *enc_session_p)
|
lsquic_enc_session_is_sess_resume_enabled (enc_session_t *enc_session_p)
|
||||||
{
|
{
|
||||||
struct lsquic_enc_session *const enc_session = enc_session_p;
|
struct lsquic_enc_session *const enc_session = enc_session_p;
|
||||||
return enc_session->info && enc_session->cert_item;
|
return enc_session->info && enc_session->cert_item;
|
||||||
|
@ -3689,7 +3689,7 @@ lsquic_enc_session_get_server_cert_chain (enc_session_t *enc_session_p)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maybe_dispatch_zero_rtt (enc_session_t *enc_session_p,
|
maybe_dispatch_sess_resume (enc_session_t *enc_session_p,
|
||||||
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t))
|
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t))
|
||||||
{
|
{
|
||||||
struct lsquic_enc_session *const enc_session = enc_session_p;
|
struct lsquic_enc_session *const enc_session = enc_session_p;
|
||||||
|
@ -3700,7 +3700,7 @@ maybe_dispatch_zero_rtt (enc_session_t *enc_session_p,
|
||||||
|
|
||||||
if (!(enc_session->info && enc_session->cert_item && cb))
|
if (!(enc_session->info && enc_session->cert_item && cb))
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("no zero-rtt information or callback is not set");
|
LSQ_DEBUG("no session resumption information or callback is not set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3709,17 +3709,18 @@ maybe_dispatch_zero_rtt (enc_session_t *enc_session_p,
|
||||||
sz += sizeof(uint32_t);
|
sz += sizeof(uint32_t);
|
||||||
sz += lsquic_str_len(&enc_session->cert_item->crts[i]);
|
sz += lsquic_str_len(&enc_session->cert_item->crts[i]);
|
||||||
}
|
}
|
||||||
sz += sizeof(struct lsquic_zero_rtt_storage);
|
sz += sizeof(struct lsquic_sess_resume_storage);
|
||||||
|
|
||||||
buf = malloc(sz);
|
buf = malloc(sz);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
{
|
{
|
||||||
LSQ_WARN("malloc failed: cannot allocate %zu bytes for zero-rtt", sz);
|
LSQ_WARN("malloc failed: cannot allocate %zu bytes for session "
|
||||||
|
"resumption", sz);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lsquic_enc_session_serialize_zero_rtt(
|
lsquic_enc_session_serialize_sess_resume(
|
||||||
(struct lsquic_zero_rtt_storage *) buf, lconn->cn_version,
|
(struct lsquic_sess_resume_storage *) buf, lconn->cn_version,
|
||||||
enc_session->info, enc_session->cert_item);
|
enc_session->info, enc_session->cert_item);
|
||||||
|
|
||||||
cb(lconn, buf, sz);
|
cb(lconn, buf, sz);
|
||||||
|
@ -3796,8 +3797,8 @@ struct enc_session_funcs_common lsquic_enc_session_common_gquic_1 =
|
||||||
.esf_tag_len = GQUIC_PACKET_HASH_SZ,
|
.esf_tag_len = GQUIC_PACKET_HASH_SZ,
|
||||||
.esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
|
.esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
|
||||||
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
|
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
|
||||||
.esf_did_zero_rtt_succeed = lsquic_enc_session_did_zero_rtt_succeed,
|
.esf_did_sess_resume_succeed = lsquic_enc_session_did_sess_resume_succeed,
|
||||||
.esf_is_zero_rtt_enabled = lsquic_enc_session_is_zero_rtt_enabled,
|
.esf_is_sess_resume_enabled = lsquic_enc_session_is_sess_resume_enabled,
|
||||||
.esf_set_conn = gquic_esf_set_conn,
|
.esf_set_conn = gquic_esf_set_conn,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4225,8 +4226,8 @@ struct enc_session_funcs_common lsquic_enc_session_common_gquic_2 =
|
||||||
.esf_alg_keysize = lsquic_enc_session_alg_keysize,
|
.esf_alg_keysize = lsquic_enc_session_alg_keysize,
|
||||||
.esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
|
.esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
|
||||||
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
|
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
|
||||||
.esf_did_zero_rtt_succeed = lsquic_enc_session_did_zero_rtt_succeed,
|
.esf_did_sess_resume_succeed = lsquic_enc_session_did_sess_resume_succeed,
|
||||||
.esf_is_zero_rtt_enabled = lsquic_enc_session_is_zero_rtt_enabled,
|
.esf_is_sess_resume_enabled = lsquic_enc_session_is_sess_resume_enabled,
|
||||||
.esf_set_conn = gquic_esf_set_conn,
|
.esf_set_conn = gquic_esf_set_conn,
|
||||||
/* These are different from gquic_1: */
|
/* These are different from gquic_1: */
|
||||||
.esf_encrypt_packet = gquic2_esf_encrypt_packet,
|
.esf_encrypt_packet = gquic2_esf_encrypt_packet,
|
||||||
|
@ -4266,7 +4267,7 @@ struct enc_session_funcs_gquic lsquic_enc_session_gquic_gquic_1 =
|
||||||
.esf_gen_chlo = lsquic_enc_session_gen_chlo,
|
.esf_gen_chlo = lsquic_enc_session_gen_chlo,
|
||||||
.esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply,
|
.esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply,
|
||||||
.esf_mem_used = lsquic_enc_session_mem_used,
|
.esf_mem_used = lsquic_enc_session_mem_used,
|
||||||
.esf_maybe_dispatch_zero_rtt = maybe_dispatch_zero_rtt,
|
.esf_maybe_dispatch_sess_resume = maybe_dispatch_sess_resume,
|
||||||
.esf_reset_cid = lsquic_enc_session_reset_cid,
|
.esf_reset_cid = lsquic_enc_session_reset_cid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,6 @@ enum hsk_failure_reason
|
||||||
};
|
};
|
||||||
|
|
||||||
enum lsquic_version
|
enum lsquic_version
|
||||||
lsquic_zero_rtt_version (const unsigned char *, size_t);
|
lsquic_sess_resume_version (const unsigned char *, size_t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -590,7 +590,7 @@ ietf_mini_conn_ci_hsk_done (struct lsquic_conn *lconn,
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case LSQ_HSK_OK:
|
case LSQ_HSK_OK:
|
||||||
case LSQ_HSK_0RTT_OK:
|
case LSQ_HSK_RESUMED_OK:
|
||||||
conn->imc_flags |= IMC_HSK_OK;
|
conn->imc_flags |= IMC_HSK_OK;
|
||||||
conn->imc_conn.cn_flags |= LSCONN_HANDSHAKE_DONE;
|
conn->imc_conn.cn_flags |= LSCONN_HANDSHAKE_DONE;
|
||||||
LSQ_DEBUG("handshake OK");
|
LSQ_DEBUG("handshake OK");
|
||||||
|
|
|
@ -83,6 +83,7 @@ lsquic_qlog_create_connection (const lsquic_cid_t* cid,
|
||||||
lsquic_time_now(), ip_version, srcip, dstip, srcport, dstport);
|
lsquic_time_now(), ip_version, srcip, dstip, srcport, dstport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define QLOG_FRAME_DICT_PREFIX_COMMA ",{\"frame_type\":\""
|
#define QLOG_FRAME_DICT_PREFIX_COMMA ",{\"frame_type\":\""
|
||||||
#define QLOG_FRAME_DICT_PREFIX "{\"frame_type\":\""
|
#define QLOG_FRAME_DICT_PREFIX "{\"frame_type\":\""
|
||||||
#define QLOG_FRAME_DICT_SUFFIX "\"}"
|
#define QLOG_FRAME_DICT_SUFFIX "\"}"
|
||||||
|
@ -170,7 +171,7 @@ lsquic_qlog_hsk_completed (const lsquic_cid_t* cid)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lsquic_qlog_zero_rtt (const lsquic_cid_t* cid)
|
lsquic_qlog_sess_resume (const lsquic_cid_t* cid)
|
||||||
{
|
{
|
||||||
LCID("[%" PRIu64 ",\"RECOVERY\",\"RTT_UPDATE\",\"PACKET_RX\","
|
LCID("[%" PRIu64 ",\"RECOVERY\",\"RTT_UPDATE\",\"PACKET_RX\","
|
||||||
"{\"zero_rtt\":\"successful\"}]", lsquic_time_now());
|
"{\"zero_rtt\":\"successful\"}]", lsquic_time_now());
|
||||||
|
|
|
@ -80,7 +80,7 @@ void
|
||||||
lsquic_qlog_hsk_completed (const lsquic_cid_t *);
|
lsquic_qlog_hsk_completed (const lsquic_cid_t *);
|
||||||
|
|
||||||
void
|
void
|
||||||
lsquic_qlog_zero_rtt (const lsquic_cid_t *);
|
lsquic_qlog_sess_resume (const lsquic_cid_t *);
|
||||||
|
|
||||||
void
|
void
|
||||||
lsquic_qlog_check_certs (const lsquic_cid_t *, const lsquic_str_t **, size_t);
|
lsquic_qlog_check_certs (const lsquic_cid_t *, const lsquic_str_t **, size_t);
|
||||||
|
|
|
@ -412,7 +412,7 @@ lsquic_stream_destroy (lsquic_stream_t *);
|
||||||
* failure. The latter may be caused by flow control violation or
|
* failure. The latter may be caused by flow control violation or
|
||||||
* invalid stream frame data, e.g. overlapping segments.
|
* invalid stream frame data, e.g. overlapping segments.
|
||||||
*
|
*
|
||||||
* Note that the caller does gives up control of `frame' no matter
|
* Note that the caller gives up control of `frame' no matter
|
||||||
* what this function returns.
|
* what this function returns.
|
||||||
*
|
*
|
||||||
* This data is read by the user using lsquic_stream_read() function.
|
* This data is read by the user using lsquic_stream_read() function.
|
||||||
|
@ -436,9 +436,6 @@ lsquic_stream_rst_in (lsquic_stream_t *, uint64_t offset, uint64_t error_code);
|
||||||
void
|
void
|
||||||
lsquic_stream_stop_sending_in (struct lsquic_stream *, uint64_t error_code);
|
lsquic_stream_stop_sending_in (struct lsquic_stream *, uint64_t error_code);
|
||||||
|
|
||||||
ssize_t
|
|
||||||
lsquic_stream_read (lsquic_stream_t *stream, void *buf, size_t len);
|
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
lsquic_stream_read_offset (const lsquic_stream_t *stream);
|
lsquic_stream_read_offset (const lsquic_stream_t *stream);
|
||||||
|
|
||||||
|
@ -448,11 +445,6 @@ lsquic_stream_read_offset (const lsquic_stream_t *stream);
|
||||||
int
|
int
|
||||||
lsquic_stream_tosend_fin (const lsquic_stream_t *stream);
|
lsquic_stream_tosend_fin (const lsquic_stream_t *stream);
|
||||||
|
|
||||||
/* Data to be sent out to the network is written using lsquic_stream_write().
|
|
||||||
*/
|
|
||||||
ssize_t
|
|
||||||
lsquic_stream_write (lsquic_stream_t *stream, const void *buf, size_t len);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lsquic_stream_window_update (lsquic_stream_t *stream, uint64_t offset);
|
lsquic_stream_window_update (lsquic_stream_t *stream, uint64_t offset);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
struct ver_neg {
|
struct ver_neg {
|
||||||
unsigned vn_supp; /* Remaining options, including `vn_ver' */
|
unsigned vn_supp; /* Remaining options, including `vn_ver' */
|
||||||
enum lsquic_version vn_ver; /* If client, current version sent to server
|
enum lsquic_version vn_ver; /* If client, current version sent to server
|
||||||
* (zero_rtt version or highest supported);
|
* (sess_resume version or highest supported);
|
||||||
* if server, this is set to negotiated version.
|
* if server, this is set to negotiated version.
|
||||||
*/
|
*/
|
||||||
enum ver_neg_state {
|
enum ver_neg_state {
|
||||||
|
|
|
@ -44,7 +44,7 @@ main (void)
|
||||||
|
|
||||||
lsquic_qlog_packet_rx(&cid, NULL, NULL, 0);
|
lsquic_qlog_packet_rx(&cid, NULL, NULL, 0);
|
||||||
lsquic_qlog_hsk_completed(&cid);
|
lsquic_qlog_hsk_completed(&cid);
|
||||||
lsquic_qlog_zero_rtt(&cid);
|
lsquic_qlog_sess_resume(&cid);
|
||||||
lsquic_qlog_check_certs(&cid, NULL, 0);
|
lsquic_qlog_check_certs(&cid, NULL, 0);
|
||||||
|
|
||||||
lsquic_qlog_version_negotiation(&cid, NULL, NULL);
|
lsquic_qlog_version_negotiation(&cid, NULL, NULL);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue