mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.27.3
- [BUGFIX] gQUIC: do not destroy critical streams when connection is closed. See issue #201. - [BUGFIX] Drop #if LSQUIC_CONN_STATS from lsquic.h. See issue #211. - [BUGFIX] Challenge cancellation when path validation fails. - [BUGFIX] Do not send FIN if RST is scheduled to be sent on a stream. - [BUGFIX] gQUIC's is_tickable() when connection is closing. - [BUGFIX] Q050 processing of GOAWAY frames.
This commit is contained in:
parent
1a0003e3b9
commit
e2c4907022
10 changed files with 85 additions and 54 deletions
|
@ -84,6 +84,9 @@ enum stream_if { STREAM_IF_STD, STREAM_IF_HSK, STREAM_IF_HDR, N_STREAM_IFS };
|
|||
/* Maximum number of ACK ranges that can fit into gQUIC ACK frame */
|
||||
#define MAX_ACK_RANGES 256
|
||||
|
||||
/* HANDSHAKE and HEADERS streams are always open in gQUIC connection */
|
||||
#define N_SPECIAL_STREAMS 2
|
||||
|
||||
/* IMPORTANT: Keep values of FC_SERVER and FC_HTTP same as LSENG_SERVER
|
||||
* and LSENG_HTTP.
|
||||
*/
|
||||
|
@ -1828,7 +1831,7 @@ reset_local_streams_over_goaway (struct full_conn *conn)
|
|||
el = lsquic_hash_next(conn->fc_pub.all_streams))
|
||||
{
|
||||
stream = lsquic_hashelem_getdata(el);
|
||||
if (stream->id > conn->fc_goaway_stream_id &&
|
||||
if ((int64_t) stream->id > (int64_t) conn->fc_goaway_stream_id &&
|
||||
((stream->id & 1) ^ is_server /* Locally initiated? */))
|
||||
{
|
||||
lsquic_stream_received_goaway(stream);
|
||||
|
@ -2083,8 +2086,6 @@ static unsigned
|
|||
process_connection_close_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
|
||||
const unsigned char *p, size_t len)
|
||||
{
|
||||
lsquic_stream_t *stream;
|
||||
struct lsquic_hash_elem *el;
|
||||
uint64_t error_code;
|
||||
uint16_t reason_len;
|
||||
uint8_t reason_off;
|
||||
|
@ -2101,17 +2102,7 @@ process_connection_close_frame (struct full_conn *conn, lsquic_packet_in_t *pack
|
|||
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_conncloseframe_received)
|
||||
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_conncloseframe_received(
|
||||
&conn->fc_conn, -1, error_code, (const char *) p + reason_off, reason_len);
|
||||
conn->fc_flags |= FC_RECV_CLOSE;
|
||||
if (!(conn->fc_flags & FC_CLOSING))
|
||||
{
|
||||
for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
|
||||
el = lsquic_hash_next(conn->fc_pub.all_streams))
|
||||
{
|
||||
stream = lsquic_hashelem_getdata(el);
|
||||
lsquic_stream_shutdown_internal(stream);
|
||||
}
|
||||
conn->fc_flags |= FC_CLOSING;
|
||||
}
|
||||
conn->fc_flags |= FC_RECV_CLOSE|FC_CLOSING;
|
||||
return parsed_len;
|
||||
}
|
||||
|
||||
|
@ -2411,7 +2402,7 @@ process_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
|
|||
{
|
||||
frame_types = packet_in->pi_frame_types;
|
||||
if ((conn->fc_flags & FC_GOING_AWAY)
|
||||
&& lsquic_hash_count(conn->fc_pub.all_streams) < 3)
|
||||
&& lsquic_hash_count(conn->fc_pub.all_streams) <= N_SPECIAL_STREAMS)
|
||||
{
|
||||
/* Ignore PING frames if we are going away and there are no
|
||||
* active streams. (HANDSHAKE and HEADERS streams are the
|
||||
|
@ -2627,7 +2618,7 @@ maybe_close_conn (struct full_conn *conn)
|
|||
|
||||
if ((conn->fc_flags & (FC_CLOSING|FC_GOAWAY_SENT|FC_SERVER))
|
||||
== (FC_GOAWAY_SENT|FC_SERVER)
|
||||
&& lsquic_hash_count(conn->fc_pub.all_streams) == 2)
|
||||
&& lsquic_hash_count(conn->fc_pub.all_streams) == N_SPECIAL_STREAMS)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
|
||||
|
@ -3193,7 +3184,7 @@ conn_ok_to_close (const struct full_conn *conn)
|
|||
|| (conn->fc_flags & FC_RECV_CLOSE)
|
||||
|| (
|
||||
!lsquic_send_ctl_have_outgoing_stream_frames(&conn->fc_send_ctl)
|
||||
&& lsquic_hash_count(conn->fc_pub.all_streams) == 0
|
||||
&& lsquic_hash_count(conn->fc_pub.all_streams) <= N_SPECIAL_STREAMS
|
||||
&& lsquic_send_ctl_have_unacked_stream_frames(&conn->fc_send_ctl) == 0);
|
||||
}
|
||||
|
||||
|
@ -3807,7 +3798,8 @@ full_conn_ci_close (struct lsquic_conn *lconn)
|
|||
el = lsquic_hash_next(conn->fc_pub.all_streams))
|
||||
{
|
||||
stream = lsquic_hashelem_getdata(el);
|
||||
lsquic_stream_shutdown_internal(stream);
|
||||
if (!lsquic_stream_is_critical(stream))
|
||||
lsquic_stream_reset(stream, 0);
|
||||
}
|
||||
conn->fc_flags |= FC_CLOSING;
|
||||
if (!(conn->fc_flags & FC_GOAWAY_SENT))
|
||||
|
@ -4264,7 +4256,7 @@ full_conn_ci_is_tickable (lsquic_conn_t *lconn)
|
|||
!lsquic_send_ctl_sched_is_blocked(&conn->fc_send_ctl)))
|
||||
{
|
||||
const enum full_conn_flags send_flags = FC_SEND_GOAWAY
|
||||
|FC_SEND_STOP_WAITING|FC_SEND_PING|FC_SEND_WUF|FC_CLOSING;
|
||||
|FC_SEND_STOP_WAITING|FC_SEND_PING|FC_SEND_WUF;
|
||||
if (conn->fc_flags & send_flags)
|
||||
{
|
||||
LSQ_DEBUG("tickable: flags: 0x%X", conn->fc_flags & send_flags);
|
||||
|
|
|
@ -705,8 +705,10 @@ cid_throt_alarm_expired (enum alarm_id al_id, void *ctx,
|
|||
static void
|
||||
wipe_path (struct ietf_full_conn *conn, unsigned path_id)
|
||||
{
|
||||
void *peer_ctx = conn->ifc_paths[path_id].cop_path.np_peer_ctx;
|
||||
memset(&conn->ifc_paths[path_id], 0, sizeof(conn->ifc_paths[0]));
|
||||
conn->ifc_paths[path_id].cop_path.np_path_id = path_id;
|
||||
conn->ifc_paths[path_id].cop_path.np_peer_ctx = peer_ctx;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2916,7 +2918,7 @@ ietf_full_conn_ci_close (struct lsquic_conn *lconn)
|
|||
stream = lsquic_hashelem_getdata(el);
|
||||
sd = (stream->id >> SD_SHIFT) & 1;
|
||||
if (SD_BIDI == sd)
|
||||
lsquic_stream_shutdown_internal(stream);
|
||||
lsquic_stream_reset(stream, 0);
|
||||
}
|
||||
conn->ifc_flags |= IFC_CLOSING;
|
||||
conn->ifc_send_flags |= SF_SEND_CONN_CLOSE;
|
||||
|
@ -5933,8 +5935,6 @@ static unsigned
|
|||
process_connection_close_frame (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
lsquic_stream_t *stream;
|
||||
struct lsquic_hash_elem *el;
|
||||
uint64_t error_code;
|
||||
uint16_t reason_len;
|
||||
uint8_t reason_off;
|
||||
|
@ -5971,17 +5971,7 @@ process_connection_close_frame (struct ietf_full_conn *conn,
|
|||
if (conn->ifc_enpub->enp_stream_if->on_conncloseframe_received)
|
||||
conn->ifc_enpub->enp_stream_if->on_conncloseframe_received(
|
||||
&conn->ifc_conn, app_error, error_code, (const char *) p + reason_off, reason_len);
|
||||
conn->ifc_flags |= IFC_RECV_CLOSE;
|
||||
if (!(conn->ifc_flags & IFC_CLOSING))
|
||||
{
|
||||
for (el = lsquic_hash_first(conn->ifc_pub.all_streams); el;
|
||||
el = lsquic_hash_next(conn->ifc_pub.all_streams))
|
||||
{
|
||||
stream = lsquic_hashelem_getdata(el);
|
||||
lsquic_stream_shutdown_internal(stream);
|
||||
}
|
||||
conn->ifc_flags |= IFC_CLOSING;
|
||||
}
|
||||
conn->ifc_flags |= IFC_RECV_CLOSE|IFC_CLOSING;
|
||||
return parsed_len;
|
||||
}
|
||||
|
||||
|
@ -8890,6 +8880,7 @@ cancel_push_promise (struct ietf_full_conn *conn, struct push_promise *promise)
|
|||
/* But let stream dtor free the promise object as sm_promise may yet
|
||||
* be used by the stream in some ways.
|
||||
*/
|
||||
/* TODO: drop lsquic_stream_shutdown_internal, use something else */
|
||||
lsquic_stream_shutdown_internal(promise->pp_pushed_stream);
|
||||
if (0 != lsquic_hcso_write_cancel_push(&conn->ifc_hcso, promise->pp_id))
|
||||
ABORT_WARN("cannot write CANCEL_PUSH");
|
||||
|
|
|
@ -3617,9 +3617,10 @@ lsquic_send_ctl_cancel_chals (struct lsquic_send_ctl *ctl,
|
|||
packet_out = next)
|
||||
{
|
||||
next = TAILQ_NEXT(packet_out, po_next);
|
||||
if (packet_out->po_path == path
|
||||
&& packet_out->po_frame_types == QUIC_FTBIT_PATH_CHALLENGE)
|
||||
if (packet_out->po_path == path)
|
||||
{
|
||||
assert(packet_out->po_frame_types & QUIC_FTBIT_PATH_CHALLENGE);
|
||||
assert(!(packet_out->po_frame_types & ctl->sc_retx_frames));
|
||||
send_ctl_maybe_renumber_sched_to_right(ctl, packet_out);
|
||||
send_ctl_sched_remove(ctl, packet_out);
|
||||
assert(packet_out->po_loss_chain == packet_out);
|
||||
|
|
|
@ -1837,7 +1837,8 @@ stream_shutdown_write (lsquic_stream_t *stream)
|
|||
* the flags indicate that nothing else should be written.
|
||||
*/
|
||||
if (!(stream->sm_bflags & SMBF_CRYPTO)
|
||||
&& !(stream->stream_flags & (STREAM_FIN_SENT|STREAM_RST_SENT))
|
||||
&& !((stream->stream_flags & (STREAM_FIN_SENT|STREAM_RST_SENT))
|
||||
|| (stream->sm_qflags & SMQF_SEND_RST))
|
||||
&& !stream_is_incoming_unidir(stream)
|
||||
/* In gQUIC, receiving a RESET means "stop sending" */
|
||||
&& !(!(stream->sm_bflags & SMBF_IETF)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue