mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.14.4
- [BUGFIX] Heed es_rw_once for pushed HTTP/3 streams. - [BUGFIX] IETF client: set correct flags on bidirectional streams. - [BUGFIX] Generate Cancel Stream QPACK instructions for abandoned streams. - [BUGFIX] Do not call header callbacks after stream is closed. - Use ls-qpack 2.1.1
This commit is contained in:
parent
08c45823bc
commit
1c105cf288
9 changed files with 119 additions and 33 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2020-04-24
|
||||||
|
- 2.14.4
|
||||||
|
- [BUGFIX] Heed es_rw_once for pushed HTTP/3 streams.
|
||||||
|
- [BUGFIX] IETF client: set correct flags on bidirectional streams.
|
||||||
|
- [BUGFIX] Generate Cancel Stream QPACK instructions for abandoned
|
||||||
|
streams.
|
||||||
|
- [BUGFIX] Do not call header callbacks after stream is closed.
|
||||||
|
- Use ls-qpack 2.1.1
|
||||||
|
|
||||||
2020-04-15
|
2020-04-15
|
||||||
- 2.14.3
|
- 2.14.3
|
||||||
- [BUGFIX] gQUIC: pass correct stream to hsi_create_header_set() callback.
|
- [BUGFIX] gQUIC: pass correct stream to hsi_create_header_set() callback.
|
||||||
|
|
|
@ -26,7 +26,7 @@ author = u'LiteSpeed Technologies'
|
||||||
# The short X.Y version
|
# The short X.Y version
|
||||||
version = u'2.14'
|
version = u'2.14'
|
||||||
# The full version, including alpha/beta/rc tags
|
# The full version, including alpha/beta/rc tags
|
||||||
release = u'2.14.3'
|
release = u'2.14.4'
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
||||||
|
|
||||||
#define LSQUIC_MAJOR_VERSION 2
|
#define LSQUIC_MAJOR_VERSION 2
|
||||||
#define LSQUIC_MINOR_VERSION 14
|
#define LSQUIC_MINOR_VERSION 14
|
||||||
#define LSQUIC_PATCH_VERSION 3
|
#define LSQUIC_PATCH_VERSION 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Engine flags:
|
* Engine flags:
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 451bbc6c710e058e1a409efb7bf45beac6767030
|
Subproject commit f41613843f6164bb83993e435e8a164c1bb157e2
|
|
@ -896,14 +896,20 @@ create_bidi_stream_out (struct ietf_full_conn *conn)
|
||||||
{
|
{
|
||||||
struct lsquic_stream *stream;
|
struct lsquic_stream *stream;
|
||||||
lsquic_stream_id_t stream_id;
|
lsquic_stream_id_t stream_id;
|
||||||
|
enum stream_ctor_flags flags;
|
||||||
|
|
||||||
|
flags = SCF_IETF|SCF_DI_AUTOSWITCH;
|
||||||
|
if (conn->ifc_enpub->enp_settings.es_rw_once)
|
||||||
|
flags |= SCF_DISP_RW_ONCE;
|
||||||
|
if (conn->ifc_flags & IFC_HTTP)
|
||||||
|
flags |= SCF_HTTP;
|
||||||
|
|
||||||
stream_id = generate_stream_id(conn, SD_BIDI);
|
stream_id = generate_stream_id(conn, SD_BIDI);
|
||||||
stream = lsquic_stream_new(stream_id, &conn->ifc_pub,
|
stream = lsquic_stream_new(stream_id, &conn->ifc_pub,
|
||||||
conn->ifc_enpub->enp_stream_if,
|
conn->ifc_enpub->enp_stream_if,
|
||||||
conn->ifc_enpub->enp_stream_if_ctx,
|
conn->ifc_enpub->enp_stream_if_ctx,
|
||||||
conn->ifc_settings->es_init_max_stream_data_bidi_local,
|
conn->ifc_settings->es_init_max_stream_data_bidi_local,
|
||||||
conn->ifc_cfg.max_stream_send, SCF_IETF
|
conn->ifc_cfg.max_stream_send, flags);
|
||||||
| (conn->ifc_flags & IFC_HTTP ? SCF_HTTP : 0));
|
|
||||||
if (!stream)
|
if (!stream)
|
||||||
return -1;
|
return -1;
|
||||||
if (!lsquic_hash_insert(conn->ifc_pub.all_streams, &stream->id,
|
if (!lsquic_hash_insert(conn->ifc_pub.all_streams, &stream->id,
|
||||||
|
@ -922,15 +928,20 @@ create_push_stream (struct ietf_full_conn *conn)
|
||||||
{
|
{
|
||||||
struct lsquic_stream *stream;
|
struct lsquic_stream *stream;
|
||||||
lsquic_stream_id_t stream_id;
|
lsquic_stream_id_t stream_id;
|
||||||
|
enum stream_ctor_flags flags;
|
||||||
|
|
||||||
assert((conn->ifc_flags & (IFC_SERVER|IFC_HTTP)) == (IFC_SERVER|IFC_HTTP));
|
assert((conn->ifc_flags & (IFC_SERVER|IFC_HTTP)) == (IFC_SERVER|IFC_HTTP));
|
||||||
|
|
||||||
|
flags = SCF_IETF|SCF_HTTP;
|
||||||
|
if (conn->ifc_enpub->enp_settings.es_rw_once)
|
||||||
|
flags |= SCF_DISP_RW_ONCE;
|
||||||
|
|
||||||
stream_id = generate_stream_id(conn, SD_UNI);
|
stream_id = generate_stream_id(conn, SD_UNI);
|
||||||
stream = lsquic_stream_new(stream_id, &conn->ifc_pub,
|
stream = lsquic_stream_new(stream_id, &conn->ifc_pub,
|
||||||
conn->ifc_enpub->enp_stream_if,
|
conn->ifc_enpub->enp_stream_if,
|
||||||
conn->ifc_enpub->enp_stream_if_ctx,
|
conn->ifc_enpub->enp_stream_if_ctx,
|
||||||
conn->ifc_settings->es_init_max_stream_data_bidi_local,
|
conn->ifc_settings->es_init_max_stream_data_bidi_local,
|
||||||
conn->ifc_cfg.max_stream_send, SCF_IETF|SCF_HTTP);
|
conn->ifc_cfg.max_stream_send, flags);
|
||||||
if (!stream)
|
if (!stream)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!lsquic_hash_insert(conn->ifc_pub.all_streams, &stream->id,
|
if (!lsquic_hash_insert(conn->ifc_pub.all_streams, &stream->id,
|
||||||
|
|
|
@ -594,6 +594,8 @@ lsquic_qdh_header_in_begin (struct qpack_dec_hdl *qdh,
|
||||||
union hblock_ctx *u;
|
union hblock_ctx *u;
|
||||||
unsigned char dec_buf[LSQPACK_LONGEST_HEADER_ACK];
|
unsigned char dec_buf[LSQPACK_LONGEST_HEADER_ACK];
|
||||||
|
|
||||||
|
assert(!(stream->stream_flags & STREAM_U_READ_DONE));
|
||||||
|
|
||||||
if (!(qdh->qdh_flags & QDH_INITIALIZED))
|
if (!(qdh->qdh_flags & QDH_INITIALIZED))
|
||||||
{
|
{
|
||||||
LSQ_WARN("not initialized: cannot process header block");
|
LSQ_WARN("not initialized: cannot process header block");
|
||||||
|
@ -636,6 +638,8 @@ lsquic_qdh_header_in_continue (struct qpack_dec_hdl *qdh,
|
||||||
size_t dec_buf_sz;
|
size_t dec_buf_sz;
|
||||||
unsigned char dec_buf[LSQPACK_LONGEST_HEADER_ACK];
|
unsigned char dec_buf[LSQPACK_LONGEST_HEADER_ACK];
|
||||||
|
|
||||||
|
assert(!(stream->stream_flags & STREAM_U_READ_DONE));
|
||||||
|
|
||||||
if (qdh->qdh_flags & QDH_INITIALIZED)
|
if (qdh->qdh_flags & QDH_INITIALIZED)
|
||||||
{
|
{
|
||||||
dec_buf_sz = sizeof(dec_buf);
|
dec_buf_sz = sizeof(dec_buf);
|
||||||
|
@ -651,7 +655,7 @@ lsquic_qdh_header_in_continue (struct qpack_dec_hdl *qdh,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
lsquic_qdh_unref_stream (struct qpack_dec_hdl *qdh,
|
lsquic_qdh_unref_stream (struct qpack_dec_hdl *qdh,
|
||||||
struct lsquic_stream *stream)
|
struct lsquic_stream *stream)
|
||||||
{
|
{
|
||||||
|
@ -669,6 +673,9 @@ lsquic_qdh_cancel_stream (struct qpack_dec_hdl *qdh,
|
||||||
ssize_t nw;
|
ssize_t nw;
|
||||||
unsigned char buf[LSQPACK_LONGEST_CANCEL];
|
unsigned char buf[LSQPACK_LONGEST_CANCEL];
|
||||||
|
|
||||||
|
if (!qdh->qdh_dec_sm_out)
|
||||||
|
return;
|
||||||
|
|
||||||
nw = lsqpack_dec_cancel_stream(&qdh->qdh_decoder, stream, buf, sizeof(buf));
|
nw = lsqpack_dec_cancel_stream(&qdh->qdh_decoder, stream, buf, sizeof(buf));
|
||||||
if (nw > 0)
|
if (nw > 0)
|
||||||
{
|
{
|
||||||
|
@ -687,6 +694,33 @@ lsquic_qdh_cancel_stream (struct qpack_dec_hdl *qdh,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
lsquic_qdh_cancel_stream_id (struct qpack_dec_hdl *qdh,
|
||||||
|
lsquic_stream_id_t stream_id)
|
||||||
|
{
|
||||||
|
ssize_t nw;
|
||||||
|
unsigned char buf[LSQPACK_LONGEST_CANCEL];
|
||||||
|
|
||||||
|
if (!qdh->qdh_dec_sm_out)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nw = lsqpack_dec_cancel_stream_id(&qdh->qdh_decoder, stream_id, buf,
|
||||||
|
sizeof(buf));
|
||||||
|
if (nw > 0)
|
||||||
|
{
|
||||||
|
if (0 == qdh_write_decoder(qdh, buf, nw))
|
||||||
|
LSQ_DEBUG("wrote %zd-byte Cancel Stream instruction for "
|
||||||
|
"stream %"PRIu64" to the decoder stream", stream_id, nw);
|
||||||
|
}
|
||||||
|
else if (nw == 0)
|
||||||
|
LSQ_DEBUG("not generating Cancel Stream instruction for "
|
||||||
|
"stream %"PRIu64, stream_id);
|
||||||
|
else
|
||||||
|
LSQ_WARN("cannot generate Cancel Stream instruction for "
|
||||||
|
"stream %"PRIu64" -- not enough buffer space", stream_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
lsquic_qdh_arm_if_unsent (struct qpack_dec_hdl *qdh, void (*func)(void *),
|
lsquic_qdh_arm_if_unsent (struct qpack_dec_hdl *qdh, void (*func)(void *),
|
||||||
void *ctx)
|
void *ctx)
|
||||||
|
|
|
@ -62,13 +62,13 @@ enum lsqpack_read_header_status
|
||||||
lsquic_qdh_header_in_continue (struct qpack_dec_hdl *, struct lsquic_stream *,
|
lsquic_qdh_header_in_continue (struct qpack_dec_hdl *, struct lsquic_stream *,
|
||||||
const unsigned char **, size_t);
|
const unsigned char **, size_t);
|
||||||
|
|
||||||
void
|
|
||||||
lsquic_qdh_unref_stream (struct qpack_dec_hdl *, struct lsquic_stream *);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lsquic_qdh_cancel_stream (struct qpack_dec_hdl *,
|
lsquic_qdh_cancel_stream (struct qpack_dec_hdl *,
|
||||||
struct lsquic_stream *);
|
struct lsquic_stream *);
|
||||||
|
|
||||||
|
void
|
||||||
|
lsquic_qdh_cancel_stream_id (struct qpack_dec_hdl *, lsquic_stream_id_t);
|
||||||
|
|
||||||
int
|
int
|
||||||
lsquic_qdh_arm_if_unsent (struct qpack_dec_hdl *, void (*)(void *), void *);
|
lsquic_qdh_arm_if_unsent (struct qpack_dec_hdl *, void (*)(void *), void *);
|
||||||
|
|
||||||
|
|
|
@ -572,7 +572,11 @@ lsquic_stream_destroy (lsquic_stream_t *stream)
|
||||||
if (stream->sm_qflags & SMQF_SERVICE_FLAGS)
|
if (stream->sm_qflags & SMQF_SERVICE_FLAGS)
|
||||||
TAILQ_REMOVE(&stream->conn_pub->service_streams, stream, next_service_stream);
|
TAILQ_REMOVE(&stream->conn_pub->service_streams, stream, next_service_stream);
|
||||||
if (stream->sm_qflags & SMQF_QPACK_DEC)
|
if (stream->sm_qflags & SMQF_QPACK_DEC)
|
||||||
lsquic_qdh_unref_stream(stream->conn_pub->u.ietf.qdh, stream);
|
lsquic_qdh_cancel_stream(stream->conn_pub->u.ietf.qdh, stream);
|
||||||
|
else if ((stream->sm_bflags & (SMBF_IETF|SMBF_USE_HEADERS))
|
||||||
|
== (SMBF_IETF|SMBF_USE_HEADERS)
|
||||||
|
&& !(stream->stream_flags & STREAM_FIN_REACHED))
|
||||||
|
lsquic_qdh_cancel_stream_id(stream->conn_pub->u.ietf.qdh, stream->id);
|
||||||
drop_buffered_data(stream);
|
drop_buffered_data(stream);
|
||||||
lsquic_sfcw_consume_rem(&stream->fc);
|
lsquic_sfcw_consume_rem(&stream->fc);
|
||||||
drop_frames_in(stream);
|
drop_frames_in(stream);
|
||||||
|
@ -731,6 +735,44 @@ stream_readable_http_ietf (struct lsquic_stream *stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
maybe_switch_data_in (struct lsquic_stream *stream)
|
||||||
|
{
|
||||||
|
if ((stream->sm_bflags & SMBF_AUTOSWITCH) &&
|
||||||
|
(stream->data_in->di_flags & DI_SWITCH_IMPL))
|
||||||
|
{
|
||||||
|
stream->data_in = stream->data_in->di_if->di_switch_impl(
|
||||||
|
stream->data_in, stream->read_offset);
|
||||||
|
if (!stream->data_in)
|
||||||
|
{
|
||||||
|
stream->data_in = lsquic_data_in_error_new();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Drain and discard any incoming data */
|
||||||
|
static int
|
||||||
|
stream_readable_discard (struct lsquic_stream *stream)
|
||||||
|
{
|
||||||
|
struct data_frame *data_frame;
|
||||||
|
|
||||||
|
while ((data_frame = stream->data_in->di_if->di_get_frame(
|
||||||
|
stream->data_in, stream->read_offset)))
|
||||||
|
{
|
||||||
|
data_frame->df_read_off = data_frame->df_size;
|
||||||
|
stream->data_in->di_if->di_frame_done(stream->data_in, data_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) maybe_switch_data_in(stream);
|
||||||
|
|
||||||
|
return 0; /* Never readable */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
lsquic_stream_readable (struct lsquic_stream *stream)
|
lsquic_stream_readable (struct lsquic_stream *stream)
|
||||||
{
|
{
|
||||||
|
@ -940,17 +982,8 @@ lsquic_stream_frame_in (lsquic_stream_t *stream, stream_frame_t *frame)
|
||||||
stream->sm_fin_off = DF_END(frame);
|
stream->sm_fin_off = DF_END(frame);
|
||||||
maybe_finish_stream(stream);
|
maybe_finish_stream(stream);
|
||||||
}
|
}
|
||||||
if ((stream->sm_bflags & SMBF_AUTOSWITCH) &&
|
if (0 != maybe_switch_data_in(stream))
|
||||||
(stream->data_in->di_flags & DI_SWITCH_IMPL))
|
|
||||||
{
|
|
||||||
stream->data_in = stream->data_in->di_if->di_switch_impl(
|
|
||||||
stream->data_in, stream->read_offset);
|
|
||||||
if (!stream->data_in)
|
|
||||||
{
|
|
||||||
stream->data_in = lsquic_data_in_error_new();
|
|
||||||
goto end_ok;
|
goto end_ok;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (got_next_offset)
|
if (got_next_offset)
|
||||||
/* Checking the offset saves di_get_frame() call */
|
/* Checking the offset saves di_get_frame() call */
|
||||||
maybe_conn_to_tickable_if_readable(stream);
|
maybe_conn_to_tickable_if_readable(stream);
|
||||||
|
@ -1319,17 +1352,8 @@ read_data_frames (struct lsquic_stream *stream, int do_filtering,
|
||||||
const int fin = data_frame->df_fin;
|
const int fin = data_frame->df_fin;
|
||||||
stream->data_in->di_if->di_frame_done(stream->data_in, data_frame);
|
stream->data_in->di_if->di_frame_done(stream->data_in, data_frame);
|
||||||
data_frame = NULL;
|
data_frame = NULL;
|
||||||
if ((stream->sm_bflags & SMBF_AUTOSWITCH) &&
|
if (0 != maybe_switch_data_in(stream))
|
||||||
(stream->data_in->di_flags & DI_SWITCH_IMPL))
|
|
||||||
{
|
|
||||||
stream->data_in = stream->data_in->di_if->di_switch_impl(
|
|
||||||
stream->data_in, stream->read_offset);
|
|
||||||
if (!stream->data_in)
|
|
||||||
{
|
|
||||||
stream->data_in = lsquic_data_in_error_new();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fin)
|
if (fin)
|
||||||
{
|
{
|
||||||
stream->stream_flags |= STREAM_FIN_REACHED;
|
stream->stream_flags |= STREAM_FIN_REACHED;
|
||||||
|
@ -1525,6 +1549,7 @@ stream_shutdown_read (lsquic_stream_t *stream)
|
||||||
{
|
{
|
||||||
SM_HISTORY_APPEND(stream, SHE_SHUTDOWN_READ);
|
SM_HISTORY_APPEND(stream, SHE_SHUTDOWN_READ);
|
||||||
stream->stream_flags |= STREAM_U_READ_DONE;
|
stream->stream_flags |= STREAM_U_READ_DONE;
|
||||||
|
stream->sm_readable = stream_readable_discard;
|
||||||
stream_wantread(stream, 0);
|
stream_wantread(stream, 0);
|
||||||
maybe_finish_stream(stream);
|
maybe_finish_stream(stream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@
|
||||||
#include "lsxpack_header.h"
|
#include "lsxpack_header.h"
|
||||||
#include "lsquic_frab_list.h"
|
#include "lsquic_frab_list.h"
|
||||||
#include "lsquic_qenc_hdl.h"
|
#include "lsquic_qenc_hdl.h"
|
||||||
|
#include "lsquic_http1x_if.h"
|
||||||
|
#include "lsquic_qdec_hdl.h"
|
||||||
#include "lsquic_varint.h"
|
#include "lsquic_varint.h"
|
||||||
#include "lsquic_hq.h"
|
#include "lsquic_hq.h"
|
||||||
#include "lsquic_data_in_if.h"
|
#include "lsquic_data_in_if.h"
|
||||||
|
@ -264,6 +266,8 @@ struct test_objs {
|
||||||
unsigned initial_stream_window;
|
unsigned initial_stream_window;
|
||||||
enum stream_ctor_flags ctor_flags;
|
enum stream_ctor_flags ctor_flags;
|
||||||
struct qpack_enc_hdl qeh;
|
struct qpack_enc_hdl qeh;
|
||||||
|
struct qpack_dec_hdl qdh;
|
||||||
|
struct lsquic_hset_if hsi_if;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -320,6 +324,7 @@ init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
||||||
tobjs->conn_pub.path = &network_path;
|
tobjs->conn_pub.path = &network_path;
|
||||||
tobjs->initial_stream_window = initial_stream_window;
|
tobjs->initial_stream_window = initial_stream_window;
|
||||||
tobjs->eng_pub.enp_settings.es_cc_algo = 1; /* Cubic */
|
tobjs->eng_pub.enp_settings.es_cc_algo = 1; /* Cubic */
|
||||||
|
tobjs->eng_pub.enp_hsi_if = &tobjs->hsi_if;
|
||||||
lsquic_send_ctl_init(&tobjs->send_ctl, &tobjs->alset, &tobjs->eng_pub,
|
lsquic_send_ctl_init(&tobjs->send_ctl, &tobjs->alset, &tobjs->eng_pub,
|
||||||
&tobjs->ver_neg, &tobjs->conn_pub, 0);
|
&tobjs->ver_neg, &tobjs->conn_pub, 0);
|
||||||
tobjs->send_ctl.sc_cong_u.cubic.cu_cwnd = ~0ull;
|
tobjs->send_ctl.sc_cong_u.cubic.cu_cwnd = ~0ull;
|
||||||
|
@ -332,6 +337,8 @@ init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
||||||
s = lsquic_qeh_settings(&tobjs->qeh, 0, 0, 0, 0);
|
s = lsquic_qeh_settings(&tobjs->qeh, 0, 0, 0, 0);
|
||||||
assert(0 == s);
|
assert(0 == s);
|
||||||
tobjs->conn_pub.u.ietf.qeh = &tobjs->qeh;
|
tobjs->conn_pub.u.ietf.qeh = &tobjs->qeh;
|
||||||
|
lsquic_qdh_init(&tobjs->qdh, &tobjs->lconn, 0, &tobjs->eng_pub, 0, 0);
|
||||||
|
tobjs->conn_pub.u.ietf.qdh = &tobjs->qdh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue