From 3229dd1160b197ac5a9a0e489da6a3dcadf2ed7f Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Wed, 12 Sep 2018 16:26:19 -0400 Subject: [PATCH] Release 1.14.3 - [BUGFIX] Do not abort conn on STREAM frame for a reset stream - [BUGFIX] Drop packets that would become empty due to repackaging. Packets on the scheduled queue may be marked for repackaging. Frames such as ACK frame that are never resent are removed from repackaged packets. We must check that the newly repackaged packet would not be empty. If it would be, it is destroyed instead and the next packet on the scheduled queue is used. Note that this change only affects the logic to return the next packet to be sent. Lost packets that are being rescheduled are already processed in this fashion. - Byteswap CID before logging it - this makes it match Chrome CIDs. (Except Q035, which is the last little-endian GQUIC version we support.) --- CHANGELOG | 16 ++++++++++++++++ include/lsquic.h | 3 ++- src/liblsquic/lsquic_full_conn.c | 11 ++++++++++- src/liblsquic/lsquic_logger.c | 17 +++++++++++++++-- src/liblsquic/lsquic_send_ctl.c | 17 ++++++++++++++--- 5 files changed, 57 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index aa4c2fc05..6662080a2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,19 @@ +2018-09-12 + - 1.14.3 + - [BUGFIX] Do not abort conn on STREAM frame for a reset stream + - [BUGFIX] Drop packets that would become empty due to repackaging. + Packets on the scheduled queue may be marked for repackaging. + Frames such as ACK frame that are never resent are removed from + repackaged packets. We must check that the newly repackaged packet + would not be empty. If it would be, it is destroyed instead and + the next packet on the scheduled queue is used. Note that this + change only affects the logic to return the next packet to be sent. + Lost packets that are being rescheduled are already processed in + this fashion. + - Byteswap CID before logging it - this makes it match Chrome CIDs. + (Except Q035, which is the last little-endian GQUIC version we + support.) + 2018-09-06 - 1.14.0 - [API Change] Disable packet sending if full batch cannot be sent diff --git a/include/lsquic.h b/include/lsquic.h index ba97cb902..1a6220096 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -25,7 +25,7 @@ extern "C" { #define LSQUIC_MAJOR_VERSION 1 #define LSQUIC_MINOR_VERSION 14 -#define LSQUIC_PATCH_VERSION 0 +#define LSQUIC_PATCH_VERSION 3 /** * Engine flags: @@ -512,6 +512,7 @@ enum lsquic_header_status LSQUIC_HDR_ERR_INCOMPL_REQ_PSDO_HDR, /** Unnecessary request pseudo-header present in the response */ LSQUIC_HDR_ERR_UNNEC_REQ_PSDO_HDR, + LSQUIC_HDR_ERR_BAD_REQ_HEADER = LSQUIC_HDR_ERR_UNNEC_REQ_PSDO_HDR, /** Not all response pseudo-headers are present */ LSQUIC_HDR_ERR_INCOMPL_RESP_PSDO_HDR, /** Unnecessary response pseudo-header present in the response. */ diff --git a/src/liblsquic/lsquic_full_conn.c b/src/liblsquic/lsquic_full_conn.c index 09c124fce..1d75c02c7 100644 --- a/src/liblsquic/lsquic_full_conn.c +++ b/src/liblsquic/lsquic_full_conn.c @@ -1148,7 +1148,16 @@ process_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, } stream = find_stream_by_id(conn, stream_frame->stream_id); - if (!stream) + if (stream) + { + if (lsquic_stream_is_reset(stream)) + { + LSQ_DEBUG("stream %u is reset, ignore frame", stream->id); + lsquic_malo_put(stream_frame); + return parsed_len; + } + } + else { if (conn_is_stream_closed(conn, stream_frame->stream_id)) { diff --git a/src/liblsquic/lsquic_logger.c b/src/liblsquic/lsquic_logger.c index f170be586..ea86ab3af 100644 --- a/src/liblsquic/lsquic_logger.c +++ b/src/liblsquic/lsquic_logger.c @@ -17,8 +17,20 @@ #define LSQUIC_LOGGER_MODULE LSQLM_LOGGER /* Quis custodiet ipsos custodes? */ #include "lsquic_logger.h" +#include "lsquic_byteswap.h" #include "lsquic.h" +/* The switch to big-endian format in GQUIC also resulted in Chrome swapping + * the CID in its log. We do the same thing in our log messages so that the + * CIDs are easy to match. The exception is Q035, which is the last little- + * endian GQUIC version this library supports. + */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define DISP_CID(cid) bswap_64(cid) +#else +#define DISP_CID(cid) (cid) +#endif + static enum lsquic_logger_timestamp_style g_llts = LLTS_NONE; static int @@ -220,7 +232,8 @@ lsquic_logger_log3 (enum lsq_log_level log_level, print_timestamp(); lsquic_printf("[%s] [QUIC:%"PRIu64"-%"PRIu32"] %s: ", - lsq_loglevel2str[log_level], conn_id, stream_id, lsqlm_to_str[module]); + lsq_loglevel2str[log_level], DISP_CID(conn_id), stream_id, + lsqlm_to_str[module]); va_list ap; va_start(ap, fmt); logger_if->vprintf(logger_ctx, fmt, ap); @@ -241,7 +254,7 @@ lsquic_logger_log2 (enum lsq_log_level log_level, print_timestamp(); lsquic_printf("[%s] [QUIC:%"PRIu64"] %s: ", - lsq_loglevel2str[log_level], conn_id, lsqlm_to_str[module]); + lsq_loglevel2str[log_level], DISP_CID(conn_id), lsqlm_to_str[module]); va_list ap; va_start(ap, fmt); logger_if->vprintf(logger_ctx, fmt, ap); diff --git a/src/liblsquic/lsquic_send_ctl.c b/src/liblsquic/lsquic_send_ctl.c index 977043236..48093cb49 100644 --- a/src/liblsquic/lsquic_send_ctl.c +++ b/src/liblsquic/lsquic_send_ctl.c @@ -1074,6 +1074,7 @@ lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *ctl) { lsquic_packet_out_t *packet_out; + get_packet: packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); if (!packet_out) return NULL; @@ -1087,13 +1088,23 @@ lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *ctl) return NULL; } + send_ctl_sched_remove(ctl, packet_out); if (packet_out->po_flags & PO_REPACKNO) { - update_for_resending(ctl, packet_out); - packet_out->po_flags &= ~PO_REPACKNO; + if (packet_out->po_regen_sz < packet_out->po_data_sz) + { + update_for_resending(ctl, packet_out); + packet_out->po_flags &= ~PO_REPACKNO; + } + else + { + LSQ_DEBUG("Dropping packet %"PRIu64" from scheduled queue", + packet_out->po_packno); + lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + goto get_packet; + } } - send_ctl_sched_remove(ctl, packet_out); ctl->sc_bytes_out += packet_out_total_sz(packet_out); return packet_out; }