Release 2.27.5

- [BUGFIX] Assertion in send controller when path validation fails.
- [BUGFIX] Assertion in BBR when sending out-of-order packets is
  detected.
- [BUGFIX] Drop overflow receive history ranges when cloning.
- Log correct size of the incoming packet.
- Fix internal stream function.
This commit is contained in:
Dmitri Tikhonov 2021-01-18 13:26:33 -05:00
parent 347a040589
commit bbee242ac0
11 changed files with 62 additions and 26 deletions

View file

@ -1,3 +1,12 @@
2021-01-18
- 2.27.5
- [BUGFIX] Assertion in send controller when path validation fails.
- [BUGFIX] Assertion in BBR when sending out-of-order packets is
detected.
- [BUGFIX] Drop overflow receive history ranges when cloning.
- Log correct size of the incoming packet.
- Fix internal stream function.
2021-01-13 2021-01-13
- 2.27.4 - 2.27.4
- [API] Add lsquic_conn_get_sni(), fixes issue #203. - [API] Add lsquic_conn_get_sni(), fixes issue #203.

View file

@ -26,7 +26,7 @@ author = u'LiteSpeed Technologies'
# The short X.Y version # The short X.Y version
version = u'2.27' version = u'2.27'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
release = u'2.27.4' release = u'2.27.5'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------

View file

@ -25,7 +25,7 @@ extern "C" {
#define LSQUIC_MAJOR_VERSION 2 #define LSQUIC_MAJOR_VERSION 2
#define LSQUIC_MINOR_VERSION 27 #define LSQUIC_MINOR_VERSION 27
#define LSQUIC_PATCH_VERSION 4 #define LSQUIC_PATCH_VERSION 5
/** /**
* Engine flags: * Engine flags:

View file

@ -344,10 +344,12 @@ lsquic_bbr_ack (void *cong_ctl, struct lsquic_packet_out *packet_out,
if (sample) if (sample)
TAILQ_INSERT_TAIL(&bbr->bbr_ack_state.samples, sample, next); TAILQ_INSERT_TAIL(&bbr->bbr_ack_state.samples, sample, next);
if (is_valid_packno(bbr->bbr_ack_state.max_packno)) if (!is_valid_packno(bbr->bbr_ack_state.max_packno)
/* We assume packet numbers are ordered */ /* Packet ordering is checked for, and warned about, in
assert(packet_out->po_packno > bbr->bbr_ack_state.max_packno); * lsquic_senhist_add().
bbr->bbr_ack_state.max_packno = packet_out->po_packno; */
|| packet_out->po_packno > bbr->bbr_ack_state.max_packno)
bbr->bbr_ack_state.max_packno = packet_out->po_packno;
bbr->bbr_ack_state.acked_bytes += packet_sz; bbr->bbr_ack_state.acked_bytes += packet_sz;
} }

View file

@ -52,9 +52,9 @@ void
lsquic_ev_log_packet_in (const lsquic_cid_t *cid, lsquic_ev_log_packet_in (const lsquic_cid_t *cid,
const lsquic_packet_in_t *packet_in) const lsquic_packet_in_t *packet_in)
{ {
switch (packet_in->pi_flags & ( unsigned packet_sz;
PI_FROM_MINI|
PI_GQUIC)) switch (packet_in->pi_flags & (PI_FROM_MINI|PI_GQUIC))
{ {
case PI_FROM_MINI|PI_GQUIC: case PI_FROM_MINI|PI_GQUIC:
LCID("packet in: %"PRIu64" (from mini)", packet_in->pi_packno); LCID("packet in: %"PRIu64" (from mini)", packet_in->pi_packno);
@ -65,15 +65,18 @@ lsquic_ev_log_packet_in (const lsquic_cid_t *cid,
lsquic_packet_in_ecn(packet_in)); lsquic_packet_in_ecn(packet_in));
break; break;
case PI_GQUIC: case PI_GQUIC:
LCID("packet in: %"PRIu64", size: %u", packet_in->pi_packno, packet_sz = packet_in->pi_data_sz
(unsigned) (packet_in->pi_data_sz + GQUIC_PACKET_HASH_SZ)); + (packet_in->pi_flags & PI_DECRYPTED ? GQUIC_PACKET_HASH_SZ : 0);
LCID("packet in: %"PRIu64", size: %u", packet_in->pi_packno, packet_sz);
break; break;
default: default:
packet_sz = packet_in->pi_data_sz
+ (packet_in->pi_flags & PI_DECRYPTED ? IQUIC_TAG_LEN : 0);
if (packet_in->pi_flags & PI_LOG_QL_BITS) if (packet_in->pi_flags & PI_LOG_QL_BITS)
LCID("packet in: %"PRIu64", type: %s, size: %u; ecn: %u, spin: %d; " LCID("packet in: %"PRIu64", type: %s, size: %u; ecn: %u, spin: %d; "
"path: %hhu; Q: %d; L: %d", "path: %hhu; Q: %d; L: %d",
packet_in->pi_packno, lsquic_hety2str[packet_in->pi_header_type], packet_in->pi_packno, lsquic_hety2str[packet_in->pi_header_type],
(unsigned) (packet_in->pi_data_sz + IQUIC_TAG_LEN), packet_sz,
lsquic_packet_in_ecn(packet_in), lsquic_packet_in_ecn(packet_in),
/* spin bit value is only valid for short packet headers */ /* spin bit value is only valid for short packet headers */
lsquic_packet_in_spin_bit(packet_in), packet_in->pi_path_id, lsquic_packet_in_spin_bit(packet_in), packet_in->pi_path_id,
@ -83,7 +86,7 @@ lsquic_ev_log_packet_in (const lsquic_cid_t *cid,
LCID("packet in: %"PRIu64", type: %s, size: %u; ecn: %u, spin: %d; " LCID("packet in: %"PRIu64", type: %s, size: %u; ecn: %u, spin: %d; "
"path: %hhu", "path: %hhu",
packet_in->pi_packno, lsquic_hety2str[packet_in->pi_header_type], packet_in->pi_packno, lsquic_hety2str[packet_in->pi_header_type],
(unsigned) (packet_in->pi_data_sz + IQUIC_TAG_LEN), packet_sz,
lsquic_packet_in_ecn(packet_in), lsquic_packet_in_ecn(packet_in),
/* spin bit value is only valid for short packet headers */ /* spin bit value is only valid for short packet headers */
lsquic_packet_in_spin_bit(packet_in), packet_in->pi_path_id); lsquic_packet_in_spin_bit(packet_in), packet_in->pi_path_id);

View file

@ -731,7 +731,8 @@ path_chal_alarm_expired (enum alarm_id al_id, void *ctx,
LSQ_INFO("migration to path #%u failed after none of %u path " LSQ_INFO("migration to path #%u failed after none of %u path "
"challenges received responses", path_id, copath->cop_n_chals); "challenges received responses", path_id, copath->cop_n_chals);
/* There may be a lingering challenge if its generation is delayed */ /* There may be a lingering challenge if its generation is delayed */
lsquic_send_ctl_cancel_chals(&conn->ifc_send_ctl, &copath->cop_path); lsquic_send_ctl_cancel_path_verification(&conn->ifc_send_ctl,
&copath->cop_path);
wipe_path(conn, path_id); wipe_path(conn, path_id);
} }
else else

View file

@ -503,7 +503,13 @@ lsquic_rechist_copy_ranges (struct lsquic_rechist *rechist, void *src_rechist,
assert(rechist->rh_n_used == 0); assert(rechist->rh_n_used == 0);
prev_idx = UINT_MAX; prev_idx = UINT_MAX;
for (range = first(src_rechist); range; range = next(src_rechist)) for (range = first(src_rechist); range &&
/* Do not overwrite higher-numbered ranges. (Also, logic below
* does not work if rechist_reuse_last_elem() is used.)
*/
(rechist->rh_max_ranges == 0
|| rechist->rh_n_used < rechist->rh_max_ranges);
range = next(src_rechist))
{ {
idx = rechist_alloc_elem(rechist); idx = rechist_alloc_elem(rechist);
if (idx < 0) if (idx < 0)

View file

@ -3603,15 +3603,15 @@ lsquic_send_ctl_repath (struct lsquic_send_ctl *ctl,
} }
/* Drop PATH_CHALLENGE packets for path `path'. */ /* Drop PATH_CHALLENGE and PATH_RESPONSE packets for path `path'. */
void void
lsquic_send_ctl_cancel_chals (struct lsquic_send_ctl *ctl, lsquic_send_ctl_cancel_path_verification (struct lsquic_send_ctl *ctl,
const struct network_path *path) const struct network_path *path)
{ {
struct lsquic_packet_out *packet_out, *next; struct lsquic_packet_out *packet_out, *next;
/* We need only to examine the scheduled queue as lost challenges are /* We need only to examine the scheduled queue as lost challenges and
* not retransmitted. * responses are not retransmitted.
*/ */
for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out; for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out;
packet_out = next) packet_out = next)
@ -3619,7 +3619,8 @@ lsquic_send_ctl_cancel_chals (struct lsquic_send_ctl *ctl,
next = TAILQ_NEXT(packet_out, po_next); next = TAILQ_NEXT(packet_out, po_next);
if (packet_out->po_path == path) if (packet_out->po_path == path)
{ {
assert(packet_out->po_frame_types & QUIC_FTBIT_PATH_CHALLENGE); assert(packet_out->po_frame_types
& (QUIC_FTBIT_PATH_CHALLENGE|QUIC_FTBIT_PATH_RESPONSE));
assert(!(packet_out->po_frame_types & ctl->sc_retx_frames)); assert(!(packet_out->po_frame_types & ctl->sc_retx_frames));
send_ctl_maybe_renumber_sched_to_right(ctl, packet_out); send_ctl_maybe_renumber_sched_to_right(ctl, packet_out);
send_ctl_sched_remove(ctl, packet_out); send_ctl_sched_remove(ctl, packet_out);

View file

@ -387,7 +387,7 @@ lsquic_send_ctl_repath (struct lsquic_send_ctl *ctl,
int keep_path_properties); int keep_path_properties);
void void
lsquic_send_ctl_cancel_chals (struct lsquic_send_ctl *, lsquic_send_ctl_cancel_path_verification (struct lsquic_send_ctl *,
const struct network_path *); const struct network_path *);
void void

View file

@ -909,11 +909,11 @@ lsquic_stream_readable (struct lsquic_stream *stream)
int int
lsquic_stream_is_write_reset (const struct lsquic_stream *stream) lsquic_stream_is_write_reset (const struct lsquic_stream *stream)
{ {
if (stream->sm_bflags & SMBF_IETF) /* The two protocols use different frames to effect write reset: */
return stream->stream_flags & STREAM_SS_RECVD; const enum stream_flags cause_flag = stream->sm_bflags & SMBF_IETF
else ? STREAM_SS_RECVD : STREAM_RST_RECVD;
return (stream->stream_flags & (STREAM_RST_RECVD|STREAM_RST_SENT)) return (stream->stream_flags & (cause_flag|STREAM_RST_SENT))
|| (stream->sm_qflags & SMQF_SEND_RST); || (stream->sm_qflags & SMQF_SEND_RST);
} }

View file

@ -121,6 +121,7 @@ test_range_copy (struct lsquic_rechist *orig, int ietf)
{ {
char orig_str[0x1000], new_str[0x1000]; char orig_str[0x1000], new_str[0x1000];
struct lsquic_rechist new; struct lsquic_rechist new;
size_t len;
rechist2str(orig, orig_str, sizeof(orig_str)); rechist2str(orig, orig_str, sizeof(orig_str));
@ -130,6 +131,19 @@ test_range_copy (struct lsquic_rechist *orig, int ietf)
(const struct lsquic_packno_range * (*) (void *)) lsquic_rechist_next); (const struct lsquic_packno_range * (*) (void *)) lsquic_rechist_next);
rechist2str(&new, new_str, sizeof(new_str)); rechist2str(&new, new_str, sizeof(new_str));
assert(0 == strcmp(orig_str, new_str)); assert(0 == strcmp(orig_str, new_str));
lsquic_rechist_cleanup(&new);
/* This tests that lower-numbered ranges do not overwrite higher-numbered
* ranges.
*/
lsquic_rechist_init(&new, ietf, 10);
lsquic_rechist_copy_ranges(&new, orig,
(const struct lsquic_packno_range * (*) (void *)) lsquic_rechist_first,
(const struct lsquic_packno_range * (*) (void *)) lsquic_rechist_next);
rechist2str(&new, new_str, sizeof(new_str));
len = strlen(new_str);
assert(0 == strncmp(orig_str, new_str, len));
lsquic_rechist_cleanup(&new);
} }