diff --git a/CHANGELOG b/CHANGELOG index 6662080a2..711455380 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +2018-09-27 + - 1.15.0 + - [API Change] Add LSCONN_ST_PEER_GOING_AWAY to the list of conn statuses + - [BUGFIX] free uncompressed headers correctly when error occurs + 2018-09-12 - 1.14.3 - [BUGFIX] Do not abort conn on STREAM frame for a reset stream diff --git a/include/lsquic.h b/include/lsquic.h index 1a6220096..61744608f 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -24,8 +24,8 @@ extern "C" { #endif #define LSQUIC_MAJOR_VERSION 1 -#define LSQUIC_MINOR_VERSION 14 -#define LSQUIC_PATCH_VERSION 3 +#define LSQUIC_MINOR_VERSION 15 +#define LSQUIC_PATCH_VERSION 0 /** * Engine flags: @@ -1052,6 +1052,7 @@ enum LSQUIC_CONN_STATUS LSCONN_ST_USER_ABORTED, LSCONN_ST_ERROR, LSCONN_ST_CLOSED, + LSCONN_ST_PEER_GOING_AWAY, }; enum LSQUIC_CONN_STATUS diff --git a/src/liblsquic/lsquic_full_conn.c b/src/liblsquic/lsquic_full_conn.c index 1d75c02c7..c05df5809 100644 --- a/src/liblsquic/lsquic_full_conn.c +++ b/src/liblsquic/lsquic_full_conn.c @@ -3300,19 +3300,29 @@ headers_stream_on_incoming_headers (void *ctx, struct uncompressed_headers *uh) stream = find_stream_on_non_stream_frame(conn, uh->uh_stream_id, 0, "headers"); if (!stream) + goto free_uh; + + if (lsquic_stream_is_reset(stream)) { - free(uh); - return; + LSQ_DEBUG("stream is reset: ignore headers"); + goto free_uh; } if (0 != lsquic_stream_uh_in(stream, uh)) { ABORT_ERROR("stream %u refused incoming headers", uh->uh_stream_id); - free(uh); + goto free_uh; } if (!(stream->stream_flags & STREAM_ONNEW_DONE)) lsquic_stream_call_on_new(stream); + + return; + + free_uh: + if (uh->uh_hset) + conn->fc_enpub->enp_hsi_if->hsi_discard_header_set(uh->uh_hset); + free(uh); } @@ -3332,8 +3342,7 @@ headers_stream_on_push_promise (void *ctx, struct uncompressed_headers *uh) { ABORT_ERROR("invalid push promise stream IDs: %u, %u", uh->uh_oth_stream_id, uh->uh_stream_id); - free(uh); - return; + goto free_uh; } if (!(conn_is_stream_closed(conn, uh->uh_stream_id) || @@ -3341,8 +3350,7 @@ headers_stream_on_push_promise (void *ctx, struct uncompressed_headers *uh) { ABORT_ERROR("invalid push promise original stream ID %u never " "initiated", uh->uh_stream_id); - free(uh); - return; + goto free_uh; } if (conn_is_stream_closed(conn, uh->uh_oth_stream_id) || @@ -3350,8 +3358,7 @@ headers_stream_on_push_promise (void *ctx, struct uncompressed_headers *uh) { ABORT_ERROR("invalid promised stream ID %u already used", uh->uh_oth_stream_id); - free(uh); - return; + goto free_uh; } stream = new_stream_ext(conn, uh->uh_oth_stream_id, STREAM_IF_STD, @@ -3360,12 +3367,16 @@ headers_stream_on_push_promise (void *ctx, struct uncompressed_headers *uh) if (!stream) { ABORT_ERROR("cannot create stream: %s", strerror(errno)); - free(uh); - return; + goto free_uh; } lsquic_stream_push_req(stream, uh); lsquic_stream_call_on_new(stream); return; + + free_uh: + if (uh->uh_hset) + conn->fc_enpub->enp_hsi_if->hsi_discard_header_set(uh->uh_hset); + free(uh); } @@ -3420,7 +3431,9 @@ lsquic_conn_status (lsquic_conn_t *lconn, char *errbuf, size_t bufsz) |FC_CLOSING |FC_GOING_AWAY))) { - if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE) + if (lconn->cn_flags & LSCONN_PEER_GOING_AWAY) + return LSCONN_ST_PEER_GOING_AWAY; + else if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE) return LSCONN_ST_CONNECTED; else return LSCONN_ST_HSK_IN_PROGRESS;