# HG changeset patch # User Vladimir Homutov # Date 1603091421 -10800 # Node ID 018baa412c0d7e9edd32a6da415fd5859e364065 # Parent 61f1c6ac89671b5721d3649d6eb582ca73881425 try: --skiptests diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -243,6 +243,8 @@ static ngx_int_t ngx_quic_ack_packet(ngx ngx_quic_header_t *pkt); static ngx_int_t ngx_quic_send_ack_range(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, uint64_t smallest, uint64_t largest); +static void ngx_quic_drop_ack_ranges(ngx_connection_t *c, + ngx_quic_send_ctx_t *ctx, uint64_t pn); static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx); static ngx_int_t ngx_quic_ack_delay(ngx_connection_t *c, @@ -2509,6 +2511,53 @@ ngx_quic_send_ack_range(ngx_connection_t } +static void +ngx_quic_drop_ack_ranges(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, + uint64_t pn) +{ + uint64_t base; + ngx_uint_t i, smallest, largest; + ngx_quic_ack_range_t *r; + + base = ctx->largest_range; + + if (base == (uint64_t) -1) { + return; + } + + largest = base; + smallest = largest - ctx->first_range; + + if (pn >= largest) { + ctx->largest_range = (uint64_t) - 1; + ctx->first_range = 0; + ctx->nranges = 0; + return; + } + + if (pn >= smallest) { + ctx->first_range = largest - pn - 1; + ctx->nranges = 0; + return; + } + + for (i = 0; i < ctx->nranges; i++) { + r = &ctx->ranges[i]; + largest = smallest - r->gap - 2; + smallest = largest - r->range; + if (pn >= largest) { + ctx->nranges = i; + return; + } + if (pn >= smallest) { + r->range = largest - pn - 1; + ctx->nranges = i + 1; + return; + } + } +} + + static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx) { @@ -2779,7 +2828,22 @@ ngx_quic_handle_ack_frame_range(ngx_conn if (f->pnum >= min && f->pnum <= max) { ngx_quic_congestion_ack(c, f); - ngx_quic_handle_stream_ack(c, f); + switch (f->type) { + case NGX_QUIC_FT_ACK: + ngx_quic_drop_ack_ranges(c, ctx, f->u.ack.largest); + break; + + case NGX_QUIC_FT_STREAM0: + case NGX_QUIC_FT_STREAM1: + case NGX_QUIC_FT_STREAM2: + case NGX_QUIC_FT_STREAM3: + case NGX_QUIC_FT_STREAM4: + case NGX_QUIC_FT_STREAM5: + case NGX_QUIC_FT_STREAM6: + case NGX_QUIC_FT_STREAM7: + ngx_quic_handle_stream_ack(c, f); + break; + } if (f->pnum > found_num || !found) { *send_time = f->last; @@ -2901,10 +2965,6 @@ ngx_quic_handle_stream_ack(ngx_connectio ngx_quic_stream_t *sn; ngx_quic_connection_t *qc; - if (f->type < NGX_QUIC_FT_STREAM0 || f->type > NGX_QUIC_FT_STREAM7) { - return; - } - qc = c->quic; sn = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);