# HG changeset patch # User Roman Arutyunyan # Date 1603805040 0 # Node ID 867c189f875d0938bad557e8498120e8d61cd43d # Parent b1676cd64dc90a5960baceba9981d439c9b54168 QUIC: unified range format for rx and tx ACK frames. Previously, tx ACK frames held ranges in an array of ngx_quic_ack_range_t, while rx ACK frames held ranges in the serialized format. Now serialized format is used for both types of frames. 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 @@ -371,12 +371,11 @@ static SSL_QUIC_METHOD quic_method = { static void ngx_quic_log_frame(ngx_log_t *log, ngx_quic_frame_t *f, ngx_uint_t tx) { - u_char *p, *last, *pos, *end; - ssize_t n; - uint64_t gap, range; - ngx_uint_t i; - ngx_quic_ack_range_t *ranges; - u_char buf[NGX_MAX_ERROR_STR]; + u_char *p, *last, *pos, *end; + ssize_t n; + uint64_t gap, range; + ngx_uint_t i; + u_char buf[NGX_MAX_ERROR_STR]; p = buf; last = buf + sizeof(buf); @@ -400,28 +399,18 @@ ngx_quic_log_frame(ngx_log_t *log, ngx_q f->u.ack.largest, f->u.ack.first_range, f->u.ack.range_count, f->u.ack.delay); - if (tx) { - ranges = (ngx_quic_ack_range_t *) f->u.ack.ranges_start; - - for (i = 0; i < f->u.ack.range_count; i++) { - p = ngx_slprintf(p, last, " %uL,%uL", - ranges[i].gap, ranges[i].range); + pos = f->u.ack.ranges_start; + end = f->u.ack.ranges_end; + + for (i = 0; i < f->u.ack.range_count; i++) { + n = ngx_quic_parse_ack_range(log, pos, end, &gap, &range); + if (n == NGX_ERROR) { + break; } - } else { - pos = f->u.ack.ranges_start; - end = f->u.ack.ranges_end; - - for (i = 0; i < f->u.ack.range_count; i++) { - n = ngx_quic_parse_ack_range(log, pos, end, &gap, &range); - if (n == NGX_ERROR) { - break; - } - - pos += n; - - p = ngx_slprintf(p, last, " %uL,%uL", gap, range); - } + pos += n; + + p = ngx_slprintf(p, last, " %uL,%uL", gap, range); } if (f->type == NGX_QUIC_FT_ACK_ECN) { @@ -2879,8 +2868,10 @@ ngx_quic_drop_ack_ranges(ngx_connection_ static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx) { + u_char *p; size_t ranges_len; uint64_t ack_delay; + ngx_uint_t i; ngx_quic_frame_t *frame; if (ctx->level == ssl_encryption_application) { @@ -2892,14 +2883,24 @@ ngx_quic_send_ack(ngx_connection_t *c, n ack_delay = 0; } - ranges_len = sizeof(ngx_quic_ack_range_t) * ctx->nranges; + ranges_len = 0; + + for (i = 0; i < ctx->nranges; i++) { + ranges_len += ngx_quic_create_ack_range(NULL, ctx->ranges[i].gap, + ctx->ranges[i].range); + } frame = ngx_quic_alloc_frame(c, ranges_len); if (frame == NULL) { return NGX_ERROR; } - ngx_memcpy(frame->data, ctx->ranges, ranges_len); + p = frame->data; + + for (i = 0; i < ctx->nranges; i++) { + p += ngx_quic_create_ack_range(p, ctx->ranges[i].gap, + ctx->ranges[i].range); + } frame->level = ctx->level; frame->type = NGX_QUIC_FT_ACK; diff --git a/src/event/ngx_event_quic_transport.c b/src/event/ngx_event_quic_transport.c --- a/src/event/ngx_event_quic_transport.c +++ b/src/event/ngx_event_quic_transport.c @@ -1119,6 +1119,27 @@ ngx_quic_parse_ack_range(ngx_log_t *log, } +size_t +ngx_quic_create_ack_range(u_char *p, uint64_t gap, uint64_t range) +{ + size_t len; + u_char *start; + + if (p == NULL) { + len = ngx_quic_varint_len(gap); + len += ngx_quic_varint_len(range); + return len; + } + + start = p; + + ngx_quic_build_int(&p, gap); + ngx_quic_build_int(&p, range); + + return p - start; +} + + ssize_t ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f) { @@ -1187,12 +1208,8 @@ ngx_quic_create_frame(u_char *p, ngx_qui static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack) { - size_t len; - u_char *start; - ngx_uint_t i; - ngx_quic_ack_range_t *ranges; - - ranges = (ngx_quic_ack_range_t *) ack->ranges_start; + size_t len; + u_char *start; if (p == NULL) { len = ngx_quic_varint_len(NGX_QUIC_FT_ACK); @@ -1200,11 +1217,7 @@ ngx_quic_create_ack(u_char *p, ngx_quic_ len += ngx_quic_varint_len(ack->delay); len += ngx_quic_varint_len(ack->range_count); len += ngx_quic_varint_len(ack->first_range); - - for (i = 0; i < ack->range_count; i++) { - len += ngx_quic_varint_len(ranges[i].gap); - len += ngx_quic_varint_len(ranges[i].range); - } + len += ack->ranges_end - ack->ranges_start; return len; } @@ -1216,11 +1229,7 @@ ngx_quic_create_ack(u_char *p, ngx_quic_ ngx_quic_build_int(&p, ack->delay); ngx_quic_build_int(&p, ack->range_count); ngx_quic_build_int(&p, ack->first_range); - - for (i = 0; i < ack->range_count; i++) { - ngx_quic_build_int(&p, ranges[i].gap); - ngx_quic_build_int(&p, ranges[i].range); - } + p = ngx_cpymem(p, ack->ranges_start, ack->ranges_end - ack->ranges_start); return p - start; } diff --git a/src/event/ngx_event_quic_transport.h b/src/event/ngx_event_quic_transport.h --- a/src/event/ngx_event_quic_transport.h +++ b/src/event/ngx_event_quic_transport.h @@ -345,6 +345,7 @@ ssize_t ngx_quic_create_frame(u_char *p, ssize_t ngx_quic_parse_ack_range(ngx_log_t *log, u_char *start, u_char *end, uint64_t *gap, uint64_t *range); +size_t ngx_quic_create_ack_range(u_char *p, uint64_t gap, uint64_t range); ngx_int_t ngx_quic_parse_transport_params(u_char *p, u_char *end, ngx_quic_tp_t *tp, ngx_log_t *log);