comparison src/event/quic/ngx_event_quic.c @ 9051:37d5dddabaea quic

QUIC: reusable mode for main connection. The connection is automatically switched to this mode by transport layer when there are no non-cancelable streams. Currently, cancelable streams are HTTP/3 encoder/decoder/control streams.
author Roman Arutyunyan <arut@nginx.com>
date Tue, 29 Nov 2022 17:46:46 +0400
parents aaca8e111959
children 1192923be0aa
comparison
equal deleted inserted replaced
9050:aaca8e111959 9051:37d5dddabaea
339 339
340 if (ngx_quic_open_sockets(c, qc, pkt) != NGX_OK) { 340 if (ngx_quic_open_sockets(c, qc, pkt) != NGX_OK) {
341 return NULL; 341 return NULL;
342 } 342 }
343 343
344 ngx_reusable_connection(c, 1);
345
344 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, 346 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
345 "quic connection created"); 347 "quic connection created");
346 348
347 return qc; 349 return qc;
348 } 350 }
418 } 420 }
419 421
420 if (c->close) { 422 if (c->close) {
421 qc->error = NGX_QUIC_ERR_NO_ERROR; 423 qc->error = NGX_QUIC_ERR_NO_ERROR;
422 qc->error_reason = "graceful shutdown"; 424 qc->error_reason = "graceful shutdown";
423 ngx_quic_close_connection(c, NGX_OK); 425 ngx_quic_close_connection(c, NGX_ERROR);
424 return; 426 return;
425 } 427 }
426 428
427 b = c->udp->buffer; 429 b = c->udp->buffer;
428 if (b == NULL) { 430 if (b == NULL) {
601 const char *reason) 603 const char *reason)
602 { 604 {
603 ngx_quic_connection_t *qc; 605 ngx_quic_connection_t *qc;
604 606
605 qc = ngx_quic_get_connection(c); 607 qc = ngx_quic_get_connection(c);
608
609 if (qc->closing) {
610 return;
611 }
612
606 qc->error = err; 613 qc->error = err;
607 qc->error_reason = reason; 614 qc->error_reason = reason;
608 qc->error_app = 1; 615 qc->error_app = 1;
609 qc->error_ftype = 0; 616 qc->error_ftype = 0;
610 617
611 ngx_quic_close_connection(c, NGX_OK); 618 ngx_post_event(&qc->close, &ngx_posted_events);
612 } 619 }
613 620
614 621
615 void 622 void
616 ngx_quic_shutdown_connection(ngx_connection_t *c, ngx_uint_t err, 623 ngx_quic_shutdown_connection(ngx_connection_t *c, ngx_uint_t err,
628 635
629 636
630 static void 637 static void
631 ngx_quic_close_handler(ngx_event_t *ev) 638 ngx_quic_close_handler(ngx_event_t *ev)
632 { 639 {
633 ngx_connection_t *c; 640 ngx_connection_t *c;
634 ngx_quic_connection_t *qc;
635 641
636 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic close handler"); 642 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic close handler");
637 643
638 c = ev->data; 644 c = ev->data;
639 qc = ngx_quic_get_connection(c); 645
640 646 ngx_quic_close_connection(c, NGX_OK);
641 if (qc->closing) {
642 ngx_quic_close_connection(c, NGX_OK);
643
644 } else if (qc->shutdown) {
645 ngx_quic_shutdown_quic(c);
646 }
647 } 647 }
648 648
649 649
650 static ngx_int_t 650 static ngx_int_t
651 ngx_quic_handle_datagram(ngx_connection_t *c, ngx_buf_t *b, 651 ngx_quic_handle_datagram(ngx_connection_t *c, ngx_buf_t *b,
1426 1426
1427 1427
1428 void 1428 void
1429 ngx_quic_shutdown_quic(ngx_connection_t *c) 1429 ngx_quic_shutdown_quic(ngx_connection_t *c)
1430 { 1430 {
1431 ngx_rbtree_t *tree;
1432 ngx_rbtree_node_t *node;
1433 ngx_quic_stream_t *qs;
1434 ngx_quic_connection_t *qc; 1431 ngx_quic_connection_t *qc;
1435 1432
1436 qc = ngx_quic_get_connection(c); 1433 if (c->reusable) {
1437 1434 qc = ngx_quic_get_connection(c);
1438 if (qc->closing) { 1435 ngx_quic_finalize_connection(c, qc->shutdown_code, qc->shutdown_reason);
1439 return; 1436 }
1440 } 1437 }
1441
1442 tree = &qc->streams.tree;
1443
1444 if (tree->root != tree->sentinel) {
1445 for (node = ngx_rbtree_min(tree->root, tree->sentinel);
1446 node;
1447 node = ngx_rbtree_next(tree, node))
1448 {
1449 qs = (ngx_quic_stream_t *) node;
1450
1451 if (!qs->cancelable) {
1452 return;
1453 }
1454 }
1455 }
1456
1457 ngx_quic_finalize_connection(c, qc->shutdown_code, qc->shutdown_reason);
1458 }