mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.26.2
- [BUGFIX] Do not drop incoming data when STOP_SENDING is received. - [BUGFIX] Receipt of STOP_SENDING should not cause read-reset. - [BUGFIX] Allow stream writes after receiving RESET. - [BUGFIX] Typo in stream: ANDing enum with wrong flag. - [BUGFIX] Reset elision: do not use zero as special stream ID value, for zero is a valid stream ID in IETF QUIC. - [API] Add optional on_conncloseframe_received() callback. - Use zero error code in RESET stream sent in response to STOP_SENDING.
This commit is contained in:
parent
efa7f95dff
commit
292abba1f8
11 changed files with 165 additions and 33 deletions
|
@ -297,7 +297,7 @@ lsquic_packet_out_destroy (lsquic_packet_out_t *packet_out,
|
|||
}
|
||||
|
||||
|
||||
/* If `stream_id' is zero, stream frames from all reset streams are elided.
|
||||
/* If `stream_id' is UINT64_MAX, stream frames from all reset streams are elided.
|
||||
* Otherwise, elision is limited to the specified stream.
|
||||
*/
|
||||
unsigned
|
||||
|
@ -320,16 +320,16 @@ lsquic_packet_out_elide_reset_stream_frames (lsquic_packet_out_t *packet_out,
|
|||
{
|
||||
++n_stream_frames;
|
||||
|
||||
if (stream_id)
|
||||
if (stream_id != UINT64_MAX)
|
||||
{
|
||||
victim = frec->fe_stream->id == stream_id;
|
||||
if (victim)
|
||||
{
|
||||
assert(lsquic_stream_is_reset(frec->fe_stream));
|
||||
assert(lsquic_stream_is_write_reset(frec->fe_stream));
|
||||
}
|
||||
}
|
||||
else
|
||||
victim = lsquic_stream_is_reset(frec->fe_stream);
|
||||
victim = lsquic_stream_is_write_reset(frec->fe_stream);
|
||||
|
||||
if (victim)
|
||||
{
|
||||
|
|
|
@ -1430,7 +1430,8 @@ send_ctl_next_lost (lsquic_send_ctl_t *ctl)
|
|||
{
|
||||
if (0 == (lost_packet->po_flags & PO_MINI))
|
||||
{
|
||||
lsquic_packet_out_elide_reset_stream_frames(lost_packet, 0);
|
||||
lsquic_packet_out_elide_reset_stream_frames(lost_packet,
|
||||
UINT64_MAX);
|
||||
if (lost_packet->po_regen_sz >= lost_packet->po_data_sz)
|
||||
{
|
||||
LSQ_DEBUG("Dropping packet %"PRIu64" from lost queue",
|
||||
|
|
|
@ -872,6 +872,17 @@ stream_readable_discard (struct lsquic_stream *stream)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
stream_is_read_reset (const struct lsquic_stream *stream)
|
||||
{
|
||||
if (stream->sm_bflags & SMBF_IETF)
|
||||
return stream->stream_flags & STREAM_RST_RECVD;
|
||||
else
|
||||
return (stream->stream_flags & (STREAM_RST_RECVD|STREAM_RST_SENT))
|
||||
|| (stream->sm_qflags & SMQF_SEND_RST);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lsquic_stream_readable (struct lsquic_stream *stream)
|
||||
{
|
||||
|
@ -885,13 +896,27 @@ lsquic_stream_readable (struct lsquic_stream *stream)
|
|||
* lsquic_stream_read() will return -1 (we want the user to be
|
||||
* able to collect the error).
|
||||
*/
|
||||
|| lsquic_stream_is_reset(stream)
|
||||
|| stream_is_read_reset(stream)
|
||||
/* Type-dependent readability check: */
|
||||
|| stream->sm_readable(stream);
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if write end of the stream has been reset.
|
||||
* Note that the logic for gQUIC is the same for write and read resets.
|
||||
*/
|
||||
int
|
||||
lsquic_stream_is_write_reset (const struct lsquic_stream *stream)
|
||||
{
|
||||
if (stream->sm_bflags & SMBF_IETF)
|
||||
return stream->stream_flags & STREAM_SS_RECVD;
|
||||
else
|
||||
return (stream->stream_flags & (STREAM_RST_RECVD|STREAM_RST_SENT))
|
||||
|| (stream->sm_qflags & SMQF_SEND_RST);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
stream_writeable (struct lsquic_stream *stream)
|
||||
{
|
||||
|
@ -901,7 +926,7 @@ stream_writeable (struct lsquic_stream *stream)
|
|||
* lsquic_stream_write() will return -1 (we want the user to be
|
||||
* able to collect the error).
|
||||
*/
|
||||
lsquic_stream_is_reset(stream)
|
||||
lsquic_stream_is_write_reset(stream)
|
||||
/* - Data can be written to stream: */
|
||||
|| lsquic_stream_write_avail(stream)
|
||||
;
|
||||
|
@ -1294,13 +1319,12 @@ lsquic_stream_stop_sending_in (struct lsquic_stream *stream,
|
|||
maybe_conn_to_tickable_if_writeable(stream, 0);
|
||||
|
||||
lsquic_sfcw_consume_rem(&stream->fc);
|
||||
drop_frames_in(stream);
|
||||
drop_buffered_data(stream);
|
||||
maybe_elide_stream_frames(stream);
|
||||
|
||||
if (!(stream->stream_flags & (STREAM_RST_SENT|STREAM_FIN_SENT))
|
||||
&& !(stream->sm_qflags & SMQF_SEND_RST))
|
||||
lsquic_stream_reset_ext(stream, error_code, 0);
|
||||
lsquic_stream_reset_ext(stream, 0, 0);
|
||||
|
||||
maybe_finish_stream(stream);
|
||||
maybe_schedule_call_on_close(stream);
|
||||
|
@ -1628,7 +1652,7 @@ lsquic_stream_readf (struct lsquic_stream *stream,
|
|||
|
||||
SM_HISTORY_APPEND(stream, SHE_USER_READ);
|
||||
|
||||
if (lsquic_stream_is_reset(stream))
|
||||
if (stream_is_read_reset(stream))
|
||||
{
|
||||
if (stream->stream_flags & STREAM_RST_RECVD)
|
||||
stream->stream_flags |= STREAM_RST_READ;
|
||||
|
@ -1816,7 +1840,7 @@ stream_shutdown_write (lsquic_stream_t *stream)
|
|||
&& !(stream->stream_flags & (STREAM_FIN_SENT|STREAM_RST_SENT))
|
||||
&& !stream_is_incoming_unidir(stream)
|
||||
/* In gQUIC, receiving a RESET means "stop sending" */
|
||||
&& !(!(stream->sm_qflags & SMBF_IETF)
|
||||
&& !(!(stream->sm_bflags & SMBF_IETF)
|
||||
&& (stream->stream_flags & STREAM_RST_RECVD)))
|
||||
{
|
||||
if ((stream->sm_bflags & SMBF_USE_HEADERS)
|
||||
|
@ -2530,7 +2554,7 @@ lsquic_stream_flush_threshold (const struct lsquic_stream *stream,
|
|||
return -1; \
|
||||
} \
|
||||
} \
|
||||
if (lsquic_stream_is_reset(stream)) \
|
||||
if (lsquic_stream_is_write_reset(stream)) \
|
||||
{ \
|
||||
LSQ_INFO("Attempt to write to stream after it had been reset"); \
|
||||
errno = ECONNRESET; \
|
||||
|
@ -4600,7 +4624,7 @@ lsquic_stream_get_hset (struct lsquic_stream *stream)
|
|||
{
|
||||
void *hset;
|
||||
|
||||
if (lsquic_stream_is_reset(stream))
|
||||
if (stream_is_read_reset(stream))
|
||||
{
|
||||
LSQ_INFO("%s: stream is reset, no headers returned", __func__);
|
||||
errno = ECONNRESET;
|
||||
|
|
|
@ -429,16 +429,15 @@ lsquic_stream_call_on_new (lsquic_stream_t *);
|
|||
void
|
||||
lsquic_stream_destroy (lsquic_stream_t *);
|
||||
|
||||
/* Any of these flags will cause user-facing read and write and
|
||||
* shutdown calls to return an error. They also make the stream
|
||||
* both readable and writeable, as we want the user to collect
|
||||
* the error.
|
||||
*/
|
||||
/* True if either read or write side of the stream has been reset */
|
||||
#define lsquic_stream_is_reset(stream) \
|
||||
(((stream)->stream_flags & \
|
||||
(STREAM_RST_RECVD|STREAM_RST_SENT|STREAM_SS_RECVD)) \
|
||||
|| ((stream)->sm_qflags & SMQF_SEND_RST))
|
||||
|
||||
int
|
||||
lsquic_stream_is_write_reset (const struct lsquic_stream *);
|
||||
|
||||
/* Data that from the network gets inserted into the stream using
|
||||
* lsquic_stream_frame_in() function. Returns 0 on success, -1 on
|
||||
* failure. The latter may be caused by flow control violation or
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue