git: 36c55cddabc8 - main - www/nginx-devel: update from 1.23.2 to 1.23.3

From: Sergey A. Osokin <osa_at_FreeBSD.org>
Date: Tue, 13 Dec 2022 17:26:53 UTC
The branch main has been updated by osa:

URL: https://cgit.FreeBSD.org/ports/commit/?id=36c55cddabc8eeaa8fbdbbc3f2ff9124cae3bce5

commit 36c55cddabc8eeaa8fbdbbc3f2ff9124cae3bce5
Author:     Sergey A. Osokin <osa@FreeBSD.org>
AuthorDate: 2022-12-13 17:25:41 +0000
Commit:     Sergey A. Osokin <osa@FreeBSD.org>
CommitDate: 2022-12-13 17:26:48 +0000

    www/nginx-devel: update from 1.23.2 to 1.23.3
    
    Update HTTPv3/QUIC patch.
    
    <Changelog>
    
    *) Bugfix: an error might occur when reading PROXY protocol version 2
       header with large number of TLVs.
    
    *) Bugfix: a segmentation fault might occur in a worker process if SSI
       was used to process subrequests created by other modules.
       Thanks to Ciel Zhao.
    
    *) Workaround: when a hostname used in the "listen" directive resolves
       to multiple addresses, nginx now ignores duplicates within these
       addresses.
    
    *) Bugfix: nginx might hog CPU during unbuffered proxying if SSL
       connections to backends were used.
    
    </Changelog>
---
 www/nginx-devel/Makefile                 |    3 +-
 www/nginx-devel/distinfo                 |    6 +-
 www/nginx-devel/files/extra-patch-httpv3 | 1050 ++++++++++++++++++------------
 3 files changed, 635 insertions(+), 424 deletions(-)

diff --git a/www/nginx-devel/Makefile b/www/nginx-devel/Makefile
index f8d9d8561b4b..b337240e9ea1 100644
--- a/www/nginx-devel/Makefile
+++ b/www/nginx-devel/Makefile
@@ -1,6 +1,5 @@
 PORTNAME?=	nginx
-PORTVERSION=	1.23.2
-PORTREVISION=	4
+PORTVERSION=	1.23.3
 CATEGORIES=	www
 MASTER_SITES=	https://nginx.org/download/ \
 		LOCAL/osa
diff --git a/www/nginx-devel/distinfo b/www/nginx-devel/distinfo
index fe040b23c3a0..bfb28c9b4831 100644
--- a/www/nginx-devel/distinfo
+++ b/www/nginx-devel/distinfo
@@ -1,6 +1,6 @@
-TIMESTAMP = 1669035006
-SHA256 (nginx-1.23.2.tar.gz) = a80cc272d3d72aaee70aa8b517b4862a635c0256790434dbfc4d618a999b0b46
-SIZE (nginx-1.23.2.tar.gz) = 1108243
+TIMESTAMP = 1670951542
+SHA256 (nginx-1.23.3.tar.gz) = 75cb5787dbb9fae18b14810f91cc4343f64ce4c24e27302136fb52498042ba54
+SIZE (nginx-1.23.3.tar.gz) = 1108958
 SHA256 (nginx_mogilefs_module-1.0.4.tar.gz) = 7ac230d30907f013dff8d435a118619ea6168aa3714dba62c6962d350c6295ae
 SIZE (nginx_mogilefs_module-1.0.4.tar.gz) = 11208
 SHA256 (nginx_mod_h264_streaming-2.2.7.tar.gz) = 6d974ba630cef59de1f60996c66b401264a345d25988a76037c2856cec756c19
diff --git a/www/nginx-devel/files/extra-patch-httpv3 b/www/nginx-devel/files/extra-patch-httpv3
index 3dce419120f9..bc3ae99cef43 100644
--- a/www/nginx-devel/files/extra-patch-httpv3
+++ b/www/nginx-devel/files/extra-patch-httpv3
@@ -1,7 +1,7 @@
 diff -r aa901551a7eb README
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/README	Thu Oct 20 13:21:28 2022 -0400
-@@ -0,0 +1,250 @@
++++ b/README	Tue Dec 13 12:15:22 2022 -0500
+@@ -0,0 +1,251 @@
 +Experimental QUIC support for nginx
 +-----------------------------------
 +
@@ -19,8 +19,8 @@ diff -r aa901551a7eb README
 +
 +    The code is developed in a separate "quic" branch available
 +    at https://hg.nginx.org/nginx-quic.  Currently it is based
-+    on nginx mainline 1.23.x.  We merge new nginx releases into
-+    this branch regularly.
++    on nginx mainline 1.23.x.  NGINX Development team merges new
++    nginx releases into this branch regularly.
 +
 +    The project code base is under the same BSD license as nginx.
 +
@@ -131,7 +131,7 @@ diff -r aa901551a7eb README
 +        quic_host_key <filename>;
 +
 +
-+    By default, GSO Linux-specific optimization [10] is disabled.
++    By default, GSO Linux-specific optimization [11] is disabled.
 +    Enable it in case a corresponding network interface is configured to
 +    support GSO.
 +
@@ -217,12 +217,12 @@ diff -r aa901551a7eb README
 +    + Ensure a client is actually sending requests over QUIC
 +      (see "Clients" section about browsers and cache)
 +
-+      We recommend to start with simple console client like ngtcp2
++      Please start with a simple console client such as ngtcp2 [9]
 +      to ensure the server is configured properly before trying
 +      with real browsers that may be very picky with certificates,
 +      for example.
 +
-+    + Build nginx with debug support [9] and check the debug log.
++    + Build nginx with debug support [10] and check the debug log.
 +      It should contain all details about connection and why it
 +      failed. All related messages contain "quic " prefix and can
 +      be easily filtered out.
@@ -250,11 +250,12 @@ diff -r aa901551a7eb README
 +    [6] https://github.com/quictls/openssl
 +    [7] https://github.com/libressl-portable/portable/releases/tag/v3.6.0
 +    [8] https://nginx.org/en/docs/http/ngx_http_core_module.html#listen
-+    [9] https://nginx.org/en/docs/debugging_log.html
-+    [10] http://vger.kernel.org/lpc_net2018_talks/willemdebruijn-lpc2018-udpgso-paper-DRAFT-1.pdf
++    [9] https://github.com/ngtcp2/ngtcp2
++    [10] https://nginx.org/en/docs/debugging_log.html
++    [11] http://vger.kernel.org/lpc_net2018_talks/willemdebruijn-lpc2018-udpgso-paper-DRAFT-1.pdf
 diff -r aa901551a7eb auto/lib/openssl/conf
 --- a/auto/lib/openssl/conf	Wed Oct 19 10:56:20 2022 +0300
-+++ b/auto/lib/openssl/conf	Thu Oct 20 13:21:28 2022 -0400
++++ b/auto/lib/openssl/conf	Tue Dec 13 12:15:22 2022 -0500
 @@ -5,12 +5,16 @@
  
  if [ $OPENSSL != NONE ]; then
@@ -316,7 +317,7 @@ diff -r aa901551a7eb auto/lib/openssl/conf
  fi
 diff -r aa901551a7eb auto/make
 --- a/auto/make	Wed Oct 19 10:56:20 2022 +0300
-+++ b/auto/make	Thu Oct 20 13:21:28 2022 -0400
++++ b/auto/make	Tue Dec 13 12:15:22 2022 -0500
 @@ -6,9 +6,10 @@
  echo "creating $NGX_MAKEFILE"
  
@@ -332,7 +333,7 @@ diff -r aa901551a7eb auto/make
           $NGX_OBJS/src/misc
 diff -r aa901551a7eb auto/modules
 --- a/auto/modules	Wed Oct 19 10:56:20 2022 +0300
-+++ b/auto/modules	Thu Oct 20 13:21:28 2022 -0400
++++ b/auto/modules	Tue Dec 13 12:15:22 2022 -0500
 @@ -102,7 +102,7 @@ if [ $HTTP = YES ]; then
      fi
  
@@ -495,7 +496,7 @@ diff -r aa901551a7eb auto/modules
      ngx_module_name=ngx_regex_module
 diff -r aa901551a7eb auto/options
 --- a/auto/options	Wed Oct 19 10:56:20 2022 +0300
-+++ b/auto/options	Thu Oct 20 13:21:28 2022 -0400
++++ b/auto/options	Tue Dec 13 12:15:22 2022 -0500
 @@ -45,6 +45,8 @@ USE_THREADS=NO
  
  NGX_FILE_AIO=NO
@@ -585,7 +586,7 @@ diff -r aa901551a7eb auto/options
    --with-stream_geoip_module=dynamic enable dynamic ngx_stream_geoip_module
 diff -r aa901551a7eb auto/os/linux
 --- a/auto/os/linux	Wed Oct 19 10:56:20 2022 +0300
-+++ b/auto/os/linux	Thu Oct 20 13:21:28 2022 -0400
++++ b/auto/os/linux	Tue Dec 13 12:15:22 2022 -0500
 @@ -232,6 +232,50 @@ ngx_feature_test="struct crypt_data  cd;
  ngx_include="sys/vfs.h";     . auto/include
  
@@ -639,7 +640,7 @@ diff -r aa901551a7eb auto/os/linux
  ngx_feature="UDP_SEGMENT"
 diff -r aa901551a7eb auto/sources
 --- a/auto/sources	Wed Oct 19 10:56:20 2022 +0300
-+++ b/auto/sources	Thu Oct 20 13:21:28 2022 -0400
++++ b/auto/sources	Tue Dec 13 12:15:22 2022 -0500
 @@ -83,7 +83,7 @@ CORE_SRCS="src/core/nginx.c \
  
  EVENT_MODULES="ngx_events_module ngx_event_core_module"
@@ -651,7 +652,7 @@ diff -r aa901551a7eb auto/sources
              src/event/ngx_event_timer.h \
 diff -r aa901551a7eb src/core/nginx.c
 --- a/src/core/nginx.c	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/core/nginx.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/core/nginx.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -680,6 +680,9 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, 
  
      ls = cycle->listening.elts;
@@ -664,7 +665,7 @@ diff -r aa901551a7eb src/core/nginx.c
  
 diff -r aa901551a7eb src/core/ngx_bpf.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/ngx_bpf.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/core/ngx_bpf.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,143 @@
 +
 +/*
@@ -811,7 +812,7 @@ diff -r aa901551a7eb src/core/ngx_bpf.c
 +}
 diff -r aa901551a7eb src/core/ngx_bpf.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/ngx_bpf.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/core/ngx_bpf.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,43 @@
 +
 +/*
@@ -858,7 +859,7 @@ diff -r aa901551a7eb src/core/ngx_bpf.h
 +#endif /* _NGX_BPF_H_INCLUDED_ */
 diff -r aa901551a7eb src/core/ngx_connection.c
 --- a/src/core/ngx_connection.c	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/core/ngx_connection.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/core/ngx_connection.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -72,10 +72,6 @@ ngx_create_listening(ngx_conf_t *cf, str
  
      ngx_memcpy(ls->addr_text.data, text, len);
@@ -885,7 +886,7 @@ diff -r aa901551a7eb src/core/ngx_connection.c
          if (c) {
 diff -r aa901551a7eb src/core/ngx_connection.h
 --- a/src/core/ngx_connection.h	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/core/ngx_connection.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/core/ngx_connection.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -73,6 +73,7 @@ struct ngx_listening_s {
      unsigned            reuseport:1;
      unsigned            add_reuseport:1;
@@ -907,7 +908,7 @@ diff -r aa901551a7eb src/core/ngx_connection.h
  #endif
 diff -r aa901551a7eb src/core/ngx_core.h
 --- a/src/core/ngx_core.h	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/core/ngx_core.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/core/ngx_core.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -27,6 +27,7 @@ typedef struct ngx_connection_s      ngx
  typedef struct ngx_thread_task_s     ngx_thread_task_t;
  typedef struct ngx_ssl_s             ngx_ssl_t;
@@ -938,7 +939,7 @@ diff -r aa901551a7eb src/core/ngx_core.h
  #define LF     (u_char) '\n'
 diff -r aa901551a7eb src/event/ngx_event.c
 --- a/src/event/ngx_event.c	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/event/ngx_event.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/ngx_event.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -267,6 +267,18 @@ ngx_process_events_and_timers(ngx_cycle_
  ngx_int_t
  ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
@@ -997,7 +998,7 @@ diff -r aa901551a7eb src/event/ngx_event.c
  
 diff -r aa901551a7eb src/event/ngx_event_openssl.c
 --- a/src/event/ngx_event_openssl.c	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/event/ngx_event_openssl.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/ngx_event_openssl.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -3197,6 +3197,13 @@ ngx_ssl_shutdown(ngx_connection_t *c)
      ngx_err_t   err;
      ngx_uint_t  tries;
@@ -1014,7 +1015,7 @@ diff -r aa901551a7eb src/event/ngx_event_openssl.c
      ngx_ssl_ocsp_cleanup(c);
 diff -r aa901551a7eb src/event/ngx_event_openssl.h
 --- a/src/event/ngx_event_openssl.h	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/event/ngx_event_openssl.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/ngx_event_openssl.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -24,6 +24,14 @@
  #include <openssl/engine.h>
  #endif
@@ -1032,7 +1033,7 @@ diff -r aa901551a7eb src/event/ngx_event_openssl.h
  #include <openssl/ocsp.h>
 diff -r aa901551a7eb src/event/ngx_event_udp.c
 --- a/src/event/ngx_event_udp.c	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/event/ngx_event_udp.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/ngx_event_udp.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -12,13 +12,6 @@
  
  #if !(NGX_WIN32)
@@ -1049,7 +1050,7 @@ diff -r aa901551a7eb src/event/ngx_event_udp.c
      size_t size);
 diff -r aa901551a7eb src/event/ngx_event_udp.h
 --- a/src/event/ngx_event_udp.h	Wed Oct 19 10:56:20 2022 +0300
-+++ b/src/event/ngx_event_udp.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/ngx_event_udp.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -23,6 +23,13 @@
  #endif
  
@@ -1066,7 +1067,7 @@ diff -r aa901551a7eb src/event/ngx_event_udp.h
  typedef union {
 diff -r aa901551a7eb src/event/quic/bpf/bpfgen.sh
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/bpf/bpfgen.sh	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/bpf/bpfgen.sh	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,113 @@
 +#!/bin/bash
 +
@@ -1183,7 +1184,7 @@ diff -r aa901551a7eb src/event/quic/bpf/bpfgen.sh
 +
 diff -r aa901551a7eb src/event/quic/bpf/makefile
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/bpf/makefile	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/bpf/makefile	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,30 @@
 +CFLAGS=-O2 -Wall
 +
@@ -1217,7 +1218,7 @@ diff -r aa901551a7eb src/event/quic/bpf/makefile
 +.DELETE_ON_ERROR:
 diff -r aa901551a7eb src/event/quic/bpf/ngx_quic_reuseport_helper.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/bpf/ngx_quic_reuseport_helper.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/bpf/ngx_quic_reuseport_helper.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,140 @@
 +#include <errno.h>
 +#include <linux/string.h>
@@ -1361,8 +1362,8 @@ diff -r aa901551a7eb src/event/quic/bpf/ngx_quic_reuseport_helper.c
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic.c	Thu Oct 20 13:21:28 2022 -0400
-@@ -0,0 +1,1459 @@
++++ b/src/event/quic/ngx_event_quic.c	Tue Dec 13 12:15:22 2022 -0500
+@@ -0,0 +1,1444 @@
 +
 +/*
 + * Copyright (C) Nginx, Inc.
@@ -1380,8 +1381,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +static ngx_int_t ngx_quic_handle_stateless_reset(ngx_connection_t *c,
 +    ngx_quic_header_t *pkt);
 +static void ngx_quic_input_handler(ngx_event_t *rev);
-+
-+static void ngx_quic_close_timer_handler(ngx_event_t *ev);
++static void ngx_quic_close_handler(ngx_event_t *ev);
 +
 +static ngx_int_t ngx_quic_handle_datagram(ngx_connection_t *c, ngx_buf_t *b,
 +    ngx_quic_conf_t *conf);
@@ -1438,7 +1438,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +
 +    if (qc) {
 +
-+        if (qc->error) {
++        if (qc->error != (ngx_uint_t) -1) {
 +            p = ngx_slprintf(p, last, "%s", qc->error_app ? " app" : "");
 +            p = ngx_slprintf(p, last, " error:%ui", qc->error);
 +
@@ -1641,17 +1641,18 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +    qc->pto.log = c->log;
 +    qc->pto.data = c;
 +    qc->pto.handler = ngx_quic_pto_handler;
-+    qc->pto.cancelable = 1;
 +
 +    qc->push.log = c->log;
 +    qc->push.data = c;
 +    qc->push.handler = ngx_quic_push_handler;
-+    qc->push.cancelable = 1;
++
++    qc->close.log = c->log;
++    qc->close.data = c;
++    qc->close.handler = ngx_quic_close_handler;
 +
 +    qc->path_validation.log = c->log;
 +    qc->path_validation.data = c;
 +    qc->path_validation.handler = ngx_quic_path_validation_handler;
-+    qc->path_validation.cancelable = 1;
 +
 +    qc->conf = conf;
 +
@@ -1702,6 +1703,9 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +        return NULL;
 +    }
 +
++    c->idle = 1;
++    ngx_reusable_connection(c, 1);
++
 +    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
 +                   "quic connection created");
 +
@@ -1779,23 +1783,26 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +    }
 +
 +    if (c->close) {
-+        qc->error_reason = "graceful shutdown";
-+        ngx_quic_close_connection(c, NGX_OK);
-+        return;
-+    }
++        c->close = 0;
 +
-+    if (!rev->ready) {
-+        if (qc->closing) {
-+            ngx_quic_close_connection(c, NGX_OK);
++        if (!ngx_exiting) {
++            qc->error = NGX_QUIC_ERR_NO_ERROR;
++            qc->error_reason = "graceful shutdown";
++            ngx_quic_close_connection(c, NGX_ERROR);
++            return;
++        }
 +
-+        } else if (qc->shutdown) {
-+            ngx_quic_shutdown_quic(c);
++        if (!qc->closing && qc->conf->shutdown) {
++            qc->conf->shutdown(c);
 +        }
 +
 +        return;
 +    }
 +
 +    b = c->udp->buffer;
++    if (b == NULL) {
++        return;
++    }
 +
 +    rc = ngx_quic_handle_datagram(c, b, NULL);
 +
@@ -1871,31 +1878,21 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +            qc->error_level = c->ssl ? SSL_quic_read_level(c->ssl->connection)
 +                                     : ssl_encryption_initial;
 +
-+            if (rc == NGX_OK) {
-+                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-+                               "quic close immediate drain:%d",
-+                               qc->draining);
++            if (qc->error == (ngx_uint_t) -1) {
++                qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
++                qc->error_app = 0;
++            }
 +
-+                qc->close.log = c->log;
-+                qc->close.data = c;
-+                qc->close.handler = ngx_quic_close_timer_handler;
-+                qc->close.cancelable = 1;
++            ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
++                           "quic close immediate term:%d drain:%d "
++                           "%serror:%ui \"%s\"",
++                           rc == NGX_ERROR ? 1 : 0, qc->draining,
++                           qc->error_app ? "app " : "", qc->error,
++                           qc->error_reason ? qc->error_reason : "");
 +
++            if (rc == NGX_OK) {
 +                ctx = ngx_quic_get_send_ctx(qc, qc->error_level);
-+
 +                ngx_add_timer(&qc->close, 3 * ngx_quic_pto(c, ctx));
-+
-+                qc->error = NGX_QUIC_ERR_NO_ERROR;
-+
-+            } else {
-+                if (qc->error == 0 && !qc->error_app) {
-+                    qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
-+                }
-+
-+                ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
-+                               "quic close immediate due to %serror: %ui %s",
-+                               qc->error_app ? "app " : "", qc->error,
-+                               qc->error_reason ? qc->error_reason : "");
 +            }
 +
 +            (void) ngx_quic_send_cc(c);
@@ -1939,6 +1936,10 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +        return;
 +    }
 +
++    if (qc->close.posted) {
++        ngx_delete_posted_event(&qc->close);
++    }
++
 +    ngx_quic_close_sockets(c);
 +
 +    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic close completed");
@@ -1977,12 +1978,17 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +    ngx_quic_connection_t  *qc;
 +
 +    qc = ngx_quic_get_connection(c);
++
++    if (qc->closing) {
++        return;
++    }
++
 +    qc->error = err;
 +    qc->error_reason = reason;
 +    qc->error_app = 1;
 +    qc->error_ftype = 0;
 +
-+    ngx_quic_close_connection(c, NGX_ERROR);
++    ngx_post_event(&qc->close, &ngx_posted_events);
 +}
 +
 +
@@ -2002,14 +2008,15 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +
 +
 +static void
-+ngx_quic_close_timer_handler(ngx_event_t *ev)
++ngx_quic_close_handler(ngx_event_t *ev)
 +{
 +    ngx_connection_t  *c;
 +
-+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic close timer");
++    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic close handler");
 +
 +    c = ev->data;
-+    ngx_quic_close_connection(c, NGX_DONE);
++
++    ngx_quic_close_connection(c, NGX_OK);
 +}
 +
 +
@@ -2304,7 +2311,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +
 +    qc = ngx_quic_get_connection(c);
 +
-+    qc->error = 0;
++    qc->error = (ngx_uint_t) -1;
 +    qc->error_reason = 0;
 +
 +    c->log->action = "decrypting packet";
@@ -2794,38 +2801,17 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.c
 +void
 +ngx_quic_shutdown_quic(ngx_connection_t *c)
 +{
-+    ngx_rbtree_t           *tree;
-+    ngx_rbtree_node_t      *node;
-+    ngx_quic_stream_t      *qs;
 +    ngx_quic_connection_t  *qc;
 +
-+    qc = ngx_quic_get_connection(c);
-+
-+    if (qc->closing) {
-+        return;
-+    }
-+
-+    tree = &qc->streams.tree;
-+
-+    if (tree->root != tree->sentinel) {
-+        for (node = ngx_rbtree_min(tree->root, tree->sentinel);
-+             node;
-+             node = ngx_rbtree_next(tree, node))
-+        {
-+            qs = (ngx_quic_stream_t *) node;
-+
-+            if (!qs->cancelable) {
-+                return;
-+            }
-+        }
++    if (c->reusable) {
++        qc = ngx_quic_get_connection(c);
++        ngx_quic_finalize_connection(c, qc->shutdown_code, qc->shutdown_reason);
 +    }
-+
-+    ngx_quic_finalize_connection(c, qc->shutdown_code, qc->shutdown_reason);
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic.h	Thu Oct 20 13:21:28 2022 -0400
-@@ -0,0 +1,123 @@
++++ b/src/event/quic/ngx_event_quic.h	Tue Dec 13 12:15:22 2022 -0500
+@@ -0,0 +1,133 @@
 +
 +/*
 + * Copyright (C) Nginx, Inc.
@@ -2856,6 +2842,10 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.h
 +#define NGX_QUIC_STREAM_UNIDIRECTIONAL       0x02
 +
 +
++typedef ngx_int_t (*ngx_quic_init_pt)(ngx_connection_t *c);
++typedef void (*ngx_quic_shutdown_pt)(ngx_connection_t *c);
++
++
 +typedef enum {
 +    NGX_QUIC_STREAM_SEND_READY = 0,
 +    NGX_QUIC_STREAM_SEND_SEND,
@@ -2902,6 +2892,9 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.h
 +    ngx_int_t                      stream_reject_code_uni;
 +    ngx_int_t                      stream_reject_code_bidi;
 +
++    ngx_quic_init_pt               init;
++    ngx_quic_shutdown_pt           shutdown;
++
 +    u_char                         av_token_key[NGX_QUIC_AV_KEY_LEN];
 +    u_char                         sr_token_key[NGX_QUIC_SR_KEY_LEN];
 +} ngx_quic_conf_t;
@@ -2913,6 +2906,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.h
 +    ngx_connection_t              *parent;
 +    ngx_connection_t              *connection;
 +    uint64_t                       id;
++    uint64_t                       sent;
 +    uint64_t                       acked;
 +    uint64_t                       send_max_data;
 +    uint64_t                       send_offset;
@@ -2926,7 +2920,8 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.h
 +    ngx_quic_buffer_t              recv;
 +    ngx_quic_stream_send_state_e   send_state;
 +    ngx_quic_stream_recv_state_e   recv_state;
-+    ngx_uint_t                     cancelable;  /* unsigned  cancelable:1; */
++    unsigned                       cancelable:1;
++    unsigned                       fin_acked:1;
 +};
 +
 +
@@ -2941,6 +2936,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.h
 +    const char *reason);
 +ngx_int_t ngx_quic_reset_stream(ngx_connection_t *c, ngx_uint_t err);
 +ngx_int_t ngx_quic_shutdown_stream(ngx_connection_t *c, int how);
++void ngx_quic_cancelable_stream(ngx_connection_t *c);
 +ngx_int_t ngx_quic_handle_read_event(ngx_event_t *rev, ngx_uint_t flags);
 +ngx_int_t ngx_quic_handle_write_event(ngx_event_t *wev, size_t lowat);
 +ngx_int_t ngx_quic_get_packet_dcid(ngx_log_t *log, u_char *data, size_t len,
@@ -2951,8 +2947,8 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic.h
 +#endif /* _NGX_EVENT_QUIC_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_ack.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_ack.c	Thu Oct 20 13:21:28 2022 -0400
-@@ -0,0 +1,1193 @@
++++ b/src/event/quic/ngx_event_quic_ack.c	Tue Dec 13 12:15:22 2022 -0500
+@@ -0,0 +1,1194 @@
 +
 +/*
 + * Copyright (C) Nginx, Inc.
@@ -3150,7 +3146,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_ack.c
 +    } else {
 +        qc->min_rtt = ngx_min(qc->min_rtt, latest_rtt);
 +
-+        ack_delay = ack->delay * (1 << qc->ctp.ack_delay_exponent) / 1000;
++        ack_delay = (ack->delay << qc->ctp.ack_delay_exponent) / 1000;
 +
 +        if (c->ssl->handshaked) {
 +            ack_delay = ngx_min(ack_delay, qc->ctp.max_ack_delay);
@@ -3208,6 +3204,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_ack.c
 +                break;
 +
 +            case NGX_QUIC_FT_STREAM:
++            case NGX_QUIC_FT_RESET_STREAM:
 +                ngx_quic_handle_stream_ack(c, f);
 +                break;
 +            }
@@ -4148,7 +4145,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_ack.c
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_ack.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_ack.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_ack.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,30 @@
 +
 +/*
@@ -4182,7 +4179,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_ack.h
 +#endif /* _NGX_EVENT_QUIC_ACK_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_bpf.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_bpf.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_bpf.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,657 @@
 +
 +/*
@@ -4843,7 +4840,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_bpf.c
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_bpf_code.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_bpf_code.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_bpf_code.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,88 @@
 +/* AUTO-GENERATED, DO NOT EDIT. */
 +
@@ -4935,7 +4932,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_bpf_code.c
 +};
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_connection.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_connection.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_connection.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,276 @@
 +/*
 + * Copyright (C) Nginx, Inc.
@@ -5215,7 +5212,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_connection.h
 +#endif /* _NGX_EVENT_QUIC_CONNECTION_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_connid.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_connid.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_connid.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,502 @@
 +
 +/*
@@ -5721,7 +5718,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_connid.c
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_connid.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_connid.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_connid.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,29 @@
 +
 +/*
@@ -5754,7 +5751,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_connid.h
 +#endif /* _NGX_EVENT_QUIC_CONNID_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_frames.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_frames.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_frames.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,844 @@
 +
 +/*
@@ -6602,7 +6599,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_frames.c
 +#endif
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_frames.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_frames.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_frames.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,43 @@
 +
 +/*
@@ -6649,7 +6646,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_frames.h
 +#endif /* _NGX_EVENT_QUIC_FRAMES_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_migration.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_migration.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_migration.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,671 @@
 +
 +/*
@@ -7324,7 +7321,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_migration.c
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_migration.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_migration.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_migration.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,42 @@
 +
 +/*
@@ -7370,7 +7367,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_migration.h
 +#endif /* _NGX_EVENT_QUIC_MIGRATION_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_output.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_output.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_output.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,1292 @@
 +
 +/*
@@ -8666,7 +8663,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_output.c
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_output.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_output.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_output.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,40 @@
 +
 +/*
@@ -8710,7 +8707,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_output.h
 +#endif /* _NGX_EVENT_QUIC_OUTPUT_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_protection.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_protection.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,1126 @@
 +
 +/*
@@ -8762,12 +8759,10 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +    const u_char             *label;
 +} ngx_quic_hkdf_t;
 +
-+#define ngx_quic_hkdf_set(label, out, prk)                                    \
-+    {                                                                         \
-+        (out)->len, (out)->data,                                              \
-+        (prk)->len, (prk)->data,                                              \
-+        (sizeof(label) - 1), (u_char *)(label),                               \
-+    }
++#define ngx_quic_hkdf_set(seq, _label, _out, _prk)                            \
++    (seq)->out_len = (_out)->len; (seq)->out = (_out)->data;                  \
++    (seq)->prk_len = (_prk)->len, (seq)->prk = (_prk)->data,                  \
++    (seq)->label_len = (sizeof(_label) - 1); (seq)->label = (u_char *)(_label);
 +
 +
 +static ngx_int_t ngx_hkdf_expand(u_char *out_key, size_t out_len,
@@ -8863,8 +8858,10 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +{
 +    size_t              is_len;
 +    uint8_t             is[SHA256_DIGEST_LENGTH];
++    ngx_str_t           iss;
 +    ngx_uint_t          i;
 +    const EVP_MD       *digest;
++    ngx_quic_hkdf_t     seq[8];
 +    ngx_quic_secret_t  *client, *server;
 +
 +    static const uint8_t salt[20] =
@@ -8891,10 +8888,8 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +        return NGX_ERROR;
 +    }
 +
-+    ngx_str_t iss = {
-+        .data = is,
-+        .len = is_len
-+    };
++    iss.len = is_len;
++    iss.data = is;
 +
 +    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
 +                   "quic ngx_quic_set_initial_secret");
@@ -8917,17 +8912,15 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +    client->iv.len = NGX_QUIC_IV_LEN;
 +    server->iv.len = NGX_QUIC_IV_LEN;
 +
-+    ngx_quic_hkdf_t seq[] = {
-+        /* labels per RFC 9001, 5.1. Packet Protection Keys */
-+        ngx_quic_hkdf_set("tls13 client in", &client->secret, &iss),
-+        ngx_quic_hkdf_set("tls13 quic key",  &client->key,    &client->secret),
-+        ngx_quic_hkdf_set("tls13 quic iv",   &client->iv,     &client->secret),
-+        ngx_quic_hkdf_set("tls13 quic hp",   &client->hp,     &client->secret),
-+        ngx_quic_hkdf_set("tls13 server in", &server->secret, &iss),
-+        ngx_quic_hkdf_set("tls13 quic key",  &server->key,    &server->secret),
-+        ngx_quic_hkdf_set("tls13 quic iv",   &server->iv,     &server->secret),
-+        ngx_quic_hkdf_set("tls13 quic hp",   &server->hp,     &server->secret),
-+    };
++    /* labels per RFC 9001, 5.1. Packet Protection Keys */
++    ngx_quic_hkdf_set(&seq[0], "tls13 client in", &client->secret, &iss);
++    ngx_quic_hkdf_set(&seq[1], "tls13 quic key", &client->key, &client->secret);
++    ngx_quic_hkdf_set(&seq[2], "tls13 quic iv", &client->iv, &client->secret);
++    ngx_quic_hkdf_set(&seq[3], "tls13 quic hp", &client->hp, &client->secret);
++    ngx_quic_hkdf_set(&seq[4], "tls13 server in", &server->secret, &iss);
++    ngx_quic_hkdf_set(&seq[5], "tls13 quic key", &server->key, &server->secret);
++    ngx_quic_hkdf_set(&seq[6], "tls13 quic iv", &server->iv, &server->secret);
++    ngx_quic_hkdf_set(&seq[7], "tls13 quic hp", &server->hp, &server->secret);
 +
 +    for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
 +        if (ngx_quic_hkdf_expand(&seq[i], digest, log) != NGX_OK) {
@@ -9353,6 +9346,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +    ngx_int_t            key_len;
 +    ngx_str_t            secret_str;
 +    ngx_uint_t           i;
++    ngx_quic_hkdf_t      seq[3];
 +    ngx_quic_secret_t   *peer_secret;
 +    ngx_quic_ciphers_t   ciphers;
 +
@@ -9384,11 +9378,10 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +    secret_str.len = secret_len;
 +    secret_str.data = (u_char *) secret;
 +
-+    ngx_quic_hkdf_t seq[] = {
-+        ngx_quic_hkdf_set("tls13 quic key", &peer_secret->key, &secret_str),
-+        ngx_quic_hkdf_set("tls13 quic iv", &peer_secret->iv, &secret_str),
-+        ngx_quic_hkdf_set("tls13 quic hp", &peer_secret->hp, &secret_str),
-+    };
++    ngx_quic_hkdf_set(&seq[0], "tls13 quic key",
++                      &peer_secret->key, &secret_str);
++    ngx_quic_hkdf_set(&seq[1], "tls13 quic iv", &peer_secret->iv, &secret_str);
++    ngx_quic_hkdf_set(&seq[2], "tls13 quic hp", &peer_secret->hp, &secret_str);
 +
 +    for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
 +        if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, log) != NGX_OK) {
@@ -9434,6 +9427,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys)
 +{
 +    ngx_uint_t           i;
++    ngx_quic_hkdf_t      seq[6];
 +    ngx_quic_ciphers_t   ciphers;
 +    ngx_quic_secrets_t  *current, *next;
 +
@@ -9458,20 +9452,18 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +    next->server.iv.len = NGX_QUIC_IV_LEN;
 +    next->server.hp = current->server.hp;
 +
-+    ngx_quic_hkdf_t seq[] = {
-+        ngx_quic_hkdf_set("tls13 quic ku",
-+                          &next->client.secret, &current->client.secret),
-+        ngx_quic_hkdf_set("tls13 quic key",
-+                          &next->client.key, &next->client.secret),
-+        ngx_quic_hkdf_set("tls13 quic iv",
-+                          &next->client.iv, &next->client.secret),
-+        ngx_quic_hkdf_set("tls13 quic ku",
-+                          &next->server.secret, &current->server.secret),
-+        ngx_quic_hkdf_set("tls13 quic key",
-+                          &next->server.key, &next->server.secret),
-+        ngx_quic_hkdf_set("tls13 quic iv",
-+                          &next->server.iv, &next->server.secret),
-+    };
++    ngx_quic_hkdf_set(&seq[0], "tls13 quic ku",
++                      &next->client.secret, &current->client.secret);
++    ngx_quic_hkdf_set(&seq[1], "tls13 quic key",
++                      &next->client.key, &next->client.secret);
++    ngx_quic_hkdf_set(&seq[2], "tls13 quic iv",
++                      &next->client.iv, &next->client.secret);
++    ngx_quic_hkdf_set(&seq[3], "tls13 quic ku",
++                      &next->server.secret, &current->server.secret);
++    ngx_quic_hkdf_set(&seq[4], "tls13 quic key",
++                      &next->server.key, &next->server.secret);
++    ngx_quic_hkdf_set(&seq[5], "tls13 quic iv",
++                      &next->server.iv, &next->server.secret);
 +
 +    for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
 +        if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) {
@@ -9683,10 +9675,14 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +static void
 +ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn)
 +{
-+    nonce[len - 4] ^= (pn & 0xff000000) >> 24;
-+    nonce[len - 3] ^= (pn & 0x00ff0000) >> 16;
-+    nonce[len - 2] ^= (pn & 0x0000ff00) >> 8;
-+    nonce[len - 1] ^= (pn & 0x000000ff);
++    nonce[len - 8] ^= (pn >> 56) & 0x3f;
++    nonce[len - 7] ^= (pn >> 48) & 0xff;
++    nonce[len - 6] ^= (pn >> 40) & 0xff;
++    nonce[len - 5] ^= (pn >> 32) & 0xff;
++    nonce[len - 4] ^= (pn >> 24) & 0xff;
++    nonce[len - 3] ^= (pn >> 16) & 0xff;
++    nonce[len - 2] ^= (pn >> 8) & 0xff;
++    nonce[len - 1] ^= pn & 0xff;
 +}
 +
 +
@@ -9707,8 +9703,9 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +    u_char              *p, *sample;
 +    size_t               len;
 +    uint64_t             pn, lpn;
-+    ngx_int_t            pnl, rc, key_phase;
++    ngx_int_t            pnl, rc;
 +    ngx_str_t            in, ad;
++    ngx_uint_t           key_phase;
 +    ngx_quic_secret_t   *secret;
 +    ngx_quic_ciphers_t   ciphers;
 +    uint8_t              nonce[NGX_QUIC_IV_LEN], mask[NGX_QUIC_HP_LEN];
@@ -9840,7 +9837,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.c
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_protection.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_protection.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,75 @@
 +
 +/*
@@ -9919,7 +9916,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_protection.h
 +#endif /* _NGX_EVENT_QUIC_PROTECTION_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_socket.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_socket.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_socket.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,237 @@
 +
 +/*
@@ -10160,7 +10157,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_socket.c
 +}
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_socket.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_socket.h	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_socket.h	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,28 @@
 +
 +/*
@@ -10192,7 +10189,7 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_socket.h
 +#endif /* _NGX_EVENT_QUIC_SOCKET_H_INCLUDED_ */
 diff -r aa901551a7eb src/event/quic/ngx_event_quic_ssl.c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_ssl.c	Thu Oct 20 13:21:28 2022 -0400
++++ b/src/event/quic/ngx_event_quic_ssl.c	Tue Dec 13 12:15:22 2022 -0500
 @@ -0,0 +1,610 @@
 +
 +/*
@@ -10235,19 +10232,6 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_ssl.c
 +static ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data);
 +
 +
-+static SSL_QUIC_METHOD quic_method = {
-+#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
-+    .set_read_secret = ngx_quic_set_read_secret,
-+    .set_write_secret = ngx_quic_set_write_secret,
-+#else
-+    .set_encryption_secrets = ngx_quic_set_encryption_secrets,
-+#endif
-+    .add_handshake_data = ngx_quic_add_handshake_data,
-+    .flush_flight = ngx_quic_flush_flight,
-+    .send_alert = ngx_quic_send_alert,
-+};
-+
-+
 +#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
 +
 +static int
@@ -10729,13 +10713,14 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_ssl.c
 +ngx_int_t
 +ngx_quic_init_connection(ngx_connection_t *c)
 +{
-+    u_char                 *p;
-+    size_t                  clen;
-+    ssize_t                 len;
-+    ngx_str_t               dcid;
-+    ngx_ssl_conn_t         *ssl_conn;
-+    ngx_quic_socket_t      *qsock;
-+    ngx_quic_connection_t  *qc;
++    u_char                  *p;
++    size_t                   clen;
++    ssize_t                  len;
++    ngx_str_t                dcid;
++    ngx_ssl_conn_t          *ssl_conn;
++    ngx_quic_socket_t       *qsock;
++    ngx_quic_connection_t   *qc;
++    static SSL_QUIC_METHOD   quic_method;
 +
 +    qc = ngx_quic_get_connection(c);
 +
@@ -10747,6 +10732,18 @@ diff -r aa901551a7eb src/event/quic/ngx_event_quic_ssl.c
 +
 +    ssl_conn = c->ssl->connection;
 +
++    if (!quic_method.send_alert) {
++#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
++        quic_method.set_read_secret = ngx_quic_set_read_secret;
++        quic_method.set_write_secret = ngx_quic_set_write_secret;
++#else
++        quic_method.set_encryption_secrets = ngx_quic_set_encryption_secrets;
++#endif
++        quic_method.add_handshake_data = ngx_quic_add_handshake_data;
*** 1452 LINES SKIPPED ***