Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 7810:167d32476737 quic
Crypto buffer frames reordering.
If offset in CRYPTO frame doesn't match expected, following actions are taken:
a) Duplicate frames or frames within [0...current offset] are ignored
b) New data from intersecting ranges (starts before current_offset, ends
after) is consumed
c) "Future" frames are stored in a sorted queue (min offset .. max offset)
Once a frame is consumed, current offset is updated and the queue is inspected:
we iterate the queue until the gap is found and act as described
above for each frame.
The amount of data in buffered frames is limited by corresponding macro.
The CRYPTO and STREAM frame structures are now compatible: they share
the same set of initial fields. This allows to have code that deals with
both of this frames.
The ordering layer now processes the frame with offset and invokes the
handler when it can organise an ordered stream of data.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Tue, 14 Apr 2020 12:16:25 +0300 |
parents | 6ad871b63422 |
children | 72d20158c814 |
comparison
equal
deleted
inserted
replaced
7809:6ad871b63422 | 7810:167d32476737 |
---|---|
24 #define NGX_QUIC_SEND_CTX_LAST (NGX_QUIC_ENCRYPTION_LAST - 1) | 24 #define NGX_QUIC_SEND_CTX_LAST (NGX_QUIC_ENCRYPTION_LAST - 1) |
25 | 25 |
26 #define NGX_QUIC_STREAMS_INC 16 | 26 #define NGX_QUIC_STREAMS_INC 16 |
27 #define NGX_QUIC_STREAMS_LIMIT (1ULL < 60) | 27 #define NGX_QUIC_STREAMS_LIMIT (1ULL < 60) |
28 | 28 |
29 /* | |
30 * 7.4. Cryptographic Message Buffering | |
31 * Implementations MUST support buffering at least 4096 bytes of data | |
32 */ | |
33 #define NGX_QUIC_MAX_BUFFERED 65535 | |
34 | |
29 | 35 |
30 typedef enum { | 36 typedef enum { |
31 NGX_QUIC_ST_INITIAL, /* connection just created */ | 37 NGX_QUIC_ST_INITIAL, /* connection just created */ |
32 NGX_QUIC_ST_HANDSHAKE, /* handshake started */ | 38 NGX_QUIC_ST_HANDSHAKE, /* handshake started */ |
33 NGX_QUIC_ST_EARLY_DATA, /* handshake in progress */ | 39 NGX_QUIC_ST_EARLY_DATA, /* handshake in progress */ |
62 ngx_queue_t frames; | 68 ngx_queue_t frames; |
63 ngx_queue_t sent; | 69 ngx_queue_t sent; |
64 } ngx_quic_send_ctx_t; | 70 } ngx_quic_send_ctx_t; |
65 | 71 |
66 | 72 |
73 /* ordered frames stream context */ | |
74 typedef struct { | |
75 uint64_t sent; | |
76 uint64_t received; | |
77 ngx_queue_t frames; | |
78 size_t total; /* size of buffered data */ | |
79 } ngx_quic_frames_stream_t; | |
80 | |
81 | |
67 struct ngx_quic_connection_s { | 82 struct ngx_quic_connection_s { |
68 ngx_str_t scid; | 83 ngx_str_t scid; |
69 ngx_str_t dcid; | 84 ngx_str_t dcid; |
70 ngx_str_t token; | 85 ngx_str_t token; |
71 | 86 |
76 ngx_quic_state_t state; | 91 ngx_quic_state_t state; |
77 | 92 |
78 ngx_quic_send_ctx_t send_ctx[NGX_QUIC_SEND_CTX_LAST]; | 93 ngx_quic_send_ctx_t send_ctx[NGX_QUIC_SEND_CTX_LAST]; |
79 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST]; | 94 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST]; |
80 ngx_quic_secrets_t next_key; | 95 ngx_quic_secrets_t next_key; |
81 uint64_t crypto_offset_out[NGX_QUIC_ENCRYPTION_LAST]; | 96 ngx_quic_frames_stream_t crypto[NGX_QUIC_ENCRYPTION_LAST]; |
82 uint64_t crypto_offset_in[NGX_QUIC_ENCRYPTION_LAST]; | |
83 | 97 |
84 ngx_ssl_t *ssl; | 98 ngx_ssl_t *ssl; |
85 | 99 |
86 ngx_event_t push; | 100 ngx_event_t push; |
87 ngx_event_t retry; | 101 ngx_event_t retry; |
145 static ngx_int_t ngx_quic_handle_ack_frame(ngx_connection_t *c, | 159 static ngx_int_t ngx_quic_handle_ack_frame(ngx_connection_t *c, |
146 ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f); | 160 ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f); |
147 static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c, | 161 static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c, |
148 ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max); | 162 ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max); |
149 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, | 163 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, |
150 ngx_quic_header_t *pkt, ngx_quic_crypto_frame_t *frame); | 164 ngx_quic_header_t *pkt, ngx_quic_frame_t *frame); |
165 static ngx_int_t ngx_quic_adjust_frame_offset(ngx_connection_t *c, | |
166 ngx_quic_frame_t *f, uint64_t offset_in); | |
167 static ngx_int_t ngx_quic_buffer_frame(ngx_connection_t *c, | |
168 ngx_quic_frames_stream_t *stream, ngx_quic_frame_t *f); | |
169 | |
170 typedef ngx_int_t (*ngx_quic_frame_handler_pt)(ngx_connection_t *c, | |
171 ngx_quic_frame_t *frame); | |
172 | |
173 static ngx_int_t ngx_quic_handle_ordered_frame(ngx_connection_t *c, | |
174 ngx_quic_frames_stream_t *fs, ngx_quic_frame_t *frame, | |
175 ngx_quic_frame_handler_pt handler); | |
176 | |
177 static ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, | |
178 ngx_quic_frame_t *frame); | |
151 static ngx_int_t ngx_quic_handle_stream_frame(ngx_connection_t *c, | 179 static ngx_int_t ngx_quic_handle_stream_frame(ngx_connection_t *c, |
152 ngx_quic_header_t *pkt, ngx_quic_stream_frame_t *frame); | 180 ngx_quic_header_t *pkt, ngx_quic_stream_frame_t *frame); |
153 static ngx_int_t ngx_quic_handle_max_streams(ngx_connection_t *c); | 181 static ngx_int_t ngx_quic_handle_max_streams(ngx_connection_t *c); |
154 static ngx_int_t ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c, | 182 static ngx_int_t ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c, |
155 ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f); | 183 ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f); |
290 | 318 |
291 static int | 319 static int |
292 ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, | 320 ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, |
293 enum ssl_encryption_level_t level, const uint8_t *data, size_t len) | 321 enum ssl_encryption_level_t level, const uint8_t *data, size_t len) |
294 { | 322 { |
295 u_char *p, *end; | 323 u_char *p, *end; |
296 size_t client_params_len; | 324 size_t client_params_len; |
297 const uint8_t *client_params; | 325 const uint8_t *client_params; |
298 ngx_quic_frame_t *frame; | 326 ngx_quic_frame_t *frame; |
299 ngx_connection_t *c; | 327 ngx_connection_t *c; |
300 ngx_quic_connection_t *qc; | 328 ngx_quic_connection_t *qc; |
329 ngx_quic_frames_stream_t *fs; | |
301 | 330 |
302 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | 331 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
303 qc = c->quic; | 332 qc = c->quic; |
304 | 333 |
305 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | 334 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
333 | 362 |
334 qc->client_tp_done = 1; | 363 qc->client_tp_done = 1; |
335 } | 364 } |
336 } | 365 } |
337 | 366 |
367 fs = &qc->crypto[level]; | |
368 | |
338 frame = ngx_quic_alloc_frame(c, len); | 369 frame = ngx_quic_alloc_frame(c, len); |
339 if (frame == NULL) { | 370 if (frame == NULL) { |
340 return 0; | 371 return 0; |
341 } | 372 } |
342 | 373 |
343 ngx_memcpy(frame->data, data, len); | 374 ngx_memcpy(frame->data, data, len); |
344 | 375 |
345 frame->level = level; | 376 frame->level = level; |
346 frame->type = NGX_QUIC_FT_CRYPTO; | 377 frame->type = NGX_QUIC_FT_CRYPTO; |
347 frame->u.crypto.offset += qc->crypto_offset_out[level]; | 378 frame->u.crypto.offset += fs->sent; |
348 frame->u.crypto.len = len; | 379 frame->u.crypto.length = len; |
349 frame->u.crypto.data = frame->data; | 380 frame->u.crypto.data = frame->data; |
350 | 381 |
351 qc->crypto_offset_out[level] += len; | 382 fs->sent += len; |
352 | 383 |
353 ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d", len, level); | 384 ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d", len, level); |
354 | 385 |
355 ngx_quic_queue_frame(qc, frame); | 386 ngx_quic_queue_frame(qc, frame); |
356 | 387 |
476 qc->state = NGX_QUIC_ST_INITIAL; | 507 qc->state = NGX_QUIC_ST_INITIAL; |
477 | 508 |
478 ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel, | 509 ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel, |
479 ngx_quic_rbtree_insert_stream); | 510 ngx_quic_rbtree_insert_stream); |
480 | 511 |
481 for (i = 0; i < 3; i++) { | 512 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { |
482 ngx_queue_init(&qc->send_ctx[i].frames); | 513 ngx_queue_init(&qc->send_ctx[i].frames); |
483 ngx_queue_init(&qc->send_ctx[i].sent); | 514 ngx_queue_init(&qc->send_ctx[i].sent); |
484 } | 515 } |
516 | |
517 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) { | |
518 ngx_queue_init(&qc->crypto[i].frames); | |
519 } | |
485 | 520 |
486 ngx_queue_init(&qc->free_frames); | 521 ngx_queue_init(&qc->free_frames); |
487 | 522 |
488 qc->retry.log = c->log; | 523 qc->retry.log = c->log; |
489 qc->retry.data = c; | 524 qc->retry.data = c; |
711 ngx_quic_stream_t *qs; | 746 ngx_quic_stream_t *qs; |
712 ngx_quic_connection_t *qc; | 747 ngx_quic_connection_t *qc; |
713 | 748 |
714 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "close quic connection"); | 749 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "close quic connection"); |
715 | 750 |
751 // TODO: free frames from reorder queue if any | |
752 | |
716 qc = c->quic; | 753 qc = c->quic; |
717 | 754 |
718 if (qc) { | 755 if (qc) { |
719 qc->closing = 1; | 756 qc->closing = 1; |
720 tree = &qc->streams.tree; | 757 tree = &qc->streams.tree; |
827 | 864 |
828 } else { | 865 } else { |
829 rc = ngx_quic_app_input(c, &pkt); | 866 rc = ngx_quic_app_input(c, &pkt); |
830 } | 867 } |
831 | 868 |
832 if (rc != NGX_OK) { | 869 if (rc == NGX_ERROR) { |
833 return rc; | 870 return NGX_ERROR; |
834 } | 871 } |
872 | |
873 /* NGX_OK || NGX_DECLINED */ | |
874 | |
875 /* | |
876 * we get NGX_DECLINED when there are no keys [yet] available | |
877 * to decrypt packet. | |
878 * Instead of queueing it, we ignore it and rely on the sender's | |
879 * retransmission: | |
880 * | |
881 * 12.2. Coalescing Packets: | |
882 * | |
883 * For example, if decryption fails (because the keys are | |
884 * not available or any other reason), the receiver MAY either | |
885 * discard or buffer the packet for later processing and MUST | |
886 * attempt to process the remaining packets. | |
887 */ | |
835 | 888 |
836 /* b->pos is at header end, adjust by actual packet length */ | 889 /* b->pos is at header end, adjust by actual packet length */ |
837 p = b->pos + pkt.len; | 890 p = b->pos + pkt.len; |
838 b->pos = p; /* reset b->pos to the next packet start */ | 891 b->pos = p; /* reset b->pos to the next packet start */ |
839 } | 892 } |
1117 | 1170 |
1118 break; | 1171 break; |
1119 | 1172 |
1120 case NGX_QUIC_FT_CRYPTO: | 1173 case NGX_QUIC_FT_CRYPTO: |
1121 | 1174 |
1122 if (ngx_quic_handle_crypto_frame(c, pkt, &frame.u.crypto) | 1175 if (ngx_quic_handle_crypto_frame(c, pkt, &frame) != NGX_OK) { |
1123 != NGX_OK) | |
1124 { | |
1125 return NGX_ERROR; | 1176 return NGX_ERROR; |
1126 } | 1177 } |
1127 | 1178 |
1128 ack_this = 1; | 1179 ack_this = 1; |
1129 break; | 1180 break; |
1371 } | 1422 } |
1372 | 1423 |
1373 | 1424 |
1374 static ngx_int_t | 1425 static ngx_int_t |
1375 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, | 1426 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, |
1376 ngx_quic_crypto_frame_t *f) | 1427 ngx_quic_frame_t *frame) |
1377 { | 1428 { |
1378 int sslerr; | 1429 ngx_quic_connection_t *qc; |
1379 ssize_t n; | 1430 ngx_quic_frames_stream_t *fs; |
1380 uint64_t *curr_offset; | |
1381 ngx_ssl_conn_t *ssl_conn; | |
1382 ngx_quic_connection_t *qc; | |
1383 | 1431 |
1384 qc = c->quic; | 1432 qc = c->quic; |
1385 | 1433 fs = &qc->crypto[pkt->level]; |
1386 curr_offset = &qc->crypto_offset_in[pkt->level]; | 1434 |
1387 | 1435 return ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_crypto_input); |
1388 if (f->offset != *curr_offset) { | 1436 } |
1437 | |
1438 | |
1439 static ngx_int_t | |
1440 ngx_quic_handle_ordered_frame(ngx_connection_t *c, ngx_quic_frames_stream_t *fs, | |
1441 ngx_quic_frame_t *frame, ngx_quic_frame_handler_pt handler) | |
1442 { | |
1443 size_t full_len; | |
1444 ngx_queue_t *q; | |
1445 ngx_quic_ordered_frame_t *f; | |
1446 | |
1447 f = &frame->u.ord; | |
1448 | |
1449 if (f->offset > fs->received) { | |
1450 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1451 "out-of-order frame: expecting %ui got %ui", | |
1452 fs->received, f->offset); | |
1453 | |
1454 return ngx_quic_buffer_frame(c, fs, frame); | |
1455 } | |
1456 | |
1457 if (f->offset < fs->received) { | |
1458 | |
1459 if (ngx_quic_adjust_frame_offset(c, frame, fs->received) | |
1460 == NGX_DONE) | |
1461 { | |
1462 /* old/duplicate data range */ | |
1463 return NGX_OK; | |
1464 } | |
1465 | |
1466 /* intersecting data range, frame modified */ | |
1467 } | |
1468 | |
1469 /* f->offset == fs->received */ | |
1470 | |
1471 if (handler(c, frame) != NGX_OK) { | |
1472 return NGX_ERROR; | |
1473 } | |
1474 | |
1475 fs->received += f->length; | |
1476 | |
1477 /* now check the queue if we can continue with buffered frames */ | |
1478 | |
1479 do { | |
1480 q = ngx_queue_head(&fs->frames); | |
1481 if (q == ngx_queue_sentinel(&fs->frames)) { | |
1482 break; | |
1483 } | |
1484 | |
1485 frame = ngx_queue_data(q, ngx_quic_frame_t, queue); | |
1486 f = &frame->u.ord; | |
1487 | |
1488 if (f->offset > fs->received) { | |
1489 /* gap found, nothing more to do */ | |
1490 break; | |
1491 } | |
1492 | |
1493 full_len = f->length; | |
1494 | |
1495 if (f->offset < fs->received) { | |
1496 | |
1497 if (ngx_quic_adjust_frame_offset(c, frame, fs->received) | |
1498 == NGX_DONE) | |
1499 { | |
1500 /* old/duplicate data range */ | |
1501 ngx_queue_remove(q); | |
1502 fs->total -= f->length; | |
1503 | |
1504 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1505 "skipped buffered frame, total %ui", fs->total); | |
1506 ngx_quic_free_frame(c, frame); | |
1507 continue; | |
1508 } | |
1509 | |
1510 /* frame was adjusted, proceed to input */ | |
1511 } | |
1512 | |
1513 /* f->offset == fs->received */ | |
1514 | |
1515 if (handler(c, frame) != NGX_OK) { | |
1516 return NGX_ERROR; | |
1517 } | |
1518 | |
1519 fs->received += f->length; | |
1520 fs->total -= full_len; | |
1521 | |
1522 ngx_queue_remove(q); | |
1523 | |
1524 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1525 "consumed buffered frame, total %ui", fs->total); | |
1526 | |
1527 ngx_quic_free_frame(c, frame); | |
1528 | |
1529 } while (1); | |
1530 | |
1531 return NGX_OK; | |
1532 } | |
1533 | |
1534 | |
1535 static ngx_int_t | |
1536 ngx_quic_adjust_frame_offset(ngx_connection_t *c, ngx_quic_frame_t *frame, | |
1537 uint64_t offset_in) | |
1538 { | |
1539 size_t tail; | |
1540 ngx_quic_ordered_frame_t *f; | |
1541 | |
1542 f = &frame->u.ord; | |
1543 | |
1544 tail = offset_in - f->offset; | |
1545 | |
1546 if (tail >= f->length) { | |
1547 /* range preceeding already received data or duplicate, ignore */ | |
1548 | |
1549 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1550 "old or duplicate data in ordered frame, ignored"); | |
1551 return NGX_DONE; | |
1552 } | |
1553 | |
1554 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1555 "adjusted ordered frame data start to expected offset"); | |
1556 | |
1557 /* intersecting range: adjust data size */ | |
1558 | |
1559 f->offset += tail; | |
1560 f->data += tail; | |
1561 f->length -= tail; | |
1562 | |
1563 return NGX_OK; | |
1564 } | |
1565 | |
1566 | |
1567 static ngx_int_t | |
1568 ngx_quic_buffer_frame(ngx_connection_t *c, ngx_quic_frames_stream_t *fs, | |
1569 ngx_quic_frame_t *frame) | |
1570 { | |
1571 u_char *data; | |
1572 ngx_queue_t *q; | |
1573 ngx_quic_frame_t *dst, *item; | |
1574 ngx_quic_ordered_frame_t *f, *df; | |
1575 | |
1576 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_quic_buffer_frame"); | |
1577 | |
1578 f = &frame->u.ord; | |
1579 | |
1580 /* frame start offset is in the future, buffer it */ | |
1581 | |
1582 /* check limit on total size used by all buffered frames, not actual data */ | |
1583 if (NGX_QUIC_MAX_BUFFERED - fs->total < f->length) { | |
1389 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 1584 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
1390 "crypto frame with unexpected offset"); | 1585 "ordered input buffer limit exceeded"); |
1391 | 1586 return NGX_ERROR; |
1392 /* TODO: support reordering/buffering of data */ | 1587 } |
1393 return NGX_ERROR; | 1588 |
1394 } | 1589 dst = ngx_quic_alloc_frame(c, f->length); |
1590 if (dst == NULL) { | |
1591 return NGX_ERROR; | |
1592 } | |
1593 | |
1594 data = dst->data; | |
1595 ngx_memcpy(dst, frame, sizeof(ngx_quic_frame_t)); | |
1596 dst->data = data; | |
1597 | |
1598 ngx_memcpy(dst->data, f->data, f->length); | |
1599 | |
1600 df = &dst->u.ord; | |
1601 df->data = dst->data; | |
1602 | |
1603 fs->total += f->length; | |
1604 | |
1605 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1606 "ordered frame with unexpected offset: buffered, total %ui", | |
1607 fs->total); | |
1608 | |
1609 /* TODO: do we need some timeout for this queue ? */ | |
1610 | |
1611 if (ngx_queue_empty(&fs->frames)) { | |
1612 ngx_queue_insert_after(&fs->frames, &dst->queue); | |
1613 return NGX_OK; | |
1614 } | |
1615 | |
1616 for (q = ngx_queue_last(&fs->frames); | |
1617 q != ngx_queue_sentinel(&fs->frames); | |
1618 q = ngx_queue_prev(q)) | |
1619 { | |
1620 item = ngx_queue_data(q, ngx_quic_frame_t, queue); | |
1621 f = &item->u.ord; | |
1622 | |
1623 if (f->offset < df->offset) { | |
1624 ngx_queue_insert_after(q, &dst->queue); | |
1625 return NGX_OK; | |
1626 } | |
1627 } | |
1628 | |
1629 ngx_queue_insert_after(&fs->frames, &dst->queue); | |
1630 | |
1631 return NGX_OK; | |
1632 } | |
1633 | |
1634 | |
1635 static ngx_int_t | |
1636 ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame) | |
1637 { | |
1638 int sslerr; | |
1639 ssize_t n; | |
1640 ngx_ssl_conn_t *ssl_conn; | |
1641 ngx_quic_crypto_frame_t *f; | |
1642 | |
1643 f = &frame->u.crypto; | |
1395 | 1644 |
1396 ssl_conn = c->ssl->connection; | 1645 ssl_conn = c->ssl->connection; |
1397 | 1646 |
1398 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 1647 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1399 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", | 1648 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", |
1400 (int) SSL_quic_read_level(ssl_conn), | 1649 (int) SSL_quic_read_level(ssl_conn), |
1401 (int) SSL_quic_write_level(ssl_conn)); | 1650 (int) SSL_quic_write_level(ssl_conn)); |
1402 | 1651 |
1403 if (!SSL_provide_quic_data(ssl_conn, SSL_quic_read_level(ssl_conn), | 1652 if (!SSL_provide_quic_data(ssl_conn, SSL_quic_read_level(ssl_conn), |
1404 f->data, f->len)) | 1653 f->data, f->length)) |
1405 { | 1654 { |
1406 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | 1655 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, |
1407 "SSL_provide_quic_data() failed"); | 1656 "SSL_provide_quic_data() failed"); |
1408 return NGX_ERROR; | 1657 return NGX_ERROR; |
1409 } | 1658 } |
1410 | |
1411 *curr_offset += f->len; | |
1412 | 1659 |
1413 n = SSL_do_handshake(ssl_conn); | 1660 n = SSL_do_handshake(ssl_conn); |
1414 | 1661 |
1415 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | 1662 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); |
1416 | 1663 |