]> git.kaiwu.me - nginx.git/commitdiff
Added basic offset support in client CRYPTO frames.
authorVladimir Homutov <vl@nginx.com>
Tue, 7 Apr 2020 12:50:38 +0000 (15:50 +0300)
committerVladimir Homutov <vl@nginx.com>
Tue, 7 Apr 2020 12:50:38 +0000 (15:50 +0300)
The offset in client CRYPTO frames is tracked in c->quic->crypto_offset_in.
This means that CRYPTO frames with non-zero offset are now accepted making
possible to finish handshake with client certificates that exceed max packet
size (if no reordering happens).

The c->quic->crypto_offset field is renamed to crypto_offset_out to avoid
confusion with tracking of incoming CRYPTO stream.

src/event/ngx_event_quic.c

index 65d71a2868f579fae56ab86c09ad534d0db1f8c2..b71cb6e0d1083ed292f6a898311fa2525d11b30d 100644 (file)
@@ -69,7 +69,8 @@ struct ngx_quic_connection_s {
     ngx_quic_namespace_t              ns[NGX_QUIC_NAMESPACE_LAST];
     ngx_quic_secrets_t                keys[NGX_QUIC_ENCRYPTION_LAST];
     ngx_quic_secrets_t                next_key;
-    uint64_t                          crypto_offset[NGX_QUIC_ENCRYPTION_LAST];
+    uint64_t                          crypto_offset_out[NGX_QUIC_ENCRYPTION_LAST];
+    uint64_t                          crypto_offset_in[NGX_QUIC_ENCRYPTION_LAST];
 
     ngx_ssl_t                        *ssl;
 
@@ -334,11 +335,11 @@ ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
 
     frame->level = level;
     frame->type = NGX_QUIC_FT_CRYPTO;
-    frame->u.crypto.offset += qc->crypto_offset[level];
+    frame->u.crypto.offset += qc->crypto_offset_out[level];
     frame->u.crypto.len = len;
     frame->u.crypto.data = frame->data;
 
-    qc->crypto_offset[level] += len;
+    qc->crypto_offset_out[level] += len;
 
     ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d", len, level);
 
@@ -1368,14 +1369,21 @@ static ngx_int_t
 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
     ngx_quic_crypto_frame_t *f)
 {
-    int                sslerr;
-    ssize_t            n;
-    ngx_ssl_conn_t    *ssl_conn;
+    int                     sslerr;
+    ssize_t                 n;
+    uint64_t               *curr_offset;
+    ngx_ssl_conn_t         *ssl_conn;
+    ngx_quic_connection_t  *qc;
+
+    qc = c->quic;
+
+    curr_offset = &qc->crypto_offset_in[pkt->level];
 
-    if (f->offset != 0x0) {
+    if (f->offset != *curr_offset) {
         ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                      "crypto frame with non-zero offset");
-        // TODO: add support for crypto frames spanning packets
+                      "crypto frame with unexpected offset");
+
+        /* TODO: support reordering/buffering of data */
         return NGX_ERROR;
     }
 
@@ -1394,6 +1402,8 @@ ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
         return NGX_ERROR;
     }
 
+    *curr_offset += f->len;
+
     n = SSL_do_handshake(ssl_conn);
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);