diff src/event/ngx_event_quic_transport.c @ 8326:1cdd53532309 quic

ACK ranges processing. + since number of ranges in unknown, provide a function to parse them once again in handler to avoid memory allocation + ack handler now processes all ranges, not only the first + ECN counters are parsed and saved into frame if present
author Vladimir Homutov <vl@nginx.com>
date Mon, 06 Apr 2020 16:19:26 +0300
parents 853908b5a216
children 167d32476737
line wrap: on
line diff
--- a/src/event/ngx_event_quic_transport.c
+++ b/src/event/ngx_event_quic_transport.c
@@ -561,9 +561,10 @@ ssize_t
 ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end,
     ngx_quic_frame_t *f)
 {
-    u_char    *p;
-    uint8_t    flags;
-    uint64_t   varint;
+    u_char      *p;
+    uint8_t      flags;
+    uint64_t     varint;
+    ngx_uint_t   i;
 
     flags = pkt->flags;
     p = start;
@@ -641,21 +642,19 @@ ngx_quic_parse_frame(ngx_quic_header_t *
             return NGX_ERROR;
         }
 
-        if (f->u.ack.range_count) {
-            p = ngx_quic_parse_int(p, end, &f->u.ack.ranges[0]);
+        f->u.ack.ranges_start = p;
+
+        /* process all ranges to get bounds, values are ignored */
+        for (i = 0; i < f->u.ack.range_count; i++) {
+            p = ngx_quic_parse_int_multi(p, end, &varint, &varint, NULL);
             if (p == NULL) {
                 ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
-                              "failed to parse ack frame first range");
+                              "failed to parse ack frame range %ui", i);
                 return NGX_ERROR;
             }
         }
 
-        if (f->type == NGX_QUIC_FT_ACK_ECN) {
-            ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
-                          "TODO: parse ECN ack frames");
-            /* TODO: add parsing of such frames */
-            return NGX_ERROR;
-        }
+        f->u.ack.ranges_end = p;
 
         ngx_log_debug4(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
                        "ACK: { largest=%ui delay=%ui count=%ui first=%ui}",
@@ -664,6 +663,21 @@ ngx_quic_parse_frame(ngx_quic_header_t *
                        f->u.ack.range_count,
                        f->u.ack.first_range);
 
+        if (f->type == NGX_QUIC_FT_ACK_ECN) {
+
+            p = ngx_quic_parse_int_multi(p, end, &f->u.ack.ect0,
+                                         &f->u.ack.ect1, &f->u.ack.ce, NULL);
+            if (p == NULL) {
+                ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
+                              "failed to parse ack frame ECT counts", i);
+                return NGX_ERROR;
+            }
+
+            ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
+                           "ACK ECN counters: %ui %ui %ui",
+                           f->u.ack.ect0, f->u.ack.ect1, f->u.ack.ce);
+        }
+
         break;
 
     case NGX_QUIC_FT_PING:
@@ -1112,6 +1126,35 @@ not_allowed:
 
 
 ssize_t
+ngx_quic_parse_ack_range(ngx_quic_header_t *pkt, u_char *start, u_char *end,
+    uint64_t *gap, uint64_t *range)
+{
+    u_char  *p;
+
+    p = start;
+
+    p = ngx_quic_parse_int(p, end, gap);
+    if (p == NULL) {
+        ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
+                      "failed to parse ack frame gap");
+        return NGX_ERROR;
+    }
+
+    p = ngx_quic_parse_int(p, end, range);
+    if (p == NULL) {
+        ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
+                      "failed to parse ack frame range");
+        return NGX_ERROR;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
+                   "ACK range: gap %ui range %ui", *gap, *range);
+
+    return p - start;
+}
+
+
+ssize_t
 ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f)
 {
     /*