comparison src/event/quic/ngx_event_quic.c @ 8750:41807e581de9 quic

QUIC: separate files for stream related processing.
author Vladimir Homutov <vl@nginx.com>
date Tue, 13 Apr 2021 14:40:00 +0300
parents 660c4a2f95f3
children bc910a5ec737
comparison
equal deleted inserted replaced
8749:660c4a2f95f3 8750:41807e581de9
18 /* 18 /*
19 * 7.4. Cryptographic Message Buffering 19 * 7.4. Cryptographic Message Buffering
20 * Implementations MUST support buffering at least 4096 bytes of data 20 * Implementations MUST support buffering at least 4096 bytes of data
21 */ 21 */
22 #define NGX_QUIC_MAX_BUFFERED 65535 22 #define NGX_QUIC_MAX_BUFFERED 65535
23
24 #define NGX_QUIC_STREAM_GONE (void *) -1
25 23
26 /* 24 /*
27 * Endpoints MUST discard packets that are too small to be valid QUIC 25 * Endpoints MUST discard packets that are too small to be valid QUIC
28 * packets. With the set of AEAD functions defined in [QUIC-TLS], 26 * packets. With the set of AEAD functions defined in [QUIC-TLS],
29 * packets that are smaller than 21 bytes are never valid. 27 * packets that are smaller than 21 bytes are never valid.
78 static ngx_inline size_t ngx_quic_max_udp_payload(ngx_connection_t *c); 76 static ngx_inline size_t ngx_quic_max_udp_payload(ngx_connection_t *c);
79 static void ngx_quic_input_handler(ngx_event_t *rev); 77 static void ngx_quic_input_handler(ngx_event_t *rev);
80 78
81 static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc); 79 static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc);
82 static void ngx_quic_close_timer_handler(ngx_event_t *ev); 80 static void ngx_quic_close_timer_handler(ngx_event_t *ev);
83 static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c,
84 ngx_quic_connection_t *qc);
85 81
86 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, 82 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b,
87 ngx_quic_conf_t *conf); 83 ngx_quic_conf_t *conf);
88 static ngx_int_t ngx_quic_process_packet(ngx_connection_t *c, 84 static ngx_int_t ngx_quic_process_packet(ngx_connection_t *c,
89 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 85 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
113 static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c, 109 static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c,
114 ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max, 110 ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max,
115 ngx_msec_t *send_time); 111 ngx_msec_t *send_time);
116 static void ngx_quic_rtt_sample(ngx_connection_t *c, ngx_quic_ack_frame_t *ack, 112 static void ngx_quic_rtt_sample(ngx_connection_t *c, ngx_quic_ack_frame_t *ack,
117 enum ssl_encryption_level_t level, ngx_msec_t send_time); 113 enum ssl_encryption_level_t level, ngx_msec_t send_time);
118 static void ngx_quic_handle_stream_ack(ngx_connection_t *c,
119 ngx_quic_frame_t *f);
120 114
121 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, 115 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c,
122 ngx_quic_header_t *pkt, ngx_quic_frame_t *frame); 116 ngx_quic_header_t *pkt, ngx_quic_frame_t *frame);
123 ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, 117 ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c,
124 ngx_quic_frame_t *frame, void *data); 118 ngx_quic_frame_t *frame, void *data);
125 static ngx_int_t ngx_quic_handle_stream_frame(ngx_connection_t *c, 119
126 ngx_quic_header_t *pkt, ngx_quic_frame_t *frame);
127 static ngx_int_t ngx_quic_stream_input(ngx_connection_t *c,
128 ngx_quic_frame_t *frame, void *data);
129
130 static ngx_int_t ngx_quic_handle_max_data_frame(ngx_connection_t *c,
131 ngx_quic_max_data_frame_t *f);
132 static ngx_int_t ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c,
133 ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f);
134 static ngx_int_t ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c,
135 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f);
136 static ngx_int_t ngx_quic_handle_max_stream_data_frame(ngx_connection_t *c,
137 ngx_quic_header_t *pkt, ngx_quic_max_stream_data_frame_t *f);
138 static ngx_int_t ngx_quic_handle_reset_stream_frame(ngx_connection_t *c,
139 ngx_quic_header_t *pkt, ngx_quic_reset_stream_frame_t *f);
140 static ngx_int_t ngx_quic_handle_stop_sending_frame(ngx_connection_t *c,
141 ngx_quic_header_t *pkt, ngx_quic_stop_sending_frame_t *f);
142 static ngx_int_t ngx_quic_handle_max_streams_frame(ngx_connection_t *c,
143 ngx_quic_header_t *pkt, ngx_quic_max_streams_frame_t *f);
144
145 static ngx_int_t ngx_quic_output(ngx_connection_t *c);
146 static ngx_uint_t ngx_quic_get_padding_level(ngx_connection_t *c); 120 static ngx_uint_t ngx_quic_get_padding_level(ngx_connection_t *c);
147 static ngx_int_t ngx_quic_generate_ack(ngx_connection_t *c, 121 static ngx_int_t ngx_quic_generate_ack(ngx_connection_t *c,
148 ngx_quic_send_ctx_t *ctx); 122 ngx_quic_send_ctx_t *ctx);
149 static ssize_t ngx_quic_output_packet(ngx_connection_t *c, 123 static ssize_t ngx_quic_output_packet(ngx_connection_t *c,
150 ngx_quic_send_ctx_t *ctx, u_char *data, size_t max, size_t min); 124 ngx_quic_send_ctx_t *ctx, u_char *data, size_t max, size_t min);
157 static ngx_int_t ngx_quic_detect_lost(ngx_connection_t *c); 131 static ngx_int_t ngx_quic_detect_lost(ngx_connection_t *c);
158 static void ngx_quic_set_lost_timer(ngx_connection_t *c); 132 static void ngx_quic_set_lost_timer(ngx_connection_t *c);
159 static void ngx_quic_resend_frames(ngx_connection_t *c, 133 static void ngx_quic_resend_frames(ngx_connection_t *c,
160 ngx_quic_send_ctx_t *ctx); 134 ngx_quic_send_ctx_t *ctx);
161 static void ngx_quic_push_handler(ngx_event_t *ev); 135 static void ngx_quic_push_handler(ngx_event_t *ev);
162
163 static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp,
164 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
165 static ngx_quic_stream_t *ngx_quic_find_stream(ngx_rbtree_t *rbtree,
166 uint64_t id);
167 static ngx_quic_stream_t *ngx_quic_create_client_stream(ngx_connection_t *c,
168 uint64_t id);
169 static ngx_quic_stream_t *ngx_quic_create_stream(ngx_connection_t *c,
170 uint64_t id, size_t rcvbuf_size);
171 static ssize_t ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf,
172 size_t size);
173 static ssize_t ngx_quic_stream_send(ngx_connection_t *c, u_char *buf,
174 size_t size);
175 static ngx_chain_t *ngx_quic_stream_send_chain(ngx_connection_t *c,
176 ngx_chain_t *in, off_t limit);
177 static size_t ngx_quic_max_stream_flow(ngx_connection_t *c);
178 static void ngx_quic_stream_cleanup_handler(void *data);
179 static void ngx_quic_shutdown_quic(ngx_connection_t *c);
180 136
181 static void ngx_quic_congestion_ack(ngx_connection_t *c, 137 static void ngx_quic_congestion_ack(ngx_connection_t *c,
182 ngx_quic_frame_t *frame); 138 ngx_quic_frame_t *frame);
183 static void ngx_quic_congestion_lost(ngx_connection_t *c, 139 static void ngx_quic_congestion_lost(ngx_connection_t *c,
184 ngx_quic_frame_t *frame); 140 ngx_quic_frame_t *frame);
1602 1558
1603 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic close timer"); 1559 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic close timer");
1604 1560
1605 c = ev->data; 1561 c = ev->data;
1606 ngx_quic_close_connection(c, NGX_DONE); 1562 ngx_quic_close_connection(c, NGX_DONE);
1607 }
1608
1609
1610 static ngx_int_t
1611 ngx_quic_close_streams(ngx_connection_t *c, ngx_quic_connection_t *qc)
1612 {
1613 ngx_event_t *rev, *wev;
1614 ngx_rbtree_t *tree;
1615 ngx_rbtree_node_t *node;
1616 ngx_quic_stream_t *qs;
1617
1618 #if (NGX_DEBUG)
1619 ngx_uint_t ns;
1620 #endif
1621
1622 tree = &qc->streams.tree;
1623
1624 if (tree->root == tree->sentinel) {
1625 return NGX_OK;
1626 }
1627
1628 #if (NGX_DEBUG)
1629 ns = 0;
1630 #endif
1631
1632 for (node = ngx_rbtree_min(tree->root, tree->sentinel);
1633 node;
1634 node = ngx_rbtree_next(tree, node))
1635 {
1636 qs = (ngx_quic_stream_t *) node;
1637
1638 rev = qs->c->read;
1639 rev->error = 1;
1640 rev->ready = 1;
1641
1642 wev = qs->c->write;
1643 wev->error = 1;
1644 wev->ready = 1;
1645
1646 ngx_post_event(rev, &ngx_posted_events);
1647
1648 if (rev->timer_set) {
1649 ngx_del_timer(rev);
1650 }
1651
1652 #if (NGX_DEBUG)
1653 ns++;
1654 #endif
1655 }
1656
1657 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
1658 "quic connection has %ui active streams", ns);
1659
1660 return NGX_AGAIN;
1661 }
1662
1663
1664 ngx_int_t
1665 ngx_quic_reset_stream(ngx_connection_t *c, ngx_uint_t err)
1666 {
1667 ngx_event_t *wev;
1668 ngx_connection_t *pc;
1669 ngx_quic_frame_t *frame;
1670 ngx_quic_stream_t *qs;
1671 ngx_quic_connection_t *qc;
1672
1673 qs = c->quic;
1674 pc = qs->parent;
1675 qc = ngx_quic_get_connection(pc);
1676
1677 frame = ngx_quic_alloc_frame(pc);
1678 if (frame == NULL) {
1679 return NGX_ERROR;
1680 }
1681
1682 frame->level = ssl_encryption_application;
1683 frame->type = NGX_QUIC_FT_RESET_STREAM;
1684 frame->u.reset_stream.id = qs->id;
1685 frame->u.reset_stream.error_code = err;
1686 frame->u.reset_stream.final_size = c->sent;
1687
1688 ngx_quic_queue_frame(qc, frame);
1689
1690 wev = c->write;
1691 wev->error = 1;
1692 wev->ready = 1;
1693
1694 return NGX_OK;
1695 } 1563 }
1696 1564
1697 1565
1698 static ngx_int_t 1566 static ngx_int_t
1699 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf) 1567 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf)
3150 3018
3151 return duration; 3019 return duration;
3152 } 3020 }
3153 3021
3154 3022
3155 static void
3156 ngx_quic_handle_stream_ack(ngx_connection_t *c, ngx_quic_frame_t *f)
3157 {
3158 uint64_t sent, unacked;
3159 ngx_event_t *wev;
3160 ngx_quic_stream_t *sn;
3161 ngx_quic_connection_t *qc;
3162
3163 qc = ngx_quic_get_connection(c);
3164
3165 sn = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);
3166 if (sn == NULL) {
3167 return;
3168 }
3169
3170 wev = sn->c->write;
3171 sent = sn->c->sent;
3172 unacked = sent - sn->acked;
3173
3174 if (unacked >= NGX_QUIC_STREAM_BUFSIZE && wev->active) {
3175 wev->ready = 1;
3176 ngx_post_event(wev, &ngx_posted_events);
3177 }
3178
3179 sn->acked += f->u.stream.length;
3180
3181 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, sn->c->log, 0,
3182 "quic stream ack len:%uL acked:%uL unacked:%uL",
3183 f->u.stream.length, sn->acked, sent - sn->acked);
3184 }
3185
3186
3187 static ngx_int_t 3023 static ngx_int_t
3188 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, 3024 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
3189 ngx_quic_frame_t *frame) 3025 ngx_quic_frame_t *frame)
3190 { 3026 {
3191 uint64_t last; 3027 uint64_t last;
3332 3168
3333 return NGX_OK; 3169 return NGX_OK;
3334 } 3170 }
3335 3171
3336 3172
3337 static ngx_int_t 3173 ngx_int_t
3338 ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
3339 ngx_quic_frame_t *frame)
3340 {
3341 size_t window;
3342 uint64_t last;
3343 ngx_buf_t *b;
3344 ngx_pool_t *pool;
3345 ngx_connection_t *sc;
3346 ngx_quic_stream_t *sn;
3347 ngx_quic_connection_t *qc;
3348 ngx_quic_stream_frame_t *f;
3349 ngx_quic_frames_stream_t *fs;
3350
3351 qc = ngx_quic_get_connection(c);
3352 f = &frame->u.stream;
3353
3354 if ((f->stream_id & NGX_QUIC_STREAM_UNIDIRECTIONAL)
3355 && (f->stream_id & NGX_QUIC_STREAM_SERVER_INITIATED))
3356 {
3357 qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
3358 return NGX_ERROR;
3359 }
3360
3361 /* no overflow since both values are 62-bit */
3362 last = f->offset + f->length;
3363
3364 sn = ngx_quic_find_stream(&qc->streams.tree, f->stream_id);
3365
3366 if (sn == NULL) {
3367 sn = ngx_quic_create_client_stream(c, f->stream_id);
3368
3369 if (sn == NULL) {
3370 return NGX_ERROR;
3371 }
3372
3373 if (sn == NGX_QUIC_STREAM_GONE) {
3374 return NGX_OK;
3375 }
3376
3377 sc = sn->c;
3378 fs = &sn->fs;
3379 b = sn->b;
3380 window = b->end - b->last;
3381
3382 if (last > window) {
3383 qc->error = NGX_QUIC_ERR_FLOW_CONTROL_ERROR;
3384 goto cleanup;
3385 }
3386
3387 if (ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_stream_input,
3388 sn)
3389 != NGX_OK)
3390 {
3391 goto cleanup;
3392 }
3393
3394 sc->listening->handler(sc);
3395
3396 return NGX_OK;
3397 }
3398
3399 fs = &sn->fs;
3400 b = sn->b;
3401 window = (b->pos - b->start) + (b->end - b->last);
3402
3403 if (last > fs->received && last - fs->received > window) {
3404 qc->error = NGX_QUIC_ERR_FLOW_CONTROL_ERROR;
3405 return NGX_ERROR;
3406 }
3407
3408 return ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_stream_input,
3409 sn);
3410
3411 cleanup:
3412
3413 pool = sc->pool;
3414
3415 ngx_close_connection(sc);
3416 ngx_destroy_pool(pool);
3417
3418 return NGX_ERROR;
3419 }
3420
3421
3422 static ngx_int_t
3423 ngx_quic_stream_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data)
3424 {
3425 uint64_t id;
3426 ngx_buf_t *b;
3427 ngx_event_t *rev;
3428 ngx_chain_t *cl;
3429 ngx_quic_stream_t *sn;
3430 ngx_quic_connection_t *qc;
3431 ngx_quic_stream_frame_t *f;
3432
3433 qc = ngx_quic_get_connection(c);
3434 sn = data;
3435
3436 f = &frame->u.stream;
3437 id = f->stream_id;
3438
3439 b = sn->b;
3440
3441 if ((size_t) ((b->pos - b->start) + (b->end - b->last)) < f->length) {
3442 ngx_log_error(NGX_LOG_INFO, c->log, 0,
3443 "quic no space in stream buffer");
3444 return NGX_ERROR;
3445 }
3446
3447 if ((size_t) (b->end - b->last) < f->length) {
3448 b->last = ngx_movemem(b->start, b->pos, b->last - b->pos);
3449 b->pos = b->start;
3450 }
3451
3452 for (cl = frame->data; cl; cl = cl->next) {
3453 b->last = ngx_cpymem(b->last, cl->buf->pos,
3454 cl->buf->last - cl->buf->pos);
3455 }
3456
3457 rev = sn->c->read;
3458 rev->ready = 1;
3459
3460 if (f->fin) {
3461 rev->pending_eof = 1;
3462 }
3463
3464 if (rev->active) {
3465 rev->handler(rev);
3466 }
3467
3468 /* check if stream was destroyed by handler */
3469 if (ngx_quic_find_stream(&qc->streams.tree, id) == NULL) {
3470 return NGX_DONE;
3471 }
3472
3473 return NGX_OK;
3474 }
3475
3476
3477 static ngx_int_t
3478 ngx_quic_handle_max_data_frame(ngx_connection_t *c,
3479 ngx_quic_max_data_frame_t *f)
3480 {
3481 ngx_event_t *wev;
3482 ngx_rbtree_t *tree;
3483 ngx_rbtree_node_t *node;
3484 ngx_quic_stream_t *qs;
3485 ngx_quic_connection_t *qc;
3486
3487 qc = ngx_quic_get_connection(c);
3488 tree = &qc->streams.tree;
3489
3490 if (f->max_data <= qc->streams.send_max_data) {
3491 return NGX_OK;
3492 }
3493
3494 if (qc->streams.sent >= qc->streams.send_max_data) {
3495
3496 for (node = ngx_rbtree_min(tree->root, tree->sentinel);
3497 node;
3498 node = ngx_rbtree_next(tree, node))
3499 {
3500 qs = (ngx_quic_stream_t *) node;
3501 wev = qs->c->write;
3502
3503 if (wev->active) {
3504 wev->ready = 1;
3505 ngx_post_event(wev, &ngx_posted_events);
3506 }
3507 }
3508 }
3509
3510 qc->streams.send_max_data = f->max_data;
3511
3512 return NGX_OK;
3513 }
3514
3515
3516 static ngx_int_t
3517 ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c,
3518 ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f)
3519 {
3520 return NGX_OK;
3521 }
3522
3523
3524 static ngx_int_t
3525 ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c,
3526 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f)
3527 {
3528 size_t n;
3529 ngx_buf_t *b;
3530 ngx_quic_frame_t *frame;
3531 ngx_quic_stream_t *sn;
3532 ngx_quic_connection_t *qc;
3533
3534 qc = ngx_quic_get_connection(c);
3535
3536 if ((f->id & NGX_QUIC_STREAM_UNIDIRECTIONAL)
3537 && (f->id & NGX_QUIC_STREAM_SERVER_INITIATED))
3538 {
3539 qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
3540 return NGX_ERROR;
3541 }
3542
3543 sn = ngx_quic_find_stream(&qc->streams.tree, f->id);
3544
3545 if (sn == NULL) {
3546 sn = ngx_quic_create_client_stream(c, f->id);
3547
3548 if (sn == NULL) {
3549 return NGX_ERROR;
3550 }
3551
3552 if (sn == NGX_QUIC_STREAM_GONE) {
3553 return NGX_OK;
3554 }
3555
3556 b = sn->b;
3557 n = b->end - b->last;
3558
3559 sn->c->listening->handler(sn->c);
3560
3561 } else {
3562 b = sn->b;
3563 n = sn->fs.received + (b->pos - b->start) + (b->end - b->last);
3564 }
3565
3566 frame = ngx_quic_alloc_frame(c);
3567 if (frame == NULL) {
3568 return NGX_ERROR;
3569 }
3570
3571 frame->level = pkt->level;
3572 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA;
3573 frame->u.max_stream_data.id = f->id;
3574 frame->u.max_stream_data.limit = n;
3575
3576 ngx_quic_queue_frame(qc, frame);
3577
3578 return NGX_OK;
3579 }
3580
3581
3582 static ngx_int_t
3583 ngx_quic_handle_max_stream_data_frame(ngx_connection_t *c,
3584 ngx_quic_header_t *pkt, ngx_quic_max_stream_data_frame_t *f)
3585 {
3586 uint64_t sent;
3587 ngx_event_t *wev;
3588 ngx_quic_stream_t *sn;
3589 ngx_quic_connection_t *qc;
3590
3591 qc = ngx_quic_get_connection(c);
3592
3593 if ((f->id & NGX_QUIC_STREAM_UNIDIRECTIONAL)
3594 && (f->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0)
3595 {
3596 qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
3597 return NGX_ERROR;
3598 }
3599
3600 sn = ngx_quic_find_stream(&qc->streams.tree, f->id);
3601
3602 if (sn == NULL) {
3603 sn = ngx_quic_create_client_stream(c, f->id);
3604
3605 if (sn == NULL) {
3606 return NGX_ERROR;
3607 }
3608
3609 if (sn == NGX_QUIC_STREAM_GONE) {
3610 return NGX_OK;
3611 }
3612
3613 if (f->limit > sn->send_max_data) {
3614 sn->send_max_data = f->limit;
3615 }
3616
3617 sn->c->listening->handler(sn->c);
3618
3619 return NGX_OK;
3620 }
3621
3622 if (f->limit <= sn->send_max_data) {
3623 return NGX_OK;
3624 }
3625
3626 sent = sn->c->sent;
3627
3628 if (sent >= sn->send_max_data) {
3629 wev = sn->c->write;
3630
3631 if (wev->active) {
3632 wev->ready = 1;
3633 ngx_post_event(wev, &ngx_posted_events);
3634 }
3635 }
3636
3637 sn->send_max_data = f->limit;
3638
3639 return NGX_OK;
3640 }
3641
3642
3643 static ngx_int_t
3644 ngx_quic_handle_reset_stream_frame(ngx_connection_t *c,
3645 ngx_quic_header_t *pkt, ngx_quic_reset_stream_frame_t *f)
3646 {
3647 ngx_event_t *rev;
3648 ngx_connection_t *sc;
3649 ngx_quic_stream_t *sn;
3650 ngx_quic_connection_t *qc;
3651
3652 qc = ngx_quic_get_connection(c);
3653
3654 if ((f->id & NGX_QUIC_STREAM_UNIDIRECTIONAL)
3655 && (f->id & NGX_QUIC_STREAM_SERVER_INITIATED))
3656 {
3657 qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
3658 return NGX_ERROR;
3659 }
3660
3661 sn = ngx_quic_find_stream(&qc->streams.tree, f->id);
3662
3663 if (sn == NULL) {
3664 sn = ngx_quic_create_client_stream(c, f->id);
3665
3666 if (sn == NULL) {
3667 return NGX_ERROR;
3668 }
3669
3670 if (sn == NGX_QUIC_STREAM_GONE) {
3671 return NGX_OK;
3672 }
3673
3674 sc = sn->c;
3675
3676 rev = sc->read;
3677 rev->error = 1;
3678 rev->ready = 1;
3679
3680 sc->listening->handler(sc);
3681
3682 return NGX_OK;
3683 }
3684
3685 rev = sn->c->read;
3686 rev->error = 1;
3687 rev->ready = 1;
3688
3689 if (rev->active) {
3690 rev->handler(rev);
3691 }
3692
3693 return NGX_OK;
3694 }
3695
3696
3697 static ngx_int_t
3698 ngx_quic_handle_stop_sending_frame(ngx_connection_t *c,
3699 ngx_quic_header_t *pkt, ngx_quic_stop_sending_frame_t *f)
3700 {
3701 ngx_event_t *wev;
3702 ngx_connection_t *sc;
3703 ngx_quic_stream_t *sn;
3704 ngx_quic_connection_t *qc;
3705
3706 qc = ngx_quic_get_connection(c);
3707
3708 if ((f->id & NGX_QUIC_STREAM_UNIDIRECTIONAL)
3709 && (f->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0)
3710 {
3711 qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
3712 return NGX_ERROR;
3713 }
3714
3715 sn = ngx_quic_find_stream(&qc->streams.tree, f->id);
3716
3717 if (sn == NULL) {
3718 sn = ngx_quic_create_client_stream(c, f->id);
3719
3720 if (sn == NULL) {
3721 return NGX_ERROR;
3722 }
3723
3724 if (sn == NGX_QUIC_STREAM_GONE) {
3725 return NGX_OK;
3726 }
3727
3728 sc = sn->c;
3729
3730 wev = sc->write;
3731 wev->error = 1;
3732 wev->ready = 1;
3733
3734 sc->listening->handler(sc);
3735
3736 return NGX_OK;
3737 }
3738
3739 wev = sn->c->write;
3740 wev->error = 1;
3741 wev->ready = 1;
3742
3743 if (wev->active) {
3744 wev->handler(wev);
3745 }
3746
3747 return NGX_OK;
3748 }
3749
3750
3751 static ngx_int_t
3752 ngx_quic_handle_max_streams_frame(ngx_connection_t *c,
3753 ngx_quic_header_t *pkt, ngx_quic_max_streams_frame_t *f)
3754 {
3755 ngx_quic_connection_t *qc;
3756
3757 qc = ngx_quic_get_connection(c);
3758
3759 if (f->bidi) {
3760 if (qc->streams.server_max_streams_bidi < f->limit) {
3761 qc->streams.server_max_streams_bidi = f->limit;
3762
3763 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
3764 "quic max_streams_bidi:%uL", f->limit);
3765 }
3766
3767 } else {
3768 if (qc->streams.server_max_streams_uni < f->limit) {
3769 qc->streams.server_max_streams_uni = f->limit;
3770
3771 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
3772 "quic max_streams_uni:%uL", f->limit);
3773 }
3774 }
3775
3776 return NGX_OK;
3777 }
3778
3779
3780 static ngx_int_t
3781 ngx_quic_output(ngx_connection_t *c) 3174 ngx_quic_output(ngx_connection_t *c)
3782 { 3175 {
3783 off_t max; 3176 off_t max;
3784 size_t len, min, in_flight; 3177 size_t len, min, in_flight;
3785 ssize_t n; 3178 ssize_t n;
4553 3946
4554 ngx_post_event(&qc->push, &ngx_posted_events); 3947 ngx_post_event(&qc->push, &ngx_posted_events);
4555 } 3948 }
4556 3949
4557 3950
4558 ngx_connection_t * 3951 void
4559 ngx_quic_open_stream(ngx_connection_t *c, ngx_uint_t bidi)
4560 {
4561 size_t rcvbuf_size;
4562 uint64_t id;
4563 ngx_quic_stream_t *qs, *sn;
4564 ngx_quic_connection_t *qc;
4565
4566 qs = c->quic;
4567 qc = ngx_quic_get_connection(qs->parent);
4568
4569 if (bidi) {
4570 if (qc->streams.server_streams_bidi
4571 >= qc->streams.server_max_streams_bidi)
4572 {
4573 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
4574 "quic too many server bidi streams:%uL",
4575 qc->streams.server_streams_bidi);
4576 return NULL;
4577 }
4578
4579 id = (qc->streams.server_streams_bidi << 2)
4580 | NGX_QUIC_STREAM_SERVER_INITIATED;
4581
4582 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
4583 "quic creating server bidi stream"
4584 " streams:%uL max:%uL id:0x%xL",
4585 qc->streams.server_streams_bidi,
4586 qc->streams.server_max_streams_bidi, id);
4587
4588 qc->streams.server_streams_bidi++;
4589 rcvbuf_size = qc->tp.initial_max_stream_data_bidi_local;
4590
4591 } else {
4592 if (qc->streams.server_streams_uni
4593 >= qc->streams.server_max_streams_uni)
4594 {
4595 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
4596 "quic too many server uni streams:%uL",
4597 qc->streams.server_streams_uni);
4598 return NULL;
4599 }
4600
4601 id = (qc->streams.server_streams_uni << 2)
4602 | NGX_QUIC_STREAM_SERVER_INITIATED
4603 | NGX_QUIC_STREAM_UNIDIRECTIONAL;
4604
4605 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
4606 "quic creating server uni stream"
4607 " streams:%uL max:%uL id:0x%xL",
4608 qc->streams.server_streams_uni,
4609 qc->streams.server_max_streams_uni, id);
4610
4611 qc->streams.server_streams_uni++;
4612 rcvbuf_size = 0;
4613 }
4614
4615 sn = ngx_quic_create_stream(qs->parent, id, rcvbuf_size);
4616 if (sn == NULL) {
4617 return NULL;
4618 }
4619
4620 return sn->c;
4621 }
4622
4623
4624 static void
4625 ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp,
4626 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
4627 {
4628 ngx_rbtree_node_t **p;
4629 ngx_quic_stream_t *qn, *qnt;
4630
4631 for ( ;; ) {
4632 qn = (ngx_quic_stream_t *) node;
4633 qnt = (ngx_quic_stream_t *) temp;
4634
4635 p = (qn->id < qnt->id) ? &temp->left : &temp->right;
4636
4637 if (*p == sentinel) {
4638 break;
4639 }
4640
4641 temp = *p;
4642 }
4643
4644 *p = node;
4645 node->parent = temp;
4646 node->left = sentinel;
4647 node->right = sentinel;
4648 ngx_rbt_red(node);
4649 }
4650
4651
4652 static ngx_quic_stream_t *
4653 ngx_quic_find_stream(ngx_rbtree_t *rbtree, uint64_t id)
4654 {
4655 ngx_rbtree_node_t *node, *sentinel;
4656 ngx_quic_stream_t *qn;
4657
4658 node = rbtree->root;
4659 sentinel = rbtree->sentinel;
4660
4661 while (node != sentinel) {
4662 qn = (ngx_quic_stream_t *) node;
4663
4664 if (id == qn->id) {
4665 return qn;
4666 }
4667
4668 node = (id < qn->id) ? node->left : node->right;
4669 }
4670
4671 return NULL;
4672 }
4673
4674
4675 static ngx_quic_stream_t *
4676 ngx_quic_create_client_stream(ngx_connection_t *c, uint64_t id)
4677 {
4678 size_t n;
4679 uint64_t min_id;
4680 ngx_quic_stream_t *sn;
4681 ngx_quic_connection_t *qc;
4682
4683 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
4684 "quic stream id:0x%xL is new", id);
4685
4686 qc = ngx_quic_get_connection(c);
4687
4688 if (qc->shutdown) {
4689 return NGX_QUIC_STREAM_GONE;
4690 }
4691
4692 if (id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
4693
4694 if (id & NGX_QUIC_STREAM_SERVER_INITIATED) {
4695 if ((id >> 2) < qc->streams.server_streams_uni) {
4696 return NGX_QUIC_STREAM_GONE;
4697 }
4698
4699 qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
4700 return NULL;
4701 }
4702
4703 if ((id >> 2) < qc->streams.client_streams_uni) {
4704 return NGX_QUIC_STREAM_GONE;
4705 }
4706
4707 if ((id >> 2) >= qc->streams.client_max_streams_uni) {
4708 qc->error = NGX_QUIC_ERR_STREAM_LIMIT_ERROR;
4709 return NULL;
4710 }
4711
4712 min_id = (qc->streams.client_streams_uni << 2)
4713 | NGX_QUIC_STREAM_UNIDIRECTIONAL;
4714 qc->streams.client_streams_uni = (id >> 2) + 1;
4715 n = qc->tp.initial_max_stream_data_uni;
4716
4717 } else {
4718
4719 if (id & NGX_QUIC_STREAM_SERVER_INITIATED) {
4720 if ((id >> 2) < qc->streams.server_streams_bidi) {
4721 return NGX_QUIC_STREAM_GONE;
4722 }
4723
4724 qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
4725 return NULL;
4726 }
4727
4728 if ((id >> 2) < qc->streams.client_streams_bidi) {
4729 return NGX_QUIC_STREAM_GONE;
4730 }
4731
4732 if ((id >> 2) >= qc->streams.client_max_streams_bidi) {
4733 qc->error = NGX_QUIC_ERR_STREAM_LIMIT_ERROR;
4734 return NULL;
4735 }
4736
4737 min_id = (qc->streams.client_streams_bidi << 2);
4738 qc->streams.client_streams_bidi = (id >> 2) + 1;
4739 n = qc->tp.initial_max_stream_data_bidi_remote;
4740 }
4741
4742 if (n < NGX_QUIC_STREAM_BUFSIZE) {
4743 n = NGX_QUIC_STREAM_BUFSIZE;
4744 }
4745
4746 /*
4747 * 2.1. Stream Types and Identifiers
4748 *
4749 * Within each type, streams are created with numerically increasing
4750 * stream IDs. A stream ID that is used out of order results in all
4751 * streams of that type with lower-numbered stream IDs also being
4752 * opened.
4753 */
4754
4755 for ( /* void */ ; min_id < id; min_id += 0x04) {
4756
4757 sn = ngx_quic_create_stream(c, min_id, n);
4758 if (sn == NULL) {
4759 return NULL;
4760 }
4761
4762 sn->c->listening->handler(sn->c);
4763
4764 if (qc->shutdown) {
4765 return NGX_QUIC_STREAM_GONE;
4766 }
4767 }
4768
4769 return ngx_quic_create_stream(c, id, n);
4770 }
4771
4772
4773 static ngx_quic_stream_t *
4774 ngx_quic_create_stream(ngx_connection_t *c, uint64_t id, size_t rcvbuf_size)
4775 {
4776 ngx_log_t *log;
4777 ngx_pool_t *pool;
4778 ngx_quic_stream_t *sn;
4779 ngx_pool_cleanup_t *cln;
4780 ngx_quic_connection_t *qc;
4781
4782 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
4783 "quic stream id:0x%xL create", id);
4784
4785 qc = ngx_quic_get_connection(c);
4786
4787 pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, c->log);
4788 if (pool == NULL) {
4789 return NULL;
4790 }
4791
4792 sn = ngx_pcalloc(pool, sizeof(ngx_quic_stream_t));
4793 if (sn == NULL) {
4794 ngx_destroy_pool(pool);
4795 return NULL;
4796 }
4797
4798 sn->node.key = id;
4799 sn->parent = c;
4800 sn->id = id;
4801
4802 sn->b = ngx_create_temp_buf(pool, rcvbuf_size);
4803 if (sn->b == NULL) {
4804 ngx_destroy_pool(pool);
4805 return NULL;
4806 }
4807
4808 ngx_queue_init(&sn->fs.frames);
4809
4810 log = ngx_palloc(pool, sizeof(ngx_log_t));
4811 if (log == NULL) {
4812 ngx_destroy_pool(pool);
4813 return NULL;
4814 }
4815
4816 *log = *c->log;
4817 pool->log = log;
4818
4819 sn->c = ngx_get_connection(-1, log);
4820 if (sn->c == NULL) {
4821 ngx_destroy_pool(pool);
4822 return NULL;
4823 }
4824
4825 sn->c->quic = sn;
4826 sn->c->type = SOCK_STREAM;
4827 sn->c->pool = pool;
4828 sn->c->ssl = c->ssl;
4829 sn->c->sockaddr = c->sockaddr;
4830 sn->c->listening = c->listening;
4831 sn->c->addr_text = c->addr_text;
4832 sn->c->local_sockaddr = c->local_sockaddr;
4833 sn->c->local_socklen = c->local_socklen;
4834 sn->c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
4835
4836 sn->c->recv = ngx_quic_stream_recv;
4837 sn->c->send = ngx_quic_stream_send;
4838 sn->c->send_chain = ngx_quic_stream_send_chain;
4839
4840 sn->c->read->log = log;
4841 sn->c->write->log = log;
4842
4843 log->connection = sn->c->number;
4844
4845 if ((id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0
4846 || (id & NGX_QUIC_STREAM_SERVER_INITIATED))
4847 {
4848 sn->c->write->ready = 1;
4849 }
4850
4851 if (id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
4852 if (id & NGX_QUIC_STREAM_SERVER_INITIATED) {
4853 sn->send_max_data = qc->ctp.initial_max_stream_data_uni;
4854 }
4855
4856 } else {
4857 if (id & NGX_QUIC_STREAM_SERVER_INITIATED) {
4858 sn->send_max_data = qc->ctp.initial_max_stream_data_bidi_remote;
4859 } else {
4860 sn->send_max_data = qc->ctp.initial_max_stream_data_bidi_local;
4861 }
4862 }
4863
4864 cln = ngx_pool_cleanup_add(pool, 0);
4865 if (cln == NULL) {
4866 ngx_close_connection(sn->c);
4867 ngx_destroy_pool(pool);
4868 return NULL;
4869 }
4870
4871 cln->handler = ngx_quic_stream_cleanup_handler;
4872 cln->data = sn->c;
4873
4874 ngx_rbtree_insert(&qc->streams.tree, &sn->node);
4875
4876 return sn;
4877 }
4878
4879
4880 static ssize_t
4881 ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, size_t size)
4882 {
4883 ssize_t len;
4884 ngx_buf_t *b;
4885 ngx_event_t *rev;
4886 ngx_connection_t *pc;
4887 ngx_quic_frame_t *frame;
4888 ngx_quic_stream_t *qs;
4889 ngx_quic_connection_t *qc;
4890
4891 qs = c->quic;
4892 b = qs->b;
4893 pc = qs->parent;
4894 qc = ngx_quic_get_connection(pc);
4895 rev = c->read;
4896
4897 if (rev->error) {
4898 return NGX_ERROR;
4899 }
4900
4901 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
4902 "quic stream recv id:0x%xL eof:%d avail:%z",
4903 qs->id, rev->pending_eof, b->last - b->pos);
4904
4905 if (b->pos == b->last) {
4906 rev->ready = 0;
4907
4908 if (rev->pending_eof) {
4909 rev->eof = 1;
4910 return 0;
4911 }
4912
4913 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
4914 "quic stream id:0x%xL recv() not ready", qs->id);
4915 return NGX_AGAIN;
4916 }
4917
4918 len = ngx_min(b->last - b->pos, (ssize_t) size);
4919
4920 ngx_memcpy(buf, b->pos, len);
4921
4922 b->pos += len;
4923 qc->streams.received += len;
4924
4925 if (b->pos == b->last) {
4926 b->pos = b->start;
4927 b->last = b->start;
4928 rev->ready = rev->pending_eof;
4929 }
4930
4931 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
4932 "quic stream id:0x%xL recv len:%z of size:%uz",
4933 qs->id, len, size);
4934
4935 if (!rev->pending_eof) {
4936 frame = ngx_quic_alloc_frame(pc);
4937 if (frame == NULL) {
4938 return NGX_ERROR;
4939 }
4940
4941 frame->level = ssl_encryption_application;
4942 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA;
4943 frame->u.max_stream_data.id = qs->id;
4944 frame->u.max_stream_data.limit = qs->fs.received + (b->pos - b->start)
4945 + (b->end - b->last);
4946
4947 ngx_quic_queue_frame(qc, frame);
4948 }
4949
4950 if ((qc->streams.recv_max_data / 2) < qc->streams.received) {
4951
4952 frame = ngx_quic_alloc_frame(pc);
4953
4954 if (frame == NULL) {
4955 return NGX_ERROR;
4956 }
4957
4958 qc->streams.recv_max_data *= 2;
4959
4960 frame->level = ssl_encryption_application;
4961 frame->type = NGX_QUIC_FT_MAX_DATA;
4962 frame->u.max_data.max_data = qc->streams.recv_max_data;
4963
4964 ngx_quic_queue_frame(qc, frame);
4965
4966 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
4967 "quic stream id:0x%xL recv: increased max_data:%uL",
4968 qs->id, qc->streams.recv_max_data);
4969 }
4970
4971 return len;
4972 }
4973
4974
4975 static ssize_t
4976 ngx_quic_stream_send(ngx_connection_t *c, u_char *buf, size_t size)
4977 {
4978 ngx_buf_t b;
4979 ngx_chain_t cl;
4980
4981 ngx_memzero(&b, sizeof(ngx_buf_t));
4982
4983 b.memory = 1;
4984 b.pos = buf;
4985 b.last = buf + size;
4986
4987 cl.buf = &b;
4988 cl.next = NULL;
4989
4990 if (ngx_quic_stream_send_chain(c, &cl, 0) == NGX_CHAIN_ERROR) {
4991 return NGX_ERROR;
4992 }
4993
4994 if (b.pos == buf) {
4995 return NGX_AGAIN;
4996 }
4997
4998 return b.pos - buf;
4999 }
5000
5001
5002 static ngx_chain_t *
5003 ngx_quic_stream_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
5004 {
5005 size_t n, flow;
5006 ngx_event_t *wev;
5007 ngx_chain_t *cl;
5008 ngx_connection_t *pc;
5009 ngx_quic_frame_t *frame;
5010 ngx_quic_stream_t *qs;
5011 ngx_quic_connection_t *qc;
5012
5013 qs = c->quic;
5014 pc = qs->parent;
5015 qc = ngx_quic_get_connection(pc);
5016 wev = c->write;
5017
5018 if (wev->error) {
5019 return NGX_CHAIN_ERROR;
5020 }
5021
5022 flow = ngx_quic_max_stream_flow(c);
5023 if (flow == 0) {
5024 wev->ready = 0;
5025 return in;
5026 }
5027
5028 n = (limit && (size_t) limit < flow) ? (size_t) limit : flow;
5029
5030 frame = ngx_quic_alloc_frame(pc);
5031 if (frame == NULL) {
5032 return NGX_CHAIN_ERROR;
5033 }
5034
5035 frame->data = ngx_quic_copy_chain(pc, in, n);
5036 if (frame->data == NGX_CHAIN_ERROR) {
5037 return NGX_CHAIN_ERROR;
5038 }
5039
5040 for (n = 0, cl = frame->data; cl; cl = cl->next) {
5041 n += ngx_buf_size(cl->buf);
5042 }
5043
5044 while (in && ngx_buf_size(in->buf) == 0) {
5045 in = in->next;
5046 }
5047
5048 frame->level = ssl_encryption_application;
5049 frame->type = NGX_QUIC_FT_STREAM6; /* OFF=1 LEN=1 FIN=0 */
5050 frame->u.stream.off = 1;
5051 frame->u.stream.len = 1;
5052 frame->u.stream.fin = 0;
5053
5054 frame->u.stream.type = frame->type;
5055 frame->u.stream.stream_id = qs->id;
5056 frame->u.stream.offset = c->sent;
5057 frame->u.stream.length = n;
5058
5059 c->sent += n;
5060 qc->streams.sent += n;
5061
5062 ngx_quic_queue_frame(qc, frame);
5063
5064 wev->ready = (n < flow) ? 1 : 0;
5065
5066 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
5067 "quic send_chain sent:%uz", n);
5068
5069 return in;
5070 }
5071
5072
5073 static size_t
5074 ngx_quic_max_stream_flow(ngx_connection_t *c)
5075 {
5076 size_t size;
5077 uint64_t sent, unacked;
5078 ngx_quic_stream_t *qs;
5079 ngx_quic_connection_t *qc;
5080
5081 qs = c->quic;
5082 qc = ngx_quic_get_connection(qs->parent);
5083
5084 size = NGX_QUIC_STREAM_BUFSIZE;
5085 sent = c->sent;
5086 unacked = sent - qs->acked;
5087
5088 if (qc->streams.send_max_data == 0) {
5089 qc->streams.send_max_data = qc->ctp.initial_max_data;
5090 }
5091
5092 if (unacked >= NGX_QUIC_STREAM_BUFSIZE) {
5093 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
5094 "quic send flow hit buffer size");
5095 return 0;
5096 }
5097
5098 if (unacked + size > NGX_QUIC_STREAM_BUFSIZE) {
5099 size = NGX_QUIC_STREAM_BUFSIZE - unacked;
5100 }
5101
5102 if (qc->streams.sent >= qc->streams.send_max_data) {
5103 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
5104 "quic send flow hit MAX_DATA");
5105 return 0;
5106 }
5107
5108 if (qc->streams.sent + size > qc->streams.send_max_data) {
5109 size = qc->streams.send_max_data - qc->streams.sent;
5110 }
5111
5112 if (sent >= qs->send_max_data) {
5113 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
5114 "quic send flow hit MAX_STREAM_DATA");
5115 return 0;
5116 }
5117
5118 if (sent + size > qs->send_max_data) {
5119 size = qs->send_max_data - sent;
5120 }
5121
5122 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
5123 "quic send flow:%uz", size);
5124
5125 return size;
5126 }
5127
5128
5129 static void
5130 ngx_quic_stream_cleanup_handler(void *data)
5131 {
5132 ngx_connection_t *c = data;
5133
5134 ngx_connection_t *pc;
5135 ngx_quic_frame_t *frame;
5136 ngx_quic_stream_t *qs;
5137 ngx_quic_connection_t *qc;
5138
5139 qs = c->quic;
5140 pc = qs->parent;
5141 qc = ngx_quic_get_connection(pc);
5142
5143 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
5144 "quic stream id:0x%xL cleanup", qs->id);
5145
5146 ngx_rbtree_delete(&qc->streams.tree, &qs->node);
5147 ngx_quic_free_frames(pc, &qs->fs.frames);
5148
5149 if (qc->closing) {
5150 /* schedule handler call to continue ngx_quic_close_connection() */
5151 ngx_post_event(pc->read, &ngx_posted_events);
5152 return;
5153 }
5154
5155 if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0
5156 || (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0)
5157 {
5158 if (!c->read->pending_eof && !c->read->error) {
5159 frame = ngx_quic_alloc_frame(pc);
5160 if (frame == NULL) {
5161 goto done;
5162 }
5163
5164 frame->level = ssl_encryption_application;
5165 frame->type = NGX_QUIC_FT_STOP_SENDING;
5166 frame->u.stop_sending.id = qs->id;
5167 frame->u.stop_sending.error_code = 0x100; /* HTTP/3 no error */
5168
5169 ngx_quic_queue_frame(qc, frame);
5170 }
5171 }
5172
5173 if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0) {
5174 frame = ngx_quic_alloc_frame(pc);
5175 if (frame == NULL) {
5176 goto done;
5177 }
5178
5179 frame->level = ssl_encryption_application;
5180 frame->type = NGX_QUIC_FT_MAX_STREAMS;
5181
5182 if (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
5183 frame->u.max_streams.limit = ++qc->streams.client_max_streams_uni;
5184 frame->u.max_streams.bidi = 0;
5185
5186 } else {
5187 frame->u.max_streams.limit = ++qc->streams.client_max_streams_bidi;
5188 frame->u.max_streams.bidi = 1;
5189 }
5190
5191 ngx_quic_queue_frame(qc, frame);
5192
5193 if (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
5194 /* do not send fin for client unidirectional streams */
5195 goto done;
5196 }
5197 }
5198
5199 if (c->write->error) {
5200 goto done;
5201 }
5202
5203 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
5204 "quic stream id:0x%xL send fin", qs->id);
5205
5206 frame = ngx_quic_alloc_frame(pc);
5207 if (frame == NULL) {
5208 goto done;
5209 }
5210
5211 frame->level = ssl_encryption_application;
5212 frame->type = NGX_QUIC_FT_STREAM7; /* OFF=1 LEN=1 FIN=1 */
5213 frame->u.stream.off = 1;
5214 frame->u.stream.len = 1;
5215 frame->u.stream.fin = 1;
5216
5217 frame->u.stream.type = frame->type;
5218 frame->u.stream.stream_id = qs->id;
5219 frame->u.stream.offset = c->sent;
5220 frame->u.stream.length = 0;
5221
5222 ngx_quic_queue_frame(qc, frame);
5223
5224 done:
5225
5226 (void) ngx_quic_output(pc);
5227
5228 if (qc->shutdown) {
5229 ngx_quic_shutdown_quic(pc);
5230 }
5231 }
5232
5233
5234 static void
5235 ngx_quic_shutdown_quic(ngx_connection_t *c) 3952 ngx_quic_shutdown_quic(ngx_connection_t *c)
5236 { 3953 {
5237 ngx_rbtree_t *tree; 3954 ngx_rbtree_t *tree;
5238 ngx_rbtree_node_t *node; 3955 ngx_rbtree_node_t *node;
5239 ngx_quic_stream_t *qs; 3956 ngx_quic_stream_t *qs;