comparison src/event/ngx_event_quic.c @ 8328:e76be8639621 quic

Added basic offset support in client CRYPTO frames. 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.
author Vladimir Homutov <vl@nginx.com>
date Tue, 07 Apr 2020 15:50:38 +0300
parents 0ae50d90658a
children bda817d16cc2
comparison
equal deleted inserted replaced
8327:0ae50d90658a 8328:e76be8639621
67 ngx_quic_state_t state; 67 ngx_quic_state_t state;
68 68
69 ngx_quic_namespace_t ns[NGX_QUIC_NAMESPACE_LAST]; 69 ngx_quic_namespace_t ns[NGX_QUIC_NAMESPACE_LAST];
70 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST]; 70 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST];
71 ngx_quic_secrets_t next_key; 71 ngx_quic_secrets_t next_key;
72 uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST]; 72 uint64_t crypto_offset_out[NGX_QUIC_ENCRYPTION_LAST];
73 uint64_t crypto_offset_in[NGX_QUIC_ENCRYPTION_LAST];
73 74
74 ngx_ssl_t *ssl; 75 ngx_ssl_t *ssl;
75 76
76 ngx_event_t push; 77 ngx_event_t push;
77 ngx_event_t retry; 78 ngx_event_t retry;
332 333
333 ngx_memcpy(frame->data, data, len); 334 ngx_memcpy(frame->data, data, len);
334 335
335 frame->level = level; 336 frame->level = level;
336 frame->type = NGX_QUIC_FT_CRYPTO; 337 frame->type = NGX_QUIC_FT_CRYPTO;
337 frame->u.crypto.offset += qc->crypto_offset[level]; 338 frame->u.crypto.offset += qc->crypto_offset_out[level];
338 frame->u.crypto.len = len; 339 frame->u.crypto.len = len;
339 frame->u.crypto.data = frame->data; 340 frame->u.crypto.data = frame->data;
340 341
341 qc->crypto_offset[level] += len; 342 qc->crypto_offset_out[level] += len;
342 343
343 ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d", len, level); 344 ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d", len, level);
344 345
345 ngx_quic_queue_frame(qc, frame); 346 ngx_quic_queue_frame(qc, frame);
346 347
1366 1367
1367 static ngx_int_t 1368 static ngx_int_t
1368 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, 1369 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
1369 ngx_quic_crypto_frame_t *f) 1370 ngx_quic_crypto_frame_t *f)
1370 { 1371 {
1371 int sslerr; 1372 int sslerr;
1372 ssize_t n; 1373 ssize_t n;
1373 ngx_ssl_conn_t *ssl_conn; 1374 uint64_t *curr_offset;
1374 1375 ngx_ssl_conn_t *ssl_conn;
1375 if (f->offset != 0x0) { 1376 ngx_quic_connection_t *qc;
1377
1378 qc = c->quic;
1379
1380 curr_offset = &qc->crypto_offset_in[pkt->level];
1381
1382 if (f->offset != *curr_offset) {
1376 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1383 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1377 "crypto frame with non-zero offset"); 1384 "crypto frame with unexpected offset");
1378 // TODO: add support for crypto frames spanning packets 1385
1386 /* TODO: support reordering/buffering of data */
1379 return NGX_ERROR; 1387 return NGX_ERROR;
1380 } 1388 }
1381 1389
1382 ssl_conn = c->ssl->connection; 1390 ssl_conn = c->ssl->connection;
1383 1391
1391 { 1399 {
1392 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, 1400 ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
1393 "SSL_provide_quic_data() failed"); 1401 "SSL_provide_quic_data() failed");
1394 return NGX_ERROR; 1402 return NGX_ERROR;
1395 } 1403 }
1404
1405 *curr_offset += f->len;
1396 1406
1397 n = SSL_do_handshake(ssl_conn); 1407 n = SSL_do_handshake(ssl_conn);
1398 1408
1399 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); 1409 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
1400 1410