]> git.kaiwu.me - nginx.git/commitdiff
Introduced packet namespace in QUIC connection.
authorVladimir Homutov <vl@nginx.com>
Wed, 1 Apr 2020 11:31:08 +0000 (14:31 +0300)
committerVladimir Homutov <vl@nginx.com>
Wed, 1 Apr 2020 11:31:08 +0000 (14:31 +0300)
The structure contains all data that is related to the namespace:
packet number and output queue (next patch).

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

index fc94996664a1a0a6d922fe405e285be3d88a8269..f3d46a5901be2def7abe69068c57678208ccd4b5 100644 (file)
@@ -9,6 +9,20 @@
 #include <ngx_event.h>
 
 
+/*  0-RTT and 1-RTT data exist in the same packet number space,
+ *  so we have 3 packet number spaces:
+ *
+ *  0 - Initial
+ *  1 - Handshake
+ *  2 - 0-RTT and 1-RTT
+ */
+#define ngx_quic_ns(level)                                                    \
+    ((level) == ssl_encryption_initial) ? 0                                   \
+        : (((level) == ssl_encryption_handshake) ? 1 : 2)
+
+#define NGX_QUIC_NAMESPACE_LAST  (NGX_QUIC_ENCRYPTION_LAST - 1)
+
+
 typedef enum {
     NGX_QUIC_ST_INITIAL,     /* connection just created */
     NGX_QUIC_ST_HANDSHAKE,   /* handshake started */
@@ -26,6 +40,14 @@ typedef struct {
 } ngx_quic_streams_t;
 
 
+typedef struct {
+    ngx_quic_secret_t                 client_secret;
+    ngx_quic_secret_t                 server_secret;
+
+    ngx_uint_t                        pnum;
+} ngx_quic_namespace_t;
+
+
 struct ngx_quic_connection_s {
     ngx_str_t                         scid;
     ngx_str_t                         dcid;
@@ -37,11 +59,7 @@ struct ngx_quic_connection_s {
 
     ngx_quic_state_t                  state;
 
-    /* current packet numbers  for each namespace */
-    ngx_uint_t                        initial_pn;
-    ngx_uint_t                        handshake_pn;
-    ngx_uint_t                        appdata_pn;
-
+    ngx_quic_namespace_t              ns[NGX_QUIC_NAMESPACE_LAST];
     ngx_quic_secrets_t                keys[NGX_QUIC_ENCRYPTION_LAST];
     uint64_t                          crypto_offset[NGX_QUIC_ENCRYPTION_LAST];
 
@@ -1106,11 +1124,14 @@ ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt)
         return NGX_ERROR;
     }
 
-    ack_frame->level = pkt->level;
+    ack_frame->level = (pkt->level == ssl_encryption_early_data)
+                       ? ssl_encryption_application
+                       : pkt->level;
+
     ack_frame->type = NGX_QUIC_FT_ACK;
     ack_frame->u.ack.pn = pkt->pn;
 
-    ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, pkt->level);
+    ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, ack_frame->level);
     ngx_quic_queue_frame(qc, ack_frame);
 
     return ngx_quic_output(c);
@@ -1454,6 +1475,7 @@ ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start,
     ngx_quic_frame_t       *f;
     ngx_quic_header_t       pkt;
     ngx_quic_secrets_t     *keys;
+    ngx_quic_namespace_t   *ns;
     ngx_quic_connection_t  *qc;
     static ngx_str_t        initial_token = ngx_null_string;
     static u_char           src[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
@@ -1493,20 +1515,17 @@ ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start,
     qc = c->quic;
 
     keys = &c->quic->keys[start->level];
+    ns = &c->quic->ns[ngx_quic_ns(start->level)];
 
     pkt.secret = &keys->server;
+    pkt.number = ns->pnum;
 
     if (start->level == ssl_encryption_initial) {
-        pkt.number = &qc->initial_pn;
         pkt.flags = NGX_QUIC_PKT_INITIAL;
         pkt.token = initial_token;
 
     } else if (start->level == ssl_encryption_handshake) {
-        pkt.number = &qc->handshake_pn;
         pkt.flags = NGX_QUIC_PKT_HANDSHAKE;
-
-    } else {
-        pkt.number = &qc->appdata_pn;
     }
 
     pkt.log = c->log;
@@ -1525,7 +1544,7 @@ ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start,
 
     c->send(c, res.data, res.len); // TODO: err handling
 
-    (*pkt.number)++;
+    ns->pnum++;
 
     return NGX_OK;
 }
index 34289d856f16690ac35e96b98d4fa54d524e6bbb..bf831109d47f77f2d6e23810ebffb42d73c9b65c 100644 (file)
@@ -673,7 +673,7 @@ ngx_quic_create_long_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
     }
 
     ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
-    pn = *pkt->number;
+    pn = pkt->number;
     nonce[11] ^= pn;
 
     ngx_quic_hexdump0(pkt->log, "server_iv", pkt->secret->iv.data, 12);
@@ -731,7 +731,7 @@ ngx_quic_create_short_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
     if (pkt->level == ssl_encryption_handshake
         || pkt->level == ssl_encryption_application)
     {
-        nonce[11] ^= *pkt->number;
+        nonce[11] ^= pkt->number;
     }
 
     ngx_quic_hexdump0(pkt->log, "server_iv", pkt->secret->iv.data, 12);
index 467a41157343340c28f6f375f87381d03bb86353..bfa3867ea544b0061f8071eb36bd515bfdff6f51 100644 (file)
@@ -366,7 +366,7 @@ ngx_quic_create_long_header(ngx_quic_header_t *pkt, u_char *out,
 
     *pnp = p;
 
-    *p++ = (uint64_t) (*pkt->number);
+    *p++ = pkt->number; // XXX: uint64
 
     return p - start;
 }
@@ -386,7 +386,7 @@ ngx_quic_create_short_header(ngx_quic_header_t *pkt, u_char *out,
 
     *pnp = p;
 
-    *p++ = (*pkt->number);
+    *p++ = pkt->number; // XXX: uint64
 
     return p - start;
 }
index c12f6c66addaeaea1801bb862b3192531f045aa9..8268d04108ce23acb6fb656894ccd9c46153207e 100644 (file)
@@ -232,7 +232,7 @@ typedef struct {
     ngx_log_t                                  *log;
 
     struct ngx_quic_secret_s                   *secret;
-    ngx_uint_t                                 *number;
+    uint64_t                                    number;
     uint8_t                                     flags;
     uint32_t                                    version;
     ngx_str_t                                   token;