mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.14.5
- [BUGFIX] In coalesced datagram, ignore packets whose CID does not match. - [BUGFIX] Frame reader: skip headers if target stream is not found. - [BUGFIX] Log message in QPACK decoder handler.
This commit is contained in:
parent
8dc2321be0
commit
72585dc942
7 changed files with 111 additions and 8 deletions
|
@ -2650,13 +2650,15 @@ lsquic_engine_packet_in (lsquic_engine_t *engine,
|
|||
const struct sockaddr *sa_local, const struct sockaddr *sa_peer,
|
||||
void *peer_ctx, int ecn)
|
||||
{
|
||||
const unsigned char *const packet_begin = packet_in_data;
|
||||
const unsigned char *const packet_end = packet_in_data + packet_in_size;
|
||||
struct packin_parse_state ppstate;
|
||||
lsquic_packet_in_t *packet_in;
|
||||
int (*parse_packet_in_begin) (struct lsquic_packet_in *, size_t length,
|
||||
int is_server, unsigned cid_len, struct packin_parse_state *);
|
||||
unsigned n_zeroes;
|
||||
int s;
|
||||
int s, is_ietf;
|
||||
lsquic_cid_t cid;
|
||||
|
||||
ENGINE_CALLS_INCR(engine);
|
||||
|
||||
|
@ -2691,6 +2693,7 @@ lsquic_engine_packet_in (lsquic_engine_t *engine,
|
|||
parse_packet_in_begin = lsquic_parse_packet_in_begin;
|
||||
|
||||
n_zeroes = 0;
|
||||
is_ietf = 0;
|
||||
do
|
||||
{
|
||||
packet_in = lsquic_mm_get_packet_in(&engine->pub.enp_mm);
|
||||
|
@ -2711,7 +2714,24 @@ lsquic_engine_packet_in (lsquic_engine_t *engine,
|
|||
break;
|
||||
}
|
||||
|
||||
/* [draft-ietf-quic-transport-27] Section 12.2:
|
||||
* " Receivers SHOULD ignore any subsequent packets with a different
|
||||
* " Destination Connection ID than the first packet in the datagram.
|
||||
*/
|
||||
if (is_ietf && packet_in_data > packet_begin)
|
||||
{
|
||||
if (!((packet_in->pi_flags & (PI_GQUIC|PI_CONN_ID)) == PI_CONN_ID
|
||||
&& LSQUIC_CIDS_EQ(&packet_in->pi_dcid, &cid)))
|
||||
{
|
||||
packet_in_data += packet_in->pi_data_sz;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
is_ietf = 0 == (packet_in->pi_flags & PI_GQUIC);
|
||||
packet_in_data += packet_in->pi_data_sz;
|
||||
if (is_ietf && packet_in_data < packet_end)
|
||||
cid = packet_in->pi_dcid;
|
||||
packet_in->pi_received = lsquic_time_now();
|
||||
packet_in->pi_flags |= (3 & ecn) << PIBIT_ECN_SHIFT;
|
||||
eng_hist_inc(&engine->history, packet_in->pi_received, sl_packets_in);
|
||||
|
|
|
@ -524,6 +524,44 @@ find_target_stream (const struct lsquic_frame_reader *fr)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
skip_headers (struct lsquic_frame_reader *fr)
|
||||
{
|
||||
const unsigned char *comp, *end;
|
||||
void *buf;
|
||||
int s;
|
||||
struct lsxpack_header xhdr;
|
||||
const size_t buf_len = 64 * 1024;
|
||||
|
||||
buf = malloc(buf_len);
|
||||
if (!buf)
|
||||
{
|
||||
fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, fr_get_stream_id(fr),
|
||||
FR_ERR_OTHER_ERROR);
|
||||
goto end;
|
||||
}
|
||||
|
||||
comp = fr->fr_header_block;
|
||||
end = comp + fr->fr_header_block_sz;
|
||||
while (comp < end)
|
||||
{
|
||||
lsxpack_header_prepare_decode(&xhdr, buf, 0, buf_len);
|
||||
s = lshpack_dec_decode(fr->fr_hdec, &comp, end, &xhdr);
|
||||
if (s != 0)
|
||||
{
|
||||
fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, fr_get_stream_id(fr),
|
||||
FR_ERR_OTHER_ERROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (buf)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
||||
/* TODO: this function always returns 0. Make it void */
|
||||
static int
|
||||
decode_and_pass_payload (struct lsquic_frame_reader *fr)
|
||||
{
|
||||
|
@ -539,7 +577,20 @@ decode_and_pass_payload (struct lsquic_frame_reader *fr)
|
|||
lsquic_stream_t *target_stream = NULL;
|
||||
|
||||
if (!(fr->fr_flags & FRF_SERVER))
|
||||
{
|
||||
target_stream = find_target_stream(fr);
|
||||
/* If the response is for a stream that cannot be found, one of two
|
||||
* things is true: a) the stream has been closed or b) this is an
|
||||
* error. If (a), we discard this header block. We choose to do the
|
||||
* same for (b) instead of erroring out for the sake of simplicity.
|
||||
* There is no way to exploit this behavior.
|
||||
*/
|
||||
if (!target_stream)
|
||||
{
|
||||
skip_headers(fr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
hset = fr->fr_hsi_if->hsi_create_header_set(fr->fr_hsi_ctx, target_stream,
|
||||
READER_PUSH_PROMISE == fr->fr_state.reader_type);
|
||||
if (!hset)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue