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; }