Release 2.29.0
- [FEATURE] QUIC and HTTP/3 Internet Draft 34 support and v1 support. The latter is turned off by default. - Drop support for ID-28 and ID-32. - [BUGFIX] IETF QUIC mini conn receive history (trechist): allow unlimited inserts by dropping smallest elements. - [BUGFIX] gQUIC: set STTL to correct value, issue #226. - [BUGFIX] Account for poison packet gap when MTU probe was too large.
This commit is contained in:
parent
ac0ce07bd0
commit
26e8f082c9
|
@ -8,7 +8,7 @@ task:
|
||||||
- cd boringssl
|
- cd boringssl
|
||||||
# This is so that both GQUIC and IETF branches build. Just picking
|
# This is so that both GQUIC and IETF branches build. Just picking
|
||||||
# a known good revision:
|
# a known good revision:
|
||||||
- git checkout b117a3a0b7bd11fe6ebd503ec6b45d6b910b41a1
|
- git checkout a2278d4d2cabe73f6663e3299ea7808edfa306b9
|
||||||
- cmake .
|
- cmake .
|
||||||
- make
|
- make
|
||||||
- cd -
|
- cd -
|
||||||
|
|
|
@ -32,7 +32,7 @@ before_script:
|
||||||
- cd boringssl
|
- cd boringssl
|
||||||
# This is so that both GQUIC and IETF branches build. Just picking
|
# This is so that both GQUIC and IETF branches build. Just picking
|
||||||
# a known good revision:
|
# a known good revision:
|
||||||
- git checkout b117a3a0b7bd11fe6ebd503ec6b45d6b910b41a1
|
- git checkout a2278d4d2cabe73f6663e3299ea7808edfa306b9
|
||||||
- cmake .
|
- cmake .
|
||||||
- make
|
- make
|
||||||
- cd -
|
- cd -
|
||||||
|
|
10
CHANGELOG
10
CHANGELOG
|
@ -1,3 +1,13 @@
|
||||||
|
2021-02-10
|
||||||
|
- 2.29.0
|
||||||
|
- [FEATURE] QUIC and HTTP/3 Internet Draft 34 support and v1 support.
|
||||||
|
The latter is turned off by default.
|
||||||
|
- Drop support for ID-28 and ID-32.
|
||||||
|
- [BUGFIX] IETF QUIC mini conn receive history (trechist): allow
|
||||||
|
unlimited inserts by dropping smallest elements.
|
||||||
|
- [BUGFIX] gQUIC: set STTL to correct value, issue #226.
|
||||||
|
- [BUGFIX] Account for poison packet gap when MTU probe was too large.
|
||||||
|
|
||||||
2021-02-03
|
2021-02-03
|
||||||
- 2.28.0
|
- 2.28.0
|
||||||
- [API] lsquic_ssl_sess_to_resume_info() is the new way to get
|
- [API] lsquic_ssl_sess_to_resume_info() is the new way to get
|
||||||
|
|
|
@ -17,7 +17,7 @@ COPY ./ /src/lsquic/
|
||||||
|
|
||||||
RUN git clone https://boringssl.googlesource.com/boringssl && \
|
RUN git clone https://boringssl.googlesource.com/boringssl && \
|
||||||
cd boringssl && \
|
cd boringssl && \
|
||||||
git checkout b117a3a0b7bd11fe6ebd503ec6b45d6b910b41a1 && \
|
git checkout a2278d4d2cabe73f6663e3299ea7808edfa306b9 && \
|
||||||
cmake . && \
|
cmake . && \
|
||||||
make
|
make
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,9 @@ and HTTP/3 functionality for servers and clients. Most of the code in this
|
||||||
distribution is used in our own products: LiteSpeed Web Server, LiteSpeed ADC,
|
distribution is used in our own products: LiteSpeed Web Server, LiteSpeed ADC,
|
||||||
and OpenLiteSpeed.
|
and OpenLiteSpeed.
|
||||||
|
|
||||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-27, ID-28, ID-29,
|
Currently supported QUIC versions are v1 (disabled by default until the
|
||||||
and ID-32. Support for newer versions is added soon after they are released.
|
QUIC RFC is released); Internet-Draft versions 34, 29, and 27;
|
||||||
|
and the older "Google" QUIC versions Q043, Q046, an Q050.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
@ -48,7 +49,7 @@ You may need to install pre-requisites like zlib and libevent.
|
||||||
2. Use specific BoringSSL version
|
2. Use specific BoringSSL version
|
||||||
|
|
||||||
```
|
```
|
||||||
git checkout b117a3a0b7bd11fe6ebd503ec6b45d6b910b41a1
|
git checkout a2278d4d2cabe73f6663e3299ea7808edfa306b9
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Compile the library
|
3. Compile the library
|
||||||
|
|
|
@ -30,7 +30,7 @@ build_script:
|
||||||
|
|
||||||
cd boringssl
|
cd boringssl
|
||||||
|
|
||||||
git checkout b117a3a0b7bd11fe6ebd503ec6b45d6b910b41a1
|
git checkout a2278d4d2cabe73f6663e3299ea7808edfa306b9
|
||||||
|
|
||||||
cmake -DCMAKE_GENERATOR_PLATFORM=x64 --config Debug -DBUILD_SHARED_LIBS=OFF -DOPENSSL_NO_ASM=1 .
|
cmake -DCMAKE_GENERATOR_PLATFORM=x64 --config Debug -DBUILD_SHARED_LIBS=OFF -DOPENSSL_NO_ASM=1 .
|
||||||
|
|
||||||
|
|
|
@ -50,17 +50,18 @@ developed by the IETF. Both types are included in a single enum:
|
||||||
|
|
||||||
IETF QUIC version ID (Internet-Draft) 27; this version is deprecated.
|
IETF QUIC version ID (Internet-Draft) 27; this version is deprecated.
|
||||||
|
|
||||||
.. member:: LSQVER_ID28
|
|
||||||
|
|
||||||
IETF QUIC version ID 28; this version is deprecated.
|
|
||||||
|
|
||||||
.. member:: LSQVER_ID29
|
.. member:: LSQVER_ID29
|
||||||
|
|
||||||
IETF QUIC version ID 29
|
IETF QUIC version ID 29
|
||||||
|
|
||||||
.. member:: LSQVER_ID32
|
.. member:: LSQVER_ID34
|
||||||
|
|
||||||
IETF QUIC version ID 32
|
IETF QUIC version ID 34
|
||||||
|
|
||||||
|
.. member:: LSQVER_I001
|
||||||
|
|
||||||
|
IETF QUIC version 1. (This version is disabled by default until
|
||||||
|
the QUIC RFC is released).
|
||||||
|
|
||||||
.. member:: N_LSQVER
|
.. member:: N_LSQVER
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,9 @@ copyright = u'2021, LiteSpeed Technologies'
|
||||||
author = u'LiteSpeed Technologies'
|
author = u'LiteSpeed Technologies'
|
||||||
|
|
||||||
# The short X.Y version
|
# The short X.Y version
|
||||||
version = u'2.28'
|
version = u'2.29'
|
||||||
# The full version, including alpha/beta/rc tags
|
# The full version, including alpha/beta/rc tags
|
||||||
release = u'2.28.0'
|
release = u'2.29.0'
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|
|
@ -16,9 +16,9 @@ Most of the code in this distribution has been used in our own products
|
||||||
-- `LiteSpeed Web Server`_, `LiteSpeed Web ADC`_, and OpenLiteSpeed_ --
|
-- `LiteSpeed Web Server`_, `LiteSpeed Web ADC`_, and OpenLiteSpeed_ --
|
||||||
since 2017.
|
since 2017.
|
||||||
|
|
||||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-27, ID-28,
|
Currently supported QUIC versions are v1 (disabled by default until the
|
||||||
ID-29, and ID-32.
|
QUIC RFC is released); Internet-Draft versions 34, 29, and 27;
|
||||||
Support for newer versions will be added soon after they are released.
|
and the older "Google" QUIC versions Q043, Q046, an Q050.
|
||||||
|
|
||||||
LSQUIC is licensed under the `MIT License`_; see LICENSE in the source
|
LSQUIC is licensed under the `MIT License`_; see LICENSE in the source
|
||||||
distribution for details.
|
distribution for details.
|
||||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LSQUIC_MAJOR_VERSION 2
|
#define LSQUIC_MAJOR_VERSION 2
|
||||||
#define LSQUIC_MINOR_VERSION 28
|
#define LSQUIC_MINOR_VERSION 29
|
||||||
#define LSQUIC_PATCH_VERSION 0
|
#define LSQUIC_PATCH_VERSION 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,20 +81,21 @@ enum lsquic_version
|
||||||
*/
|
*/
|
||||||
LSQVER_ID27,
|
LSQVER_ID27,
|
||||||
|
|
||||||
/**
|
|
||||||
* IETF QUIC Draft-28; this version is deprecated.
|
|
||||||
*/
|
|
||||||
LSQVER_ID28,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IETF QUIC Draft-29
|
* IETF QUIC Draft-29
|
||||||
*/
|
*/
|
||||||
LSQVER_ID29,
|
LSQVER_ID29,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IETF QUIC Draft-32
|
* IETF QUIC Draft-34
|
||||||
*/
|
*/
|
||||||
LSQVER_ID32,
|
LSQVER_ID34,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IETF QUIC v1. Functionally the same as Draft-34, but marked
|
||||||
|
* experimental for now.
|
||||||
|
*/
|
||||||
|
LSQVER_I001,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special version to trigger version negotiation.
|
* Special version to trigger version negotiation.
|
||||||
|
@ -106,8 +107,8 @@ enum lsquic_version
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We currently support versions 43, 46, 50, Draft-27, Draft-28, Draft-29,
|
* We currently support versions 43, 46, 50, Draft-27, Draft-29, Draft-34,
|
||||||
* and Draft-32.
|
* and IETF QUIC v1.
|
||||||
* @see lsquic_version
|
* @see lsquic_version
|
||||||
*/
|
*/
|
||||||
#define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1)
|
#define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1)
|
||||||
|
@ -118,19 +119,21 @@ enum lsquic_version
|
||||||
#define LSQUIC_FORCED_TCID0_VERSIONS ((1 << LSQVER_046)|(1 << LSQVER_050))
|
#define LSQUIC_FORCED_TCID0_VERSIONS ((1 << LSQVER_046)|(1 << LSQVER_050))
|
||||||
|
|
||||||
#define LSQUIC_EXPERIMENTAL_VERSIONS ( \
|
#define LSQUIC_EXPERIMENTAL_VERSIONS ( \
|
||||||
|
(1 << LSQVER_I001) | \
|
||||||
(1 << LSQVER_VERNEG) | LSQUIC_EXPERIMENTAL_Q098)
|
(1 << LSQVER_VERNEG) | LSQUIC_EXPERIMENTAL_Q098)
|
||||||
|
|
||||||
#define LSQUIC_DEPRECATED_VERSIONS ((1 << LSQVER_ID27) | (1 << LSQVER_ID28))
|
#define LSQUIC_DEPRECATED_VERSIONS ((1 << LSQVER_ID27))
|
||||||
|
|
||||||
#define LSQUIC_GQUIC_HEADER_VERSIONS (1 << LSQVER_043)
|
#define LSQUIC_GQUIC_HEADER_VERSIONS (1 << LSQVER_043)
|
||||||
|
|
||||||
#define LSQUIC_IETF_VERSIONS ((1 << LSQVER_ID27) | (1 << LSQVER_ID28) \
|
#define LSQUIC_IETF_VERSIONS ((1 << LSQVER_ID27) \
|
||||||
| (1 << LSQVER_ID29) \
|
| (1 << LSQVER_ID29) \
|
||||||
| (1 << LSQVER_ID32) | (1 << LSQVER_VERNEG))
|
| (1 << LSQVER_ID34) \
|
||||||
|
| (1 << LSQVER_I001) | (1 << LSQVER_VERNEG))
|
||||||
|
|
||||||
#define LSQUIC_IETF_DRAFT_VERSIONS ((1 << LSQVER_ID27) | (1 << LSQVER_ID28) \
|
#define LSQUIC_IETF_DRAFT_VERSIONS ((1 << LSQVER_ID27) \
|
||||||
| (1 << LSQVER_ID29) \
|
| (1 << LSQVER_ID29) \
|
||||||
| (1 << LSQVER_ID32) | (1 << LSQVER_VERNEG))
|
| (1 << LSQVER_ID34) | (1 << LSQVER_VERNEG))
|
||||||
|
|
||||||
enum lsquic_hsk_status
|
enum lsquic_hsk_status
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,12 @@ while (<HEADER>) {
|
||||||
push @all_versions, $1;
|
push @all_versions, $1;
|
||||||
push @all_alpns, "h3-$2";
|
push @all_alpns, "h3-$2";
|
||||||
}
|
}
|
||||||
|
if (/^\s*(LSQVER_I(\d{3}))\b/) {
|
||||||
|
push @all_versions, $1;
|
||||||
|
if (not grep 'h3' eq $_, @all_alpns) {
|
||||||
|
push @all_alpns, "h3";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -339,9 +339,9 @@ extern const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1;
|
||||||
|
|
||||||
#define select_esf_common_by_ver(ver) ( \
|
#define select_esf_common_by_ver(ver) ( \
|
||||||
ver == LSQVER_ID27 ? &lsquic_enc_session_common_ietf_v1 : \
|
ver == LSQVER_ID27 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||||
ver == LSQVER_ID28 ? &lsquic_enc_session_common_ietf_v1 : \
|
|
||||||
ver == LSQVER_ID29 ? &lsquic_enc_session_common_ietf_v1 : \
|
ver == LSQVER_ID29 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||||
ver == LSQVER_ID32 ? &lsquic_enc_session_common_ietf_v1 : \
|
ver == LSQVER_ID34 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||||
|
ver == LSQVER_I001 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||||
ver == LSQVER_VERNEG ? &lsquic_enc_session_common_ietf_v1 : \
|
ver == LSQVER_VERNEG ? &lsquic_enc_session_common_ietf_v1 : \
|
||||||
ver == LSQVER_050 ? &lsquic_enc_session_common_gquic_2 : \
|
ver == LSQVER_050 ? &lsquic_enc_session_common_gquic_2 : \
|
||||||
&lsquic_enc_session_common_gquic_1 )
|
&lsquic_enc_session_common_gquic_1 )
|
||||||
|
|
|
@ -72,10 +72,10 @@ static const struct alpn_map {
|
||||||
const unsigned char *alpn;
|
const unsigned char *alpn;
|
||||||
} s_h3_alpns[] = {
|
} s_h3_alpns[] = {
|
||||||
{ LSQVER_ID27, (unsigned char *) "\x05h3-27", },
|
{ LSQVER_ID27, (unsigned char *) "\x05h3-27", },
|
||||||
{ LSQVER_ID28, (unsigned char *) "\x05h3-28", },
|
|
||||||
{ LSQVER_ID29, (unsigned char *) "\x05h3-29", },
|
{ LSQVER_ID29, (unsigned char *) "\x05h3-29", },
|
||||||
{ LSQVER_ID32, (unsigned char *) "\x05h3-32", },
|
{ LSQVER_ID34, (unsigned char *) "\x05h3-34", },
|
||||||
{ LSQVER_VERNEG, (unsigned char *) "\x05h3-32", },
|
{ LSQVER_I001, (unsigned char *) "\x02h3", },
|
||||||
|
{ LSQVER_VERNEG, (unsigned char *) "\x05h3-34", },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_sess_iquic;
|
struct enc_sess_iquic;
|
||||||
|
@ -926,6 +926,10 @@ iquic_esfi_create_client (const char *hostname,
|
||||||
ERR_error_string(ERR_get_error(), errbuf));
|
ERR_error_string(ERR_get_error(), errbuf));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
#if BORINGSSL_API_VERSION >= 13
|
||||||
|
SSL_set_quic_use_legacy_codepoint(enc_sess->esi_ssl,
|
||||||
|
enc_sess->esi_ver_neg->vn_ver < LSQVER_ID34);
|
||||||
|
#endif
|
||||||
|
|
||||||
transpa_len = gen_trans_params(enc_sess, trans_params,
|
transpa_len = gen_trans_params(enc_sess, trans_params,
|
||||||
sizeof(trans_params));
|
sizeof(trans_params));
|
||||||
|
@ -1109,6 +1113,7 @@ setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
|
||||||
struct header_prot *hp;
|
struct header_prot *hp;
|
||||||
size_t hsk_secret_sz, key_len;
|
size_t hsk_secret_sz, key_len;
|
||||||
unsigned cliser, i;
|
unsigned cliser, i;
|
||||||
|
const unsigned char *salt;
|
||||||
unsigned char hsk_secret[EVP_MAX_MD_SIZE];
|
unsigned char hsk_secret[EVP_MAX_MD_SIZE];
|
||||||
unsigned char secret[2][SHA256_DIGEST_LENGTH]; /* client, server */
|
unsigned char secret[2][SHA256_DIGEST_LENGTH]; /* client, server */
|
||||||
unsigned char key[2][EVP_MAX_KEY_LENGTH];
|
unsigned char key[2][EVP_MAX_KEY_LENGTH];
|
||||||
|
@ -1131,12 +1136,17 @@ setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
|
||||||
pair->ykp_thresh = IQUIC_INVALID_PACKNO;
|
pair->ykp_thresh = IQUIC_INVALID_PACKNO;
|
||||||
hp = &enc_sess->esi_hsk_hps[ENC_LEV_CLEAR];
|
hp = &enc_sess->esi_hsk_hps[ENC_LEV_CLEAR];
|
||||||
|
|
||||||
|
if (enc_sess->esi_conn->cn_version < LSQVER_ID29)
|
||||||
|
salt = HSK_SALT_PRE29;
|
||||||
|
else if (enc_sess->esi_conn->cn_version < LSQVER_ID34)
|
||||||
|
salt = HSK_SALT_PRE33;
|
||||||
|
else
|
||||||
|
salt = HSK_SALT;
|
||||||
HKDF_extract(hsk_secret, &hsk_secret_sz, md, cid->idbuf, cid->len,
|
HKDF_extract(hsk_secret, &hsk_secret_sz, md, cid->idbuf, cid->len,
|
||||||
enc_sess->esi_conn->cn_version < LSQVER_ID29
|
salt, HSK_SALT_SZ);
|
||||||
? HSK_SALT_PRE29 : HSK_SALT, HSK_SALT_SZ);
|
|
||||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("handshake salt: %s", HEXSTR(HSK_SALT, HSK_SALT_SZ, hexbuf));
|
LSQ_DEBUG("handshake salt: %s", HEXSTR(salt, HSK_SALT_SZ, hexbuf));
|
||||||
LSQ_DEBUG("handshake secret: %s", HEXSTR(hsk_secret, hsk_secret_sz,
|
LSQ_DEBUG("handshake secret: %s", HEXSTR(hsk_secret, hsk_secret_sz,
|
||||||
hexbuf));
|
hexbuf));
|
||||||
}
|
}
|
||||||
|
@ -1382,6 +1392,10 @@ iquic_esfi_init_server (enc_session_t *enc_session_p)
|
||||||
ERR_error_string(ERR_get_error(), u.errbuf));
|
ERR_error_string(ERR_get_error(), u.errbuf));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#if BORINGSSL_API_VERSION >= 13
|
||||||
|
SSL_set_quic_use_legacy_codepoint(enc_sess->esi_ssl,
|
||||||
|
enc_sess->esi_conn->cn_version < LSQVER_ID34);
|
||||||
|
#endif
|
||||||
if (!(SSL_set_quic_method(enc_sess->esi_ssl, &cry_quic_method)))
|
if (!(SSL_set_quic_method(enc_sess->esi_ssl, &cry_quic_method)))
|
||||||
{
|
{
|
||||||
LSQ_INFO("could not set stream method");
|
LSQ_INFO("could not set stream method");
|
||||||
|
@ -3327,6 +3341,9 @@ const unsigned char *const lsquic_retry_key_buf[N_IETF_RETRY_VERSIONS] =
|
||||||
/* [draft-ietf-quic-tls-29] Section 5.8 */
|
/* [draft-ietf-quic-tls-29] Section 5.8 */
|
||||||
(unsigned char *)
|
(unsigned char *)
|
||||||
"\xcc\xce\x18\x7e\xd0\x9a\x09\xd0\x57\x28\x15\x5a\x6c\xb9\x6b\xe1",
|
"\xcc\xce\x18\x7e\xd0\x9a\x09\xd0\x57\x28\x15\x5a\x6c\xb9\x6b\xe1",
|
||||||
|
/* [draft-ietf-quic-tls-33] Section 5.8 */
|
||||||
|
(unsigned char *)
|
||||||
|
"\xbe\x0c\x69\x0b\x9f\x66\x57\x5a\x1d\x76\x6b\x54\xe3\x68\xc8\x4e",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -3336,6 +3353,8 @@ const unsigned char *const lsquic_retry_nonce_buf[N_IETF_RETRY_VERSIONS] =
|
||||||
(unsigned char *) "\x4d\x16\x11\xd0\x55\x13\xa5\x52\xc5\x87\xd5\x75",
|
(unsigned char *) "\x4d\x16\x11\xd0\x55\x13\xa5\x52\xc5\x87\xd5\x75",
|
||||||
/* [draft-ietf-quic-tls-29] Section 5.8 */
|
/* [draft-ietf-quic-tls-29] Section 5.8 */
|
||||||
(unsigned char *) "\xe5\x49\x30\xf9\x7f\x21\x36\xf0\x53\x0a\x8c\x1c",
|
(unsigned char *) "\xe5\x49\x30\xf9\x7f\x21\x36\xf0\x53\x0a\x8c\x1c",
|
||||||
|
/* [draft-ietf-quic-tls-33] Section 5.8 */
|
||||||
|
(unsigned char *) "\x46\x15\x99\xd3\x5d\x63\x2b\xf2\x23\x98\x25\xbb",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -674,7 +674,7 @@ lsquic_engine_new (unsigned flags,
|
||||||
{
|
{
|
||||||
int sz = lsquic_enc_sess_ietf_gen_quic_ctx(
|
int sz = lsquic_enc_sess_ietf_gen_quic_ctx(
|
||||||
&engine->pub.enp_settings,
|
&engine->pub.enp_settings,
|
||||||
i == 0 ? LSQVER_ID27 : LSQVER_ID28,
|
i == 0 ? LSQVER_ID27 : LSQVER_ID29,
|
||||||
engine->pub.enp_quic_ctx_buf[i],
|
engine->pub.enp_quic_ctx_buf[i],
|
||||||
sizeof(engine->pub.enp_quic_ctx_buf));
|
sizeof(engine->pub.enp_quic_ctx_buf));
|
||||||
if (sz < 0)
|
if (sz < 0)
|
||||||
|
|
|
@ -3314,7 +3314,7 @@ try_to_begin_migration (struct ietf_full_conn *conn,
|
||||||
return BM_NOT_MIGRATING;
|
return BM_NOT_MIGRATING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->ifc_conn.cn_version <= LSQVER_ID28 /* Starting with ID-29,
|
if (conn->ifc_conn.cn_version <= LSQVER_ID27 /* Starting with ID-29,
|
||||||
disable_active_migration TP applies only to the time period during
|
disable_active_migration TP applies only to the time period during
|
||||||
the handshake. Our client does not migrate during the handshake:
|
the handshake. Our client does not migrate during the handshake:
|
||||||
this code runs only after handshake has succeeded. */
|
this code runs only after handshake has succeeded. */
|
||||||
|
@ -7566,16 +7566,16 @@ process_incoming_packet_verneg (struct ietf_full_conn *conn,
|
||||||
*/
|
*/
|
||||||
if (!verneg_ok(conn))
|
if (!verneg_ok(conn))
|
||||||
{
|
{
|
||||||
ABORT_ERROR("version negotiation not permitted in this version "
|
ABORT_WITH_FLAG(conn, LSQ_LOG_NOTICE, IFC_ERROR,
|
||||||
"of QUIC");
|
"version negotiation not permitted in this version of QUIC");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
versions &= conn->ifc_u.cli.ifcli_ver_neg.vn_supp;
|
versions &= conn->ifc_u.cli.ifcli_ver_neg.vn_supp;
|
||||||
if (0 == versions)
|
if (0 == versions)
|
||||||
{
|
{
|
||||||
ABORT_ERROR("client does not support any of the server-specified "
|
ABORT_WITH_FLAG(conn, LSQ_LOG_NOTICE, IFC_ERROR,
|
||||||
"versions");
|
"client does not support any of the server-specified versions");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7663,13 +7663,12 @@ ietf_full_conn_ci_packet_too_large (struct lsquic_conn *lconn,
|
||||||
assert(packet_out->po_lflags & POL_HEADER_PROT);
|
assert(packet_out->po_lflags & POL_HEADER_PROT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lsquic_senhist_add(&conn->ifc_send_ctl.sc_senhist, packet_out->po_packno);
|
|
||||||
lsquic_send_ctl_sanity_check(&conn->ifc_send_ctl);
|
|
||||||
if (packet_out->po_flags & PO_MTU_PROBE)
|
if (packet_out->po_flags & PO_MTU_PROBE)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("%zu-byte MTU probe in packet %"PRIu64" is too large",
|
LSQ_DEBUG("%zu-byte MTU probe in packet %"PRIu64" is too large",
|
||||||
lsquic_packet_out_sent_sz(&conn->ifc_conn, packet_out),
|
lsquic_packet_out_sent_sz(&conn->ifc_conn, packet_out),
|
||||||
packet_out->po_packno);
|
packet_out->po_packno);
|
||||||
|
lsquic_send_ctl_mtu_not_sent(&conn->ifc_send_ctl, packet_out);
|
||||||
mtu_probe_too_large(conn, packet_out);
|
mtu_probe_too_large(conn, packet_out);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -9041,7 +9040,7 @@ on_goaway_server_27 (void *ctx, uint64_t stream_id)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_goaway_client_28 (void *ctx, uint64_t stream_id)
|
on_goaway_client_27 (void *ctx, uint64_t stream_id)
|
||||||
{
|
{
|
||||||
struct ietf_full_conn *const conn = ctx;
|
struct ietf_full_conn *const conn = ctx;
|
||||||
struct lsquic_stream *stream;
|
struct lsquic_stream *stream;
|
||||||
|
@ -9348,30 +9347,7 @@ static const struct hcsi_callbacks hcsi_callbacks_client_27 =
|
||||||
.on_max_push_id = on_max_push_id_client,
|
.on_max_push_id = on_max_push_id_client,
|
||||||
.on_settings_frame = on_settings_frame,
|
.on_settings_frame = on_settings_frame,
|
||||||
.on_setting = on_setting,
|
.on_setting = on_setting,
|
||||||
.on_goaway = on_goaway_client_28 /* sic */,
|
.on_goaway = on_goaway_client_27,
|
||||||
.on_unexpected_frame = on_unexpected_frame,
|
|
||||||
.on_priority_update = on_priority_update_client,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const struct hcsi_callbacks hcsi_callbacks_server_28 =
|
|
||||||
{
|
|
||||||
.on_cancel_push = on_cancel_push_server,
|
|
||||||
.on_max_push_id = on_max_push_id,
|
|
||||||
.on_settings_frame = on_settings_frame,
|
|
||||||
.on_setting = on_setting,
|
|
||||||
.on_goaway = on_goaway_server /* sic */,
|
|
||||||
.on_unexpected_frame = on_unexpected_frame,
|
|
||||||
.on_priority_update = on_priority_update_server,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hcsi_callbacks hcsi_callbacks_client_28 =
|
|
||||||
{
|
|
||||||
.on_cancel_push = on_cancel_push_client,
|
|
||||||
.on_max_push_id = on_max_push_id_client,
|
|
||||||
.on_settings_frame = on_settings_frame,
|
|
||||||
.on_setting = on_setting,
|
|
||||||
.on_goaway = on_goaway_client_28,
|
|
||||||
.on_unexpected_frame = on_unexpected_frame,
|
.on_unexpected_frame = on_unexpected_frame,
|
||||||
.on_priority_update = on_priority_update_client,
|
.on_priority_update = on_priority_update_client,
|
||||||
};
|
};
|
||||||
|
@ -9416,21 +9392,17 @@ hcsi_on_new (void *stream_if_ctx, struct lsquic_stream *stream)
|
||||||
case (1 << 8) | LSQVER_ID27:
|
case (1 << 8) | LSQVER_ID27:
|
||||||
callbacks = &hcsi_callbacks_server_27;
|
callbacks = &hcsi_callbacks_server_27;
|
||||||
break;
|
break;
|
||||||
case (0 << 8) | LSQVER_ID28:
|
|
||||||
callbacks = &hcsi_callbacks_client_28;
|
|
||||||
break;
|
|
||||||
case (1 << 8) | LSQVER_ID28:
|
|
||||||
callbacks = &hcsi_callbacks_server_28;
|
|
||||||
break;
|
|
||||||
case (0 << 8) | LSQVER_ID29:
|
case (0 << 8) | LSQVER_ID29:
|
||||||
case (0 << 8) | LSQVER_ID32:
|
case (0 << 8) | LSQVER_ID34:
|
||||||
|
case (0 << 8) | LSQVER_I001:
|
||||||
callbacks = &hcsi_callbacks_client_29;
|
callbacks = &hcsi_callbacks_client_29;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
/* fallthru */
|
/* fallthru */
|
||||||
case (1 << 8) | LSQVER_ID29:
|
case (1 << 8) | LSQVER_ID29:
|
||||||
case (1 << 8) | LSQVER_ID32:
|
case (1 << 8) | LSQVER_ID34:
|
||||||
|
case (1 << 8) | LSQVER_I001:
|
||||||
callbacks = &hcsi_callbacks_server_29;
|
callbacks = &hcsi_callbacks_server_29;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1963,13 +1963,12 @@ gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
|
||||||
int len;
|
int len;
|
||||||
EVP_PKEY * rsa_priv_key;
|
EVP_PKEY * rsa_priv_key;
|
||||||
SSL_CTX *ctx = enc_session->ssl_ctx;
|
SSL_CTX *ctx = enc_session->ssl_ctx;
|
||||||
const struct lsquic_engine_settings *const settings =
|
|
||||||
&enc_session->enpub->enp_settings;
|
|
||||||
hs_ctx_t *const hs_ctx = &enc_session->hs_ctx;
|
hs_ctx_t *const hs_ctx = &enc_session->hs_ctx;
|
||||||
int scfg_len = enc_session->server_config->lsc_scfg->info.scfg_len;
|
int scfg_len = enc_session->server_config->lsc_scfg->info.scfg_len;
|
||||||
uint8_t *scfg_data = enc_session->server_config->lsc_scfg->scfg;
|
uint8_t *scfg_data = enc_session->server_config->lsc_scfg->scfg;
|
||||||
size_t msg_len;
|
size_t msg_len;
|
||||||
struct message_writer mw;
|
struct message_writer mw;
|
||||||
|
uint64_t sttl;
|
||||||
|
|
||||||
rsa_priv_key = SSL_CTX_get0_privatekey(ctx);
|
rsa_priv_key = SSL_CTX_get0_privatekey(ctx);
|
||||||
if (!rsa_priv_key)
|
if (!rsa_priv_key)
|
||||||
|
@ -2029,7 +2028,7 @@ gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
|
||||||
MSG_LEN_ADD(msg_len, scfg_len);
|
MSG_LEN_ADD(msg_len, scfg_len);
|
||||||
MSG_LEN_ADD(msg_len, STK_LENGTH);
|
MSG_LEN_ADD(msg_len, STK_LENGTH);
|
||||||
MSG_LEN_ADD(msg_len, SNO_LENGTH);
|
MSG_LEN_ADD(msg_len, SNO_LENGTH);
|
||||||
MSG_LEN_ADD(msg_len, sizeof(settings->es_sttl));
|
MSG_LEN_ADD(msg_len, sizeof(sttl));
|
||||||
MSG_LEN_ADD(msg_len, lsquic_str_len(&hs_ctx->prof));
|
MSG_LEN_ADD(msg_len, lsquic_str_len(&hs_ctx->prof));
|
||||||
if (hs_ctx->ccert)
|
if (hs_ctx->ccert)
|
||||||
MSG_LEN_ADD(msg_len, hs_ctx->ccert->len);
|
MSG_LEN_ADD(msg_len, hs_ctx->ccert->len);
|
||||||
|
@ -2055,6 +2054,8 @@ gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
|
||||||
lsquic_str_setlen(&enc_session->ssno, SNO_LENGTH);
|
lsquic_str_setlen(&enc_session->ssno, SNO_LENGTH);
|
||||||
}
|
}
|
||||||
RAND_bytes((uint8_t *) lsquic_str_buf(&enc_session->ssno), SNO_LENGTH);
|
RAND_bytes((uint8_t *) lsquic_str_buf(&enc_session->ssno), SNO_LENGTH);
|
||||||
|
sttl = enc_session->enpub->enp_server_config->lsc_scfg->info.expy
|
||||||
|
- (uint64_t) time(NULL);
|
||||||
|
|
||||||
MW_BEGIN(&mw, QTAG_REJ, 7, data);
|
MW_BEGIN(&mw, QTAG_REJ, 7, data);
|
||||||
MW_WRITE_LS_STR(&mw, QTAG_STK, &enc_session->sstk);
|
MW_WRITE_LS_STR(&mw, QTAG_STK, &enc_session->sstk);
|
||||||
|
@ -2062,8 +2063,7 @@ gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
|
||||||
MW_WRITE_LS_STR(&mw, QTAG_PROF, &hs_ctx->prof);
|
MW_WRITE_LS_STR(&mw, QTAG_PROF, &hs_ctx->prof);
|
||||||
MW_WRITE_BUFFER(&mw, QTAG_SCFG, scfg_data, scfg_len);
|
MW_WRITE_BUFFER(&mw, QTAG_SCFG, scfg_data, scfg_len);
|
||||||
MW_WRITE_BUFFER(&mw, QTAG_RREJ, &hs_ctx->rrej, sizeof(hs_ctx->rrej));
|
MW_WRITE_BUFFER(&mw, QTAG_RREJ, &hs_ctx->rrej, sizeof(hs_ctx->rrej));
|
||||||
MW_WRITE_BUFFER(&mw, QTAG_STTL, &settings->es_sttl,
|
MW_WRITE_BUFFER(&mw, QTAG_STTL, &sttl, sizeof(sttl));
|
||||||
sizeof(settings->es_sttl));
|
|
||||||
if (hs_ctx->ccert)
|
if (hs_ctx->ccert)
|
||||||
MW_WRITE_BUFFER(&mw, QTAG_CRT, hs_ctx->ccert->buf, hs_ctx->ccert->len);
|
MW_WRITE_BUFFER(&mw, QTAG_CRT, hs_ctx->ccert->buf, hs_ctx->ccert->len);
|
||||||
MW_END(&mw);
|
MW_END(&mw);
|
||||||
|
|
|
@ -7,9 +7,13 @@
|
||||||
"\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02"
|
"\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02"
|
||||||
#define HSK_SALT_PRE29 ((unsigned char *) HSK_SALT_BUF)
|
#define HSK_SALT_PRE29 ((unsigned char *) HSK_SALT_BUF)
|
||||||
/* [draft-ietf-quic-tls-29] Section 5.2 */
|
/* [draft-ietf-quic-tls-29] Section 5.2 */
|
||||||
#define HSK_SALT ((unsigned char *) \
|
#define HSK_SALT_PRE33 ((unsigned char *) \
|
||||||
"\xaf\xbf\xec\x28\x99\x93\xd2\x4c\x9e\x97" \
|
"\xaf\xbf\xec\x28\x99\x93\xd2\x4c\x9e\x97" \
|
||||||
"\x86\xf1\x9c\x61\x11\xe0\x43\x90\xa8\x99")
|
"\x86\xf1\x9c\x61\x11\xe0\x43\x90\xa8\x99")
|
||||||
|
/* [draft-ietf-quic-tls-33] Section 5.2 */
|
||||||
|
#define HSK_SALT ((unsigned char *) \
|
||||||
|
"\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17" \
|
||||||
|
"\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a")
|
||||||
#define HSK_SALT_SZ (sizeof(HSK_SALT_BUF) - 1)
|
#define HSK_SALT_SZ (sizeof(HSK_SALT_BUF) - 1)
|
||||||
|
|
||||||
#define CLIENT_LABEL "client in"
|
#define CLIENT_LABEL "client in"
|
||||||
|
|
|
@ -78,6 +78,7 @@ enum http_error_code
|
||||||
HEC_REQUEST_REJECTED = 0x10B,
|
HEC_REQUEST_REJECTED = 0x10B,
|
||||||
HEC_REQUEST_CANCELLED = 0x10C,
|
HEC_REQUEST_CANCELLED = 0x10C,
|
||||||
HEC_REQUEST_INCOMPLETE = 0x10D,
|
HEC_REQUEST_INCOMPLETE = 0x10D,
|
||||||
|
HEC_MESSAGE_ERROR = 0x10E,
|
||||||
HEC_CONNECT_ERROR = 0x10F,
|
HEC_CONNECT_ERROR = 0x10F,
|
||||||
HEC_VERSION_FALLBACK = 0x110,
|
HEC_VERSION_FALLBACK = 0x110,
|
||||||
HEC_QPACK_DECOMPRESSION_FAILED = 0x200,
|
HEC_QPACK_DECOMPRESSION_FAILED = 0x200,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
/* Things specific to the IETF version of QUIC that do not fit anywhere else */
|
/* Things specific to the IETF version of QUIC that do not fit anywhere else */
|
||||||
|
|
||||||
/* [draft-ietf-quic-transport-31] Section 20 */
|
/* [draft-ietf-quic-transport-33] Section 20 */
|
||||||
enum trans_error_code
|
enum trans_error_code
|
||||||
{
|
{
|
||||||
TEC_NO_ERROR = 0x0,
|
TEC_NO_ERROR = 0x0,
|
||||||
|
@ -23,6 +23,7 @@ enum trans_error_code
|
||||||
TEC_CRYPTO_BUFFER_EXCEEDED = 0xD,
|
TEC_CRYPTO_BUFFER_EXCEEDED = 0xD,
|
||||||
TEC_KEY_UPDATE_ERROR = 0xE,
|
TEC_KEY_UPDATE_ERROR = 0xE,
|
||||||
TEC_AEAD_LIMIT_REACHED = 0xF,
|
TEC_AEAD_LIMIT_REACHED = 0xF,
|
||||||
|
TEC_NO_VIABLE_PATH = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Must be at least two */
|
/* Must be at least two */
|
||||||
|
@ -32,9 +33,12 @@ enum trans_error_code
|
||||||
#define IETF_RETRY_KEY_SZ 16
|
#define IETF_RETRY_KEY_SZ 16
|
||||||
#define IETF_RETRY_NONCE_SZ 12
|
#define IETF_RETRY_NONCE_SZ 12
|
||||||
|
|
||||||
#define N_IETF_RETRY_VERSIONS 2
|
#define N_IETF_RETRY_VERSIONS 3
|
||||||
extern const unsigned char *const lsquic_retry_key_buf[N_IETF_RETRY_VERSIONS];
|
extern const unsigned char *const lsquic_retry_key_buf[N_IETF_RETRY_VERSIONS];
|
||||||
extern const unsigned char *const lsquic_retry_nonce_buf[N_IETF_RETRY_VERSIONS];
|
extern const unsigned char *const lsquic_retry_nonce_buf[N_IETF_RETRY_VERSIONS];
|
||||||
#define lsquic_version_2_retryver(ver_) ((ver_) > LSQVER_ID28)
|
#define lsquic_version_2_retryver(ver_) ( \
|
||||||
|
(ver_) <= LSQVER_ID27 ? 0 : \
|
||||||
|
(ver_) <= LSQVER_ID34 ? 1 : \
|
||||||
|
2)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1378,15 +1378,10 @@ imico_switch_to_trechist (struct ietf_mini_conn *conn)
|
||||||
if (conn->imc_recvd_packnos.bitmasks[pns])
|
if (conn->imc_recvd_packnos.bitmasks[pns])
|
||||||
{
|
{
|
||||||
lsquic_imico_rechist_init(&iter, conn, pns);
|
lsquic_imico_rechist_init(&iter, conn, pns);
|
||||||
if (0 != lsquic_trechist_copy_ranges(&masks[pns],
|
lsquic_trechist_copy_ranges(&masks[pns],
|
||||||
elems + TRECHIST_MAX_RANGES * pns, &iter,
|
elems + TRECHIST_MAX_RANGES * pns, &iter,
|
||||||
lsquic_imico_rechist_first,
|
lsquic_imico_rechist_first,
|
||||||
lsquic_imico_rechist_next))
|
lsquic_imico_rechist_next);
|
||||||
{
|
|
||||||
LSQ_WARN("cannot copy ranges from bitmask to trechist");
|
|
||||||
free(elems);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
masks[pns] = 0;
|
masks[pns] = 0;
|
||||||
|
|
|
@ -336,7 +336,7 @@ lsquic_dcid_from_packet (const unsigned char *buf, size_t bufsz,
|
||||||
/* See [draft-ietf-quic-transport-28], Section 12.4 (Table 3) */
|
/* See [draft-ietf-quic-transport-28], Section 12.4 (Table 3) */
|
||||||
const enum quic_ft_bit lsquic_legal_frames_by_level[N_LSQVER][N_ENC_LEVS] =
|
const enum quic_ft_bit lsquic_legal_frames_by_level[N_LSQVER][N_ENC_LEVS] =
|
||||||
{
|
{
|
||||||
[LSQVER_ID32] = {
|
[LSQVER_I001] = {
|
||||||
[ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
[ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||||
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
|
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
|
||||||
[ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
[ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||||
|
@ -346,7 +346,37 @@ const enum quic_ft_bit lsquic_legal_frames_by_level[N_LSQVER][N_ENC_LEVS] =
|
||||||
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
|
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
|
||||||
| QUIC_FTBIT_STREAMS_BLOCKED
|
| QUIC_FTBIT_STREAMS_BLOCKED
|
||||||
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
|
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
|
||||||
|
| QUIC_FTBIT_PATH_CHALLENGE
|
||||||
|
| QUIC_FTBIT_DATAGRAM
|
||||||
|
| QUIC_FTBIT_RETIRE_CONNECTION_ID,
|
||||||
|
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||||
|
| QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE,
|
||||||
|
[ENC_LEV_FORW] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||||
|
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE
|
||||||
|
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
|
||||||
|
| QUIC_FTBIT_BLOCKED
|
||||||
|
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
|
||||||
|
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
|
||||||
|
| QUIC_FTBIT_STREAMS_BLOCKED
|
||||||
|
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
|
||||||
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
|
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
|
||||||
|
| QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
|
||||||
|
| QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN
|
||||||
|
| QUIC_FTBIT_TIMESTAMP
|
||||||
|
| QUIC_FTBIT_DATAGRAM
|
||||||
|
,
|
||||||
|
},
|
||||||
|
[LSQVER_ID34] = {
|
||||||
|
[ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||||
|
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
|
||||||
|
[ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||||
|
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
|
||||||
|
| QUIC_FTBIT_BLOCKED | QUIC_FTBIT_CONNECTION_CLOSE
|
||||||
|
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
|
||||||
|
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
|
||||||
|
| QUIC_FTBIT_STREAMS_BLOCKED
|
||||||
|
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
|
||||||
|
| QUIC_FTBIT_PATH_CHALLENGE
|
||||||
| QUIC_FTBIT_DATAGRAM
|
| QUIC_FTBIT_DATAGRAM
|
||||||
| QUIC_FTBIT_RETIRE_CONNECTION_ID,
|
| QUIC_FTBIT_RETIRE_CONNECTION_ID,
|
||||||
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||||
|
@ -396,34 +426,6 @@ const enum quic_ft_bit lsquic_legal_frames_by_level[N_LSQVER][N_ENC_LEVS] =
|
||||||
| QUIC_FTBIT_DATAGRAM
|
| QUIC_FTBIT_DATAGRAM
|
||||||
,
|
,
|
||||||
},
|
},
|
||||||
[LSQVER_ID28] = {
|
|
||||||
[ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
|
||||||
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
|
|
||||||
[ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
|
||||||
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
|
|
||||||
| QUIC_FTBIT_BLOCKED | QUIC_FTBIT_CONNECTION_CLOSE
|
|
||||||
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
|
|
||||||
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
|
|
||||||
| QUIC_FTBIT_STREAMS_BLOCKED
|
|
||||||
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
|
|
||||||
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
|
|
||||||
| QUIC_FTBIT_RETIRE_CONNECTION_ID,
|
|
||||||
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
|
||||||
| QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE,
|
|
||||||
[ENC_LEV_FORW] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
|
||||||
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE
|
|
||||||
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
|
|
||||||
| QUIC_FTBIT_BLOCKED
|
|
||||||
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
|
|
||||||
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
|
|
||||||
| QUIC_FTBIT_STREAMS_BLOCKED
|
|
||||||
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
|
|
||||||
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
|
|
||||||
| QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
|
|
||||||
| QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN
|
|
||||||
| QUIC_FTBIT_TIMESTAMP
|
|
||||||
,
|
|
||||||
},
|
|
||||||
[LSQVER_ID27] = {
|
[LSQVER_ID27] = {
|
||||||
[ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
[ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||||
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
|
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
|
||||||
|
|
|
@ -641,6 +641,10 @@ send_ctl_add_poison (struct lsquic_send_ctl *ctl)
|
||||||
{
|
{
|
||||||
struct lsquic_packet_out *poison;
|
struct lsquic_packet_out *poison;
|
||||||
|
|
||||||
|
/* XXX Allocating the poison packet out of the regular pool can fail.
|
||||||
|
* This leads to a lot of error checking that could be skipped if we
|
||||||
|
* did not have to allocate this packet at all.
|
||||||
|
*/
|
||||||
poison = lsquic_malo_get(ctl->sc_conn_pub->packet_out_malo);
|
poison = lsquic_malo_get(ctl->sc_conn_pub->packet_out_malo);
|
||||||
if (!poison)
|
if (!poison)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -689,6 +693,33 @@ send_ctl_reschedule_poison (struct lsquic_send_ctl *ctl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
send_ctl_update_poison_hist (struct lsquic_send_ctl *ctl,
|
||||||
|
lsquic_packno_t packno)
|
||||||
|
{
|
||||||
|
if (packno == ctl->sc_gap + 1)
|
||||||
|
{
|
||||||
|
assert(!(ctl->sc_flags & SC_POISON));
|
||||||
|
lsquic_senhist_add(&ctl->sc_senhist, ctl->sc_gap);
|
||||||
|
if (0 != send_ctl_add_poison(ctl))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
lsquic_send_ctl_mtu_not_sent (struct lsquic_send_ctl *ctl,
|
||||||
|
struct lsquic_packet_out *packet_out)
|
||||||
|
{
|
||||||
|
(void) /* See comment in send_ctl_add_poison(): the plan is to make
|
||||||
|
this code path always succeed. */
|
||||||
|
send_ctl_update_poison_hist(ctl, packet_out->po_packno);
|
||||||
|
lsquic_senhist_add(&ctl->sc_senhist, packet_out->po_packno);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *ctl,
|
lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *ctl,
|
||||||
struct lsquic_packet_out *packet_out)
|
struct lsquic_packet_out *packet_out)
|
||||||
|
@ -699,13 +730,8 @@ lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *ctl,
|
||||||
assert(!(packet_out->po_flags & PO_ENCRYPTED));
|
assert(!(packet_out->po_flags & PO_ENCRYPTED));
|
||||||
ctl->sc_last_sent_time = packet_out->po_sent;
|
ctl->sc_last_sent_time = packet_out->po_sent;
|
||||||
pns = lsquic_packet_out_pns(packet_out);
|
pns = lsquic_packet_out_pns(packet_out);
|
||||||
if (packet_out->po_packno == ctl->sc_gap + 1)
|
if (0 != send_ctl_update_poison_hist(ctl, packet_out->po_packno))
|
||||||
{
|
|
||||||
assert(!(ctl->sc_flags & SC_POISON));
|
|
||||||
lsquic_senhist_add(&ctl->sc_senhist, ctl->sc_gap);
|
|
||||||
if (0 != send_ctl_add_poison(ctl))
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
LSQ_DEBUG("packet %"PRIu64" has been sent (frame types: %s)",
|
LSQ_DEBUG("packet %"PRIu64" has been sent (frame types: %s)",
|
||||||
packet_out->po_packno, lsquic_frame_types_to_str(frames,
|
packet_out->po_packno, lsquic_frame_types_to_str(frames,
|
||||||
sizeof(frames), packet_out->po_frame_types));
|
sizeof(frames), packet_out->po_frame_types));
|
||||||
|
|
|
@ -155,6 +155,10 @@ lsquic_send_ctl_init (lsquic_send_ctl_t *, struct lsquic_alarmset *,
|
||||||
int
|
int
|
||||||
lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *, struct lsquic_packet_out *);
|
lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *, struct lsquic_packet_out *);
|
||||||
|
|
||||||
|
void
|
||||||
|
lsquic_send_ctl_mtu_not_sent (struct lsquic_send_ctl *ctl,
|
||||||
|
struct lsquic_packet_out *);
|
||||||
|
|
||||||
int
|
int
|
||||||
lsquic_send_ctl_got_ack (lsquic_send_ctl_t *, const struct ack_info *,
|
lsquic_send_ctl_got_ack (lsquic_send_ctl_t *, const struct ack_info *,
|
||||||
lsquic_time_t, lsquic_time_t);
|
lsquic_time_t, lsquic_time_t);
|
||||||
|
|
|
@ -1473,7 +1473,7 @@ verify_cl_on_fin (struct lsquic_stream *stream)
|
||||||
if (stream->sm_data_in != 0 && stream->sm_cont_len != stream->sm_data_in)
|
if (stream->sm_data_in != 0 && stream->sm_cont_len != stream->sm_data_in)
|
||||||
{
|
{
|
||||||
lconn = stream->conn_pub->lconn;
|
lconn = stream->conn_pub->lconn;
|
||||||
lconn->cn_if->ci_abort_error(lconn, 1, HEC_GENERAL_PROTOCOL_ERROR,
|
lconn->cn_if->ci_abort_error(lconn, 1, HEC_MESSAGE_ERROR,
|
||||||
"number of bytes in DATA frames of stream %"PRIu64" is %llu, "
|
"number of bytes in DATA frames of stream %"PRIu64" is %llu, "
|
||||||
"while content-length specified of %llu", stream->id,
|
"while content-length specified of %llu", stream->id,
|
||||||
stream->sm_data_in, stream->sm_cont_len);
|
stream->sm_data_in, stream->sm_cont_len);
|
||||||
|
@ -4811,7 +4811,7 @@ verify_cl_on_new_data_frame (struct lsquic_stream *stream,
|
||||||
if (stream->sm_data_in > stream->sm_cont_len)
|
if (stream->sm_data_in > stream->sm_cont_len)
|
||||||
{
|
{
|
||||||
lconn = stream->conn_pub->lconn;
|
lconn = stream->conn_pub->lconn;
|
||||||
lconn->cn_if->ci_abort_error(lconn, 1, HEC_GENERAL_PROTOCOL_ERROR,
|
lconn->cn_if->ci_abort_error(lconn, 1, HEC_MESSAGE_ERROR,
|
||||||
"number of bytes in DATA frames of stream %"PRIu64" exceeds "
|
"number of bytes in DATA frames of stream %"PRIu64" exceeds "
|
||||||
"content-length limit of %llu", stream->id, stream->sm_cont_len);
|
"content-length limit of %llu", stream->id, stream->sm_cont_len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,15 @@ find_free_slot (uint32_t slots)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns 0 on success, 1 if dup, -1 if out of elements */
|
/* When capacity is reached, smallest element is removed. When the number
|
||||||
|
* of elements in a single range cannot be represented by te_count, an
|
||||||
|
* error is returned. This is the only error this function returns.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
lsquic_trechist_insert (trechist_mask_t *mask, struct trechist_elem *elems,
|
lsquic_trechist_insert (trechist_mask_t *mask, struct trechist_elem *elems,
|
||||||
uint32_t packno)
|
uint32_t packno)
|
||||||
{
|
{
|
||||||
struct trechist_elem *el, *prev;
|
struct trechist_elem *el, *prev, *cur, *next;
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
|
|
||||||
if (*mask == 0)
|
if (*mask == 0)
|
||||||
|
@ -53,17 +56,22 @@ lsquic_trechist_insert (trechist_mask_t *mask, struct trechist_elem *elems,
|
||||||
if (packno > TE_HIGH(el) + 1)
|
if (packno > TE_HIGH(el) + 1)
|
||||||
goto insert_before;
|
goto insert_before;
|
||||||
if (packno == el->te_low - 1)
|
if (packno == el->te_low - 1)
|
||||||
|
{
|
||||||
|
if (el->te_next && el->te_low == TE_HIGH(&elems[el->te_next]) + 2)
|
||||||
|
{
|
||||||
|
if (el->te_count + elems[el->te_next].te_count - 1 > UCHAR_MAX)
|
||||||
|
return -1;
|
||||||
|
*mask &= ~(1u << el->te_next);
|
||||||
|
el->te_count += elems[el->te_next].te_count + 1;
|
||||||
|
el->te_low = elems[el->te_next].te_low;
|
||||||
|
el->te_next = elems[el->te_next].te_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (el->te_count == UCHAR_MAX)
|
if (el->te_count == UCHAR_MAX)
|
||||||
return -1;
|
return -1;
|
||||||
--el->te_low;
|
--el->te_low;
|
||||||
++el->te_count;
|
++el->te_count;
|
||||||
if (el->te_next && el->te_low == TE_HIGH(&elems[el->te_next]) + 1)
|
|
||||||
{
|
|
||||||
*mask &= ~(1u << el->te_next);
|
|
||||||
el->te_count += elems[el->te_next].te_count;
|
|
||||||
el->te_low = elems[el->te_next].te_low;
|
|
||||||
el->te_next = elems[el->te_next].te_next;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -75,15 +83,18 @@ lsquic_trechist_insert (trechist_mask_t *mask, struct trechist_elem *elems,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (packno >= el->te_low && packno <= TE_HIGH(el))
|
if (packno >= el->te_low && packno <= TE_HIGH(el))
|
||||||
return 1; /* Dup */
|
return 0; /* Dup */
|
||||||
if (!el->te_next)
|
if (!el->te_next)
|
||||||
break; /* insert tail */
|
break; /* insert tail */
|
||||||
prev = el;
|
prev = el;
|
||||||
el = &elems[el->te_next];
|
el = &elems[el->te_next];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*mask == ((1u << TRECHIST_MAX_RANGES) - 1))
|
if (*mask == TRECHIST_MAX_RANGES_MASK)
|
||||||
return -1;
|
/* No need to insert element smaller than the smallest element
|
||||||
|
* already in our list. The new element "overflows".
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
|
||||||
idx = find_free_slot(*mask);
|
idx = find_free_slot(*mask);
|
||||||
elems[idx].te_low = packno;
|
elems[idx].te_low = packno;
|
||||||
|
@ -95,10 +106,17 @@ lsquic_trechist_insert (trechist_mask_t *mask, struct trechist_elem *elems,
|
||||||
|
|
||||||
insert_before:
|
insert_before:
|
||||||
|
|
||||||
if (*mask == ((1u << TRECHIST_MAX_RANGES) - 1))
|
if (*mask != TRECHIST_MAX_RANGES_MASK)
|
||||||
return -1;
|
|
||||||
|
|
||||||
idx = find_free_slot(*mask);
|
idx = find_free_slot(*mask);
|
||||||
|
else
|
||||||
|
{ /* Drop last element and reuse its slot */
|
||||||
|
for (next = &elems[el->te_next], cur = el; next->te_next;
|
||||||
|
cur = next, next = &elems[cur->te_next])
|
||||||
|
;
|
||||||
|
idx = cur->te_next;
|
||||||
|
cur->te_next = 0;
|
||||||
|
}
|
||||||
|
|
||||||
*mask |= 1u << idx;;
|
*mask |= 1u << idx;;
|
||||||
if (el == elems)
|
if (el == elems)
|
||||||
{
|
{
|
||||||
|
@ -159,7 +177,8 @@ lsquic_trechist_next (void *iter_p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
/* First TRECHIST_MAX_RANGES ranges are copied */
|
||||||
|
void
|
||||||
lsquic_trechist_copy_ranges (trechist_mask_t *mask,
|
lsquic_trechist_copy_ranges (trechist_mask_t *mask,
|
||||||
struct trechist_elem *elems, void *src_rechist,
|
struct trechist_elem *elems, void *src_rechist,
|
||||||
const struct lsquic_packno_range * (*first) (void *),
|
const struct lsquic_packno_range * (*first) (void *),
|
||||||
|
@ -182,19 +201,13 @@ lsquic_trechist_copy_ranges (trechist_mask_t *mask,
|
||||||
el->te_next = i + 1;
|
el->te_next = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!range && el)
|
if (el)
|
||||||
{
|
|
||||||
el->te_next = 0;
|
el->te_next = 0;
|
||||||
|
|
||||||
|
if (i < 32)
|
||||||
*mask = (1u << i) - 1;
|
*mask = (1u << i) - 1;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (!el)
|
|
||||||
{
|
|
||||||
*mask = 0;
|
|
||||||
return 0; /* Must have been an empty */
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return -1;
|
*mask = UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ struct lsquic_packno_range;
|
||||||
* UCHAR_MAX, which is how many different values can fit into te_next.
|
* UCHAR_MAX, which is how many different values can fit into te_next.
|
||||||
*/
|
*/
|
||||||
#define TRECHIST_MAX_RANGES 16
|
#define TRECHIST_MAX_RANGES 16
|
||||||
|
#define TRECHIST_MAX_RANGES_MASK ((1u << TRECHIST_MAX_RANGES) - 1)
|
||||||
|
|
||||||
struct trechist_elem
|
struct trechist_elem
|
||||||
{
|
{
|
||||||
|
@ -58,7 +59,7 @@ lsquic_trechist_first (void *iter);
|
||||||
const struct lsquic_packno_range *
|
const struct lsquic_packno_range *
|
||||||
lsquic_trechist_next (void *iter);
|
lsquic_trechist_next (void *iter);
|
||||||
|
|
||||||
int
|
void
|
||||||
lsquic_trechist_copy_ranges (trechist_mask_t *mask /* This gets overwritten */,
|
lsquic_trechist_copy_ranges (trechist_mask_t *mask /* This gets overwritten */,
|
||||||
struct trechist_elem *elems, void *src_rechist,
|
struct trechist_elem *elems, void *src_rechist,
|
||||||
const struct lsquic_packno_range * (*first) (void *),
|
const struct lsquic_packno_range * (*first) (void *),
|
||||||
|
|
|
@ -19,9 +19,9 @@ static const unsigned char version_tags[N_LSQVER][4] =
|
||||||
[LSQVER_098] = { 'Q', '0', '9', '8', },
|
[LSQVER_098] = { 'Q', '0', '9', '8', },
|
||||||
#endif
|
#endif
|
||||||
[LSQVER_ID27] = { 0xFF, 0, 0, 27, },
|
[LSQVER_ID27] = { 0xFF, 0, 0, 27, },
|
||||||
[LSQVER_ID28] = { 0xFF, 0, 0, 28, },
|
|
||||||
[LSQVER_ID29] = { 0xFF, 0, 0, 29, },
|
[LSQVER_ID29] = { 0xFF, 0, 0, 29, },
|
||||||
[LSQVER_ID32] = { 0xFF, 0, 0, 32, },
|
[LSQVER_ID34] = { 0xFF, 0, 0, 34, },
|
||||||
|
[LSQVER_I001] = { 0, 0, 0, 1, },
|
||||||
[LSQVER_VERNEG] = { 0xFA, 0xFA, 0xFA, 0xFA, },
|
[LSQVER_VERNEG] = { 0xFA, 0xFA, 0xFA, 0xFA, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ const char *const lsquic_ver2str[N_LSQVER] = {
|
||||||
[LSQVER_098] = "Q098",
|
[LSQVER_098] = "Q098",
|
||||||
#endif
|
#endif
|
||||||
[LSQVER_ID27] = "FF00001B",
|
[LSQVER_ID27] = "FF00001B",
|
||||||
[LSQVER_ID28] = "FF00001C",
|
|
||||||
[LSQVER_ID29] = "FF00001D",
|
[LSQVER_ID29] = "FF00001D",
|
||||||
[LSQVER_ID32] = "FF000020",
|
[LSQVER_ID34] = "FF000022",
|
||||||
|
[LSQVER_I001] = "00000001",
|
||||||
[LSQVER_VERNEG] = "FAFAFAFA",
|
[LSQVER_VERNEG] = "FAFAFAFA",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1141,9 +1141,9 @@ fuzz_guided_pwritev_testing (const char *input)
|
||||||
case 1: version = LSQVER_046; break;
|
case 1: version = LSQVER_046; break;
|
||||||
case 2: version = LSQVER_050; break;
|
case 2: version = LSQVER_050; break;
|
||||||
case 3: version = LSQVER_ID27; break;
|
case 3: version = LSQVER_ID27; break;
|
||||||
case 4: version = LSQVER_ID28; break;
|
case 4: version = LSQVER_ID29; break;
|
||||||
default:
|
default:
|
||||||
case 5: version = LSQVER_ID29; break;
|
case 5: version = LSQVER_ID34; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sched_immed = !!(buf[8] & 0x08);
|
sched_immed = !!(buf[8] & 0x08);
|
||||||
|
|
|
@ -16,6 +16,32 @@
|
||||||
#include "lsquic_trechist.h"
|
#include "lsquic_trechist.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct str_range_iter
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
struct lsquic_packno_range range;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const struct lsquic_packno_range *
|
||||||
|
next_str_range (void *ctx)
|
||||||
|
{
|
||||||
|
struct str_range_iter *const str_iter = ctx;
|
||||||
|
|
||||||
|
if (str_iter->str && str_iter->str[0] == '[')
|
||||||
|
{
|
||||||
|
str_iter->range.high = strtoul(str_iter->str + 1, &str_iter->str, 10);
|
||||||
|
assert('-' == *str_iter->str);
|
||||||
|
str_iter->range.low = strtoul(str_iter->str + 1, &str_iter->str, 10);
|
||||||
|
assert(']' == *str_iter->str);
|
||||||
|
++str_iter->str;
|
||||||
|
return &str_iter->range;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_clone (trechist_mask_t src_mask, struct trechist_elem *src_elems)
|
test_clone (trechist_mask_t src_mask, struct trechist_elem *src_elems)
|
||||||
{
|
{
|
||||||
|
@ -23,14 +49,12 @@ test_clone (trechist_mask_t src_mask, struct trechist_elem *src_elems)
|
||||||
struct trechist_elem *hist_elems;
|
struct trechist_elem *hist_elems;
|
||||||
const struct lsquic_packno_range *ranges[2];
|
const struct lsquic_packno_range *ranges[2];
|
||||||
struct trechist_iter iters[2];
|
struct trechist_iter iters[2];
|
||||||
int s;
|
|
||||||
|
|
||||||
hist_elems = malloc(sizeof(hist_elems[0]) * TRECHIST_MAX_RANGES);
|
hist_elems = malloc(sizeof(hist_elems[0]) * TRECHIST_MAX_RANGES);
|
||||||
|
|
||||||
lsquic_trechist_iter(&iters[0], src_mask, src_elems);
|
lsquic_trechist_iter(&iters[0], src_mask, src_elems);
|
||||||
s = lsquic_trechist_copy_ranges(&hist_mask, hist_elems, &iters[0],
|
lsquic_trechist_copy_ranges(&hist_mask, hist_elems, &iters[0],
|
||||||
lsquic_trechist_first, lsquic_trechist_next);
|
lsquic_trechist_first, lsquic_trechist_next);
|
||||||
assert(s == 0);
|
|
||||||
|
|
||||||
lsquic_trechist_iter(&iters[0], src_mask, src_elems);
|
lsquic_trechist_iter(&iters[0], src_mask, src_elems);
|
||||||
lsquic_trechist_iter(&iters[1], hist_mask, hist_elems);
|
lsquic_trechist_iter(&iters[1], hist_mask, hist_elems);
|
||||||
|
@ -254,10 +278,6 @@ basic_test (void)
|
||||||
s = lsquic_trechist_insert(&hist_mask, hist_elems, 1);
|
s = lsquic_trechist_insert(&hist_mask, hist_elems, 1);
|
||||||
assert(("inserting packet number one is successful", 0 == s));
|
assert(("inserting packet number one is successful", 0 == s));
|
||||||
|
|
||||||
s = lsquic_trechist_insert(&hist_mask, hist_elems, 1);
|
|
||||||
assert(("inserting packet number one again results in duplicate error",
|
|
||||||
s == 1));
|
|
||||||
|
|
||||||
lsquic_trechist_iter(&iter, hist_mask, hist_elems);
|
lsquic_trechist_iter(&iter, hist_mask, hist_elems);
|
||||||
range = lsquic_trechist_first(&iter);
|
range = lsquic_trechist_first(&iter);
|
||||||
assert(("first range returned correctly", range));
|
assert(("first range returned correctly", range));
|
||||||
|
@ -338,18 +358,168 @@ test_limits (void)
|
||||||
s = lsquic_trechist_insert(&hist_mask, hist_elems, i);
|
s = lsquic_trechist_insert(&hist_mask, hist_elems, i);
|
||||||
assert(s == -1); /* Overflow */
|
assert(s == -1); /* Overflow */
|
||||||
|
|
||||||
for (i = 0; i < TRECHIST_MAX_RANGES - 1; ++i)
|
/* Always successful inserting new entries: */
|
||||||
|
for (i = 0; i < TRECHIST_MAX_RANGES * 2; ++i)
|
||||||
{
|
{
|
||||||
s = lsquic_trechist_insert(&hist_mask, hist_elems, 1000 + 2 * i);
|
s = lsquic_trechist_insert(&hist_mask, hist_elems, 1000 + 2 * i);
|
||||||
assert(s == 0);
|
assert(s == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = lsquic_trechist_insert(&hist_mask, hist_elems, 1000 + 2 * i);
|
/* Always successful inserting new entries in descending order, too: */
|
||||||
assert(s == -1); /* Out of ranges */
|
for (i = 0; i < TRECHIST_MAX_RANGES * 2; ++i)
|
||||||
|
{
|
||||||
|
s = lsquic_trechist_insert(&hist_mask, hist_elems, 10000 - 2 * i);
|
||||||
|
assert(s == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test merge where count exceeds max: */
|
||||||
|
hist_mask = 0;
|
||||||
|
lsquic_trechist_copy_ranges(&hist_mask, hist_elems,
|
||||||
|
& (struct str_range_iter) { .str = "[400-202][200-1]", },
|
||||||
|
next_str_range, next_str_range);
|
||||||
|
s = lsquic_trechist_insert(&hist_mask, hist_elems, 201);
|
||||||
|
assert(s == -1);
|
||||||
|
|
||||||
free(hist_elems);
|
free(hist_elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_overflow (void)
|
||||||
|
{
|
||||||
|
trechist_mask_t mask;
|
||||||
|
struct trechist_elem *elems;
|
||||||
|
int s;
|
||||||
|
char buf[0x1000];
|
||||||
|
|
||||||
|
struct str_range_iter str_iter = { .str =
|
||||||
|
"[395-390]" /* 1 */
|
||||||
|
"[385-380]"
|
||||||
|
"[375-370]"
|
||||||
|
"[365-360]"
|
||||||
|
"[355-350]" /* 5 */
|
||||||
|
"[345-340]"
|
||||||
|
"[335-330]"
|
||||||
|
"[325-320]"
|
||||||
|
"[315-310]"
|
||||||
|
"[305-300]" /* 10 */
|
||||||
|
"[295-290]"
|
||||||
|
"[285-280]"
|
||||||
|
"[275-270]"
|
||||||
|
"[265-260]"
|
||||||
|
"[255-250]" /* 15 */
|
||||||
|
"[245-240]" /* 16 */
|
||||||
|
"[235-230]" /* Overflow vvvvvv */
|
||||||
|
"[225-220]"
|
||||||
|
"[215-210]"
|
||||||
|
"[205-200]"
|
||||||
|
"[195-190]"
|
||||||
|
"[185-180]" };
|
||||||
|
|
||||||
|
elems = malloc(sizeof(elems[0]) * TRECHIST_MAX_RANGES);
|
||||||
|
lsquic_trechist_copy_ranges(&mask, elems, &str_iter, next_str_range,
|
||||||
|
next_str_range);
|
||||||
|
|
||||||
|
rechist2str(mask, elems, buf, sizeof(buf));
|
||||||
|
assert(0 == strcmp(buf,
|
||||||
|
"[395-390]" /* 1 */
|
||||||
|
"[385-380]"
|
||||||
|
"[375-370]"
|
||||||
|
"[365-360]"
|
||||||
|
"[355-350]" /* 5 */
|
||||||
|
"[345-340]"
|
||||||
|
"[335-330]"
|
||||||
|
"[325-320]"
|
||||||
|
"[315-310]"
|
||||||
|
"[305-300]" /* 10 */
|
||||||
|
"[295-290]"
|
||||||
|
"[285-280]"
|
||||||
|
"[275-270]"
|
||||||
|
"[265-260]"
|
||||||
|
"[255-250]" /* 15 */
|
||||||
|
"[245-240]" /* 16 */));
|
||||||
|
|
||||||
|
s = lsquic_trechist_insert(&mask, elems, 400);
|
||||||
|
assert(s == 0);
|
||||||
|
rechist2str(mask, elems, buf, sizeof(buf));
|
||||||
|
assert(0 == strcmp(buf,
|
||||||
|
"[400-400]"
|
||||||
|
"[395-390]"
|
||||||
|
"[385-380]"
|
||||||
|
"[375-370]"
|
||||||
|
"[365-360]"
|
||||||
|
"[355-350]"
|
||||||
|
"[345-340]"
|
||||||
|
"[335-330]"
|
||||||
|
"[325-320]"
|
||||||
|
"[315-310]"
|
||||||
|
"[305-300]"
|
||||||
|
"[295-290]"
|
||||||
|
"[285-280]"
|
||||||
|
"[275-270]"
|
||||||
|
"[265-260]"
|
||||||
|
"[255-250]"
|
||||||
|
));
|
||||||
|
|
||||||
|
/* One more for a good measure */
|
||||||
|
s = lsquic_trechist_insert(&mask, elems, 402);
|
||||||
|
assert(s == 0);
|
||||||
|
rechist2str(mask, elems, buf, sizeof(buf));
|
||||||
|
assert(0 == strcmp(buf,
|
||||||
|
"[402-402]"
|
||||||
|
"[400-400]"
|
||||||
|
"[395-390]"
|
||||||
|
"[385-380]"
|
||||||
|
"[375-370]"
|
||||||
|
"[365-360]"
|
||||||
|
"[355-350]"
|
||||||
|
"[345-340]"
|
||||||
|
"[335-330]"
|
||||||
|
"[325-320]"
|
||||||
|
"[315-310]"
|
||||||
|
"[305-300]"
|
||||||
|
"[295-290]"
|
||||||
|
"[285-280]"
|
||||||
|
"[275-270]"
|
||||||
|
"[265-260]"
|
||||||
|
));
|
||||||
|
|
||||||
|
s = lsquic_trechist_insert(&mask, elems, 401);
|
||||||
|
assert(s == 0);
|
||||||
|
s = lsquic_trechist_insert(&mask, elems, 500);
|
||||||
|
assert(s == 0);
|
||||||
|
s = lsquic_trechist_insert(&mask, elems, 200);
|
||||||
|
assert(s == 0);
|
||||||
|
s = lsquic_trechist_insert(&mask, elems, 267);
|
||||||
|
assert(s == 0);
|
||||||
|
|
||||||
|
/* One more for a good measure */
|
||||||
|
s = lsquic_trechist_insert(&mask, elems, 402);
|
||||||
|
assert(s == 0);
|
||||||
|
rechist2str(mask, elems, buf, sizeof(buf));
|
||||||
|
assert(0 == strcmp(buf,
|
||||||
|
"[500-500]"
|
||||||
|
"[402-400]"
|
||||||
|
"[395-390]"
|
||||||
|
"[385-380]"
|
||||||
|
"[375-370]"
|
||||||
|
"[365-360]"
|
||||||
|
"[355-350]"
|
||||||
|
"[345-340]"
|
||||||
|
"[335-330]"
|
||||||
|
"[325-320]"
|
||||||
|
"[315-310]"
|
||||||
|
"[305-300]"
|
||||||
|
"[295-290]"
|
||||||
|
"[285-280]"
|
||||||
|
"[275-270]"
|
||||||
|
"[267-267]"
|
||||||
|
));
|
||||||
|
|
||||||
|
free(elems);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
|
@ -357,6 +527,7 @@ main (void)
|
||||||
test4();
|
test4();
|
||||||
test5();
|
test5();
|
||||||
test_limits();
|
test_limits();
|
||||||
|
test_overflow();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue