changeset 8613:867c189f875d quic

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.
author Roman Arutyunyan <arut@nginx.com>
date Tue, 27 Oct 2020 13:24:00 +0000
parents b1676cd64dc9
children 3d79c08bb0f1
files src/event/ngx_event_quic.c src/event/ngx_event_quic_transport.c src/event/ngx_event_quic_transport.h
diffstat 3 files changed, 55 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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;
 }
--- 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);