]> git.kaiwu.me - nginx.git/commitdiff
QUIC: refactored long header parsing.
authorSergey Kandaurov <pluknet@nginx.com>
Tue, 17 Nov 2020 21:32:04 +0000 (21:32 +0000)
committerSergey Kandaurov <pluknet@nginx.com>
Tue, 17 Nov 2020 21:32:04 +0000 (21:32 +0000)
The largely duplicate type-specific functions ngx_quic_parse_initial_header(),
ngx_quic_parse_handshake_header(), and a missing one for 0-RTT, were merged.
The new order of functions listed in ngx_event_quic_transport.c reflects this.

|_ ngx_quic_parse_long_header    - version-invariant long header fields
\_ ngx_quic_supported_version    - a helper to decide we can go further
\_ ngx_quic_parse_long_header_v1 - QUICv1-specific long header fields

0-RTT packets previously appeared as Handshake are now logged as appropriate:
 *1 quic packet rx long flags:db version:ff00001d
 *1 quic packet rx early len:870

Logging SCID/DCID is no longer duplicated as were seen with Initial packets.

src/event/ngx_event_quic.c
src/event/ngx_event_quic_transport.c
src/event/ngx_event_quic_transport.h

index 5ef8df977bb1e46d2fe7d042e5c5dda8d2b4922c..a11300407d79c0342a7ae3e3357030811d1027af 100644 (file)
 
 #define NGX_QUIC_MAX_ACK_GAP     2
 
-#define ngx_quic_level_name(lvl)                                              \
-    (lvl == ssl_encryption_application) ? "app"                               \
-        : (lvl == ssl_encryption_initial) ? "init"                            \
-            : (lvl == ssl_encryption_handshake) ? "hs" : "early"
-
 
 typedef struct {
     ngx_rbtree_t                      tree;
@@ -2086,6 +2081,10 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
         ngx_quic_hexdump(c->log, "quic packet rx scid", pkt->scid.data,
                          pkt->scid.len);
     }
+
+    if (pkt->level == ssl_encryption_initial) {
+        ngx_quic_hexdump(c->log, "quic token", pkt->token.data, pkt->token.len);
+    }
 #endif
 
     if (qc) {
index 90ea572bd44f455baf0c5a4db19a7a1ba62b46de..50ec26f09c03cadfa9db823df16c4225d7d4bae0 100644 (file)
@@ -78,8 +78,7 @@ static ngx_int_t ngx_quic_parse_short_header(ngx_quic_header_t *pkt,
     size_t dcid_len);
 static ngx_int_t ngx_quic_parse_long_header(ngx_quic_header_t *pkt);
 static ngx_int_t ngx_quic_supported_version(uint32_t version);
-static ngx_int_t ngx_quic_parse_initial_header(ngx_quic_header_t *pkt);
-static ngx_int_t ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt);
+static ngx_int_t ngx_quic_parse_long_header_v1(ngx_quic_header_t *pkt);
 
 static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt,
     ngx_uint_t frame_type);
@@ -291,36 +290,7 @@ ngx_quic_parse_packet(ngx_quic_header_t *pkt)
         return NGX_ABORT;
     }
 
-    if (ngx_quic_pkt_in(pkt->flags)) {
-
-        if (pkt->len < NGX_QUIC_MIN_INITIAL_SIZE) {
-            ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
-                          "quic UDP datagram is too small for initial packet");
-            return NGX_DECLINED;
-        }
-
-        pkt->level = ssl_encryption_initial;
-
-        if (ngx_quic_parse_initial_header(pkt) != NGX_OK) {
-            return NGX_DECLINED;
-        }
-
-        return NGX_OK;
-    }
-
-    if (ngx_quic_pkt_hs(pkt->flags)) {
-        pkt->level = ssl_encryption_handshake;
-
-    } else if (ngx_quic_pkt_zrtt(pkt->flags)) {
-        pkt->level = ssl_encryption_early_data;
-
-    } else {
-         ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
-                       "quic unknown long packet type");
-         return NGX_DECLINED;
-    }
-
-    if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) {
+    if (ngx_quic_parse_long_header_v1(pkt) != NGX_OK) {
         return NGX_DECLINED;
     }
 
@@ -450,89 +420,72 @@ ngx_quic_supported_version(uint32_t version)
 
 
 static ngx_int_t
-ngx_quic_parse_initial_header(ngx_quic_header_t *pkt)
+ngx_quic_parse_long_header_v1(ngx_quic_header_t *pkt)
 {
     u_char    *p, *end;
     uint64_t   varint;
 
     p = pkt->raw->pos;
-
     end = pkt->raw->last;
 
-    pkt->log->action = "parsing quic initial header";
-
-    p = ngx_quic_parse_int(p, end, &varint);
-    if (p == NULL) {
-        ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
-                      "quic failed to parse token length");
-        return NGX_ERROR;
-    }
-
-    pkt->token.len = varint;
-
-    p = ngx_quic_read_bytes(p, end, pkt->token.len, &pkt->token.data);
-    if (p == NULL) {
-        ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
-                      "quic packet too small to read token data");
-        return NGX_ERROR;
-    }
-
-    p = ngx_quic_parse_int(p, end, &varint);
-    if (p == NULL) {
-        ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic bad packet length");
-        return NGX_ERROR;
-    }
+    pkt->log->action = "parsing quic long header";
 
-    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
-                   "quic packet rx initial len:%uL", varint);
+    if (ngx_quic_pkt_in(pkt->flags)) {
 
-    if (varint > (uint64_t) ((pkt->data + pkt->len) - p)) {
-        ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
-                      "quic truncated initial packet");
-        return NGX_ERROR;
-    }
+        if (pkt->len < NGX_QUIC_MIN_INITIAL_SIZE) {
+            ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
+                          "quic UDP datagram is too small for initial packet");
+            return NGX_DECLINED;
+        }
 
-    pkt->raw->pos = p;
-    pkt->len = p + varint - pkt->data;
+        p = ngx_quic_parse_int(p, end, &varint);
+        if (p == NULL) {
+            ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
+                          "quic failed to parse token length");
+            return NGX_ERROR;
+        }
 
-#ifdef NGX_QUIC_DEBUG_PACKETS
-    ngx_quic_hexdump(pkt->log, "quic DCID", pkt->dcid.data, pkt->dcid.len);
-    ngx_quic_hexdump(pkt->log, "quic SCID", pkt->scid.data, pkt->scid.len);
-    ngx_quic_hexdump(pkt->log, "quic token", pkt->token.data, pkt->token.len);
-#endif
+        pkt->token.len = varint;
 
-    return NGX_OK;
-}
+        p = ngx_quic_read_bytes(p, end, pkt->token.len, &pkt->token.data);
+        if (p == NULL) {
+            ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
+                          "quic packet too small to read token data");
+            return NGX_ERROR;
+        }
 
+        pkt->level = ssl_encryption_initial;
 
-static ngx_int_t
-ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt)
-{
-    u_char    *p, *end;
-    uint64_t   plen;
+    } else if (ngx_quic_pkt_zrtt(pkt->flags)) {
+        pkt->level = ssl_encryption_early_data;
 
-    p = pkt->raw->pos;
-    end = pkt->raw->last;
+    } else if (ngx_quic_pkt_hs(pkt->flags)) {
+        pkt->level = ssl_encryption_handshake;
 
-    pkt->log->action = "parsing quic handshake header";
+    } else {
+         ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
+                       "quic bad packet type");
+         return NGX_DECLINED;
+    }
 
-    p = ngx_quic_parse_int(p, end, &plen);
+    p = ngx_quic_parse_int(p, end, &varint);
     if (p == NULL) {
         ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic bad packet length");
         return NGX_ERROR;
     }
 
-    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
-                   "quic packet rx handshake len:%uL", plen);
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
+                   "quic packet rx %s len:%uL",
+                   ngx_quic_level_name(pkt->level), varint);
 
-    if (plen > (uint64_t)((pkt->data + pkt->len) - p)) {
-        ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
-                      "quic truncated handshake packet");
+    if (varint > (uint64_t) ((pkt->data + pkt->len) - p)) {
+        ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic truncated %s packet",
+                      ngx_quic_level_name(pkt->level));
         return NGX_ERROR;
     }
 
     pkt->raw->pos = p;
-    pkt->len = p + plen - pkt->data;
+    pkt->len = p + varint - pkt->data;
 
     return NGX_OK;
 }
index 988790c8c057a929d6ae05c383371ef41b68a3fc..bd41842adb5f4f585e1ddeebbf15e55d28bd5470 100644 (file)
 #define ngx_quic_pkt_retry(flags)                                             \
     (((flags) & NGX_QUIC_PKT_TYPE) == NGX_QUIC_PKT_RETRY)
 
+#define ngx_quic_level_name(lvl)                                              \
+    (lvl == ssl_encryption_application) ? "app"                               \
+        : (lvl == ssl_encryption_initial) ? "init"                            \
+            : (lvl == ssl_encryption_handshake) ? "hs" : "early"
+
 
 /* 12.4.  Frames and Frame Types */
 #define NGX_QUIC_FT_PADDING                              0x00