aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey A. Osokin <osa@FreeBSD.org>2023-03-31 04:09:52 +0000
committerSergey A. Osokin <osa@FreeBSD.org>2023-03-31 04:09:52 +0000
commit19ca0e1ac0f410a8bba180192f47794dd4f3532b (patch)
treea019c3d404d5cbaff453390b6c11aa44796b51aa
parent72044b5eaa1230acbf451f8ea5c340021b2b0bb7 (diff)
downloadports-19ca0e1ac0f410a8bba180192f47794dd4f3532b.tar.gz
ports-19ca0e1ac0f410a8bba180192f47794dd4f3532b.zip
www/nginx-devel: update HTTPv3/QUIC patch
Bump PORTREVISION. PR: 270523
-rw-r--r--www/nginx-devel/Makefile1
-rw-r--r--www/nginx-devel/files/extra-patch-httpv31960
2 files changed, 1466 insertions, 495 deletions
diff --git a/www/nginx-devel/Makefile b/www/nginx-devel/Makefile
index d3fd629b1cc3..dfaa815a9e60 100644
--- a/www/nginx-devel/Makefile
+++ b/www/nginx-devel/Makefile
@@ -1,5 +1,6 @@
PORTNAME?= nginx
PORTVERSION= 1.23.4
+PORTREVISION= 1
CATEGORIES= www
MASTER_SITES= https://nginx.org/download/ \
LOCAL/osa
diff --git a/www/nginx-devel/files/extra-patch-httpv3 b/www/nginx-devel/files/extra-patch-httpv3
index 60e9f2e85e04..ea266e8b4764 100644
--- a/www/nginx-devel/files/extra-patch-httpv3
+++ b/www/nginx-devel/files/extra-patch-httpv3
@@ -1,17 +1,18 @@
-diff -r ff3afd1ce6a6 README
+diff -r ac779115ed6e README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/README Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,250 @@
++++ b/README Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,389 @@
+Experimental QUIC support for nginx
+-----------------------------------
+
+1. Introduction
-+2. Installing
++2. Building from sources
+3. Configuration
-+4. Clients
-+5. Troubleshooting
-+6. Contributing
-+7. Links
++4. Directives
++5. Clients
++6. Troubleshooting
++7. Contributing
++8. Links
+
+1. Introduction
+
@@ -55,14 +56,28 @@ diff -r ff3afd1ce6a6 README
+ + Lost packets are detected and retransmitted properly
+ + Clients may migrate to new address
+
-+2. Installing
++2. Building from sources
+
-+ A library that provides QUIC support is required to build nginx, there
++ The build is configured using the configure command.
++ Refer to http://nginx.org/en/docs/configure.html for details.
++
++ When configuring nginx, it's possible to enable QUIC and HTTP/3
++ using the following new configuration options:
++
++ --with-http_v3_module - enable QUIC and HTTP/3
++ --with-stream_quic_module - enable QUIC in Stream
++
++ A library that provides QUIC support is recommended to build nginx, there
+ are several of those available on the market:
+ + BoringSSL [4]
+ + LibreSSL [5]
+ + QuicTLS [6]
+
++ Alternatively, nginx can be configured with OpenSSL compatibility
++ layer, which emulates BoringSSL QUIC API for OpenSSL. This mode is
++ enabled by default if native QUIC support is not detected.
++ 0-RTT is not supported in OpenSSL compatibility mode.
++
+ Clone the NGINX QUIC repository
+
+ $ hg clone -b quic https://hg.nginx.org/nginx-quic
@@ -89,21 +104,15 @@ diff -r ff3afd1ce6a6 README
+ --with-cc-opt="-I../libressl/build/include" \
+ --with-ld-opt="-L../libressl/build/lib"
+
-+ When configuring nginx, it's possible to enable QUIC and HTTP/3
-+ using the following new configuration options:
-+
-+ --with-http_v3_module - enable QUIC and HTTP/3
-+ --with-stream_quic_module - enable QUIC in Stream
-+
+3. Configuration
+
-+ The HTTP "listen" directive got a new option "http3" which enables
-+ HTTP/3 over QUIC on the specified port.
++ The HTTP "listen" directive got a new option "quic" which enables
++ QUIC as client transport protocol instead of TCP.
+
+ The Stream "listen" directive got a new option "quic" which enables
+ QUIC as client transport protocol instead of TCP or plain UDP.
+
-+ Along with "http3" or "quic", it's also possible to specify "reuseport"
++ Along with "quic", it's also possible to specify "reuseport"
+ option [8] to make it work properly with multiple workers.
+
+ To enable address validation:
@@ -137,12 +146,13 @@ diff -r ff3afd1ce6a6 README
+
+ A number of directives were added that configure HTTP/3:
+
++ http3
++ http3_hq
+ http3_stream_buffer_size
+ http3_max_concurrent_pushes
+ http3_max_concurrent_streams
+ http3_push
+ http3_push_preload
-+ http3_hq (requires NGX_HTTP_V3_HQ macro)
+
+ In http, an additional variable is available: $http3.
+ The value of $http3 is "h3" for HTTP/3 connections,
@@ -164,7 +174,7 @@ diff -r ff3afd1ce6a6 README
+ server {
+ # for better compatibility it's recommended
+ # to use the same port for quic and https
-+ listen 8443 http3 reuseport;
++ listen 8443 quic reuseport;
+ listen 8443 ssl;
+
+ ssl_certificate certs/example.com.crt;
@@ -178,7 +188,136 @@ diff -r ff3afd1ce6a6 README
+ }
+ }
+
-+4. Clients
++4. Directives
++
++ Syntax: quic_bpf on | off;
++ Default: quic_bpf off;
++ Context: main
++
++ Enables routing of QUIC packets using eBPF.
++ When enabled, this allows to support QUIC connection migration.
++ The directive is only supported on Linux 5.7+.
++
++
++ Syntax: quic_retry on | off;
++ Default: quic_retry off;
++ Context: http | stream, server
++
++ Enables the QUIC Address Validation feature. This includes:
++ - sending a new token in a Retry packet or a NEW_TOKEN frame
++ - validating a token received in the Initial packet
++
++
++ Syntax: quic_gso on | off;
++ Default: quic_gso off;
++ Context: http | stream, server
++
++ Enables sending in optimized batch mode using segmentation offloading.
++ Optimized sending is only supported on Linux featuring UDP_SEGMENT.
++
++
++ Syntax: quic_mtu size;
++ Default: quic_mtu 65527;
++ Context: http | stream, server
++
++ Sets the QUIC max_udp_payload_size transport parameter value.
++ This is the maximum UDP payload that we are willing to receive.
++
++
++ Syntax: quic_host_key file;
++ Default: -
++ Context: http | stream, server
++
++ Specifies a file with the secret key used to encrypt stateless reset and
++ address validation tokens. By default, a randomly generated key is used.
++
++
++ Syntax: quic_active_connection_id_limit number;
++ Default: quic_active_connection_id_limit 2;
++ Context: http | stream, server
++
++ Sets the QUIC active_connection_id_limit transport parameter value.
++ This is the maximum number of connection IDs we are willing to store.
++
++
++ Syntax: quic_timeout time;
++ Default: quic_timeout 60s;
++ Context: stream, server
++
++ Defines a timeout used to negotiate the QUIC idle timeout.
++ In the http module, it is taken from the keepalive_timeout directive.
++
++
++ Syntax: quic_stream_buffer_size size;
++ Default: quic_stream_buffer_size 64k;
++ Context: stream, server
++
++ Syntax: http3_stream_buffer_size size;
++ Default: http3_stream_buffer_size 64k;
++ Context: http, server
++
++ Sets buffer size for reading and writing of the QUIC STREAM payload.
++ The buffer size is used to calculate initial flow control limits
++ in the following QUIC transport parameters:
++ - initial_max_data
++ - initial_max_stream_data_bidi_local
++ - initial_max_stream_data_bidi_remote
++ - initial_max_stream_data_uni
++
++
++ Syntax: http3_max_concurrent_pushes number;
++ Default: http3_max_concurrent_pushes 10;
++ Context: http, server
++
++ Limits the maximum number of concurrent push requests in a connection.
++
++
++ Syntax: http3_max_concurrent_streams number;
++ Default: http3_max_concurrent_streams 128;
++ Context: http, server
++
++ Sets the maximum number of concurrent HTTP/3 streams in a connection.
++
++
++ Syntax: http3_push uri | off;
++ Default: http3_push off;
++ Context: http, server, location
++
++ Pre-emptively sends (pushes) a request to the specified uri along with
++ the response to the original request. Only relative URIs with absolute
++ path will be processed, for example:
++
++ http3_push /static/css/main.css;
++
++ The uri value can contain variables.
++
++ Several http3_push directives can be specified on the same configuration
++ level. The off parameter cancels the effect of the http3_push directives
++ inherited from the previous configuration level.
++
++
++ Syntax: http3_push_preload on | off;
++ Default: http3_push_preload off;
++ Context: http, server, location
++
++ Enables automatic conversion of preload links specified in the “Link”
++ response header fields into push requests.
++
++
++ Syntax: http3 on | off;
++ Default: http3 on;
++ Context: http, server
++
++ Enables HTTP/3 protocol negotiation.
++
++
++ Syntax: http3_hq on | off;
++ Default: http3_hq off;
++ Context: http, server
++
++ Enables HTTP/0.9 protocol negotiation used in QUIC interoperability tests.
++
++5. Clients
+
+ * Browsers
+
@@ -205,7 +344,7 @@ diff -r ff3afd1ce6a6 README
+ "nghttp3/ngtcp2 client" "quic"
+
+
-+5. Troubleshooting
++6. Troubleshooting
+
+ Here are some tips that may help to identify problems:
+
@@ -235,16 +374,16 @@ diff -r ff3afd1ce6a6 README
+ #define NGX_QUIC_DEBUG_ALLOC
+ #define NGX_QUIC_DEBUG_CRYPTO
+
-+6. Contributing
++7. Contributing
+
+ Please refer to
+ http://nginx.org/en/docs/contributing_changes.html
+
-+7. Links
++8. Links
+
+ [1] https://datatracker.ietf.org/doc/html/rfc9000
+ [2] https://datatracker.ietf.org/doc/html/rfc9114
-+ [3] https://mailman.nginx.org/mailman3/lists/nginx-devel.nginx.org/
++ [3] https://mailman.nginx.org/mailman/listinfo/nginx-devel
+ [4] https://boringssl.googlesource.com/boringssl/
+ [5] https://www.libressl.org/
+ [6] https://github.com/quictls/openssl
@@ -252,10 +391,10 @@ diff -r ff3afd1ce6a6 README
+ [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
-diff -r ff3afd1ce6a6 auto/lib/openssl/conf
---- a/auto/lib/openssl/conf Tue Dec 13 18:53:53 2022 +0300
-+++ b/auto/lib/openssl/conf Tue Jan 31 11:41:14 2023 -0500
-@@ -5,12 +5,16 @@
+diff -r ac779115ed6e auto/lib/openssl/conf
+--- a/auto/lib/openssl/conf Tue Mar 28 18:01:53 2023 +0300
++++ b/auto/lib/openssl/conf Fri Mar 31 00:04:13 2023 -0400
+@@ -5,12 +5,17 @@
if [ $OPENSSL != NONE ]; then
@@ -264,6 +403,7 @@ diff -r ff3afd1ce6a6 auto/lib/openssl/conf
+
+ if [ $USE_OPENSSL_QUIC = YES ]; then
+ have=NGX_QUIC . auto/have
++ have=NGX_QUIC_OPENSSL_COMPAT . auto/have
+ fi
+
case "$CC" in
@@ -275,7 +415,7 @@ diff -r ff3afd1ce6a6 auto/lib/openssl/conf
CFLAGS="$CFLAGS -DNO_SYS_TYPES_H"
CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
-@@ -33,9 +37,6 @@ if [ $OPENSSL != NONE ]; then
+@@ -33,9 +38,6 @@ if [ $OPENSSL != NONE ]; then
;;
*)
@@ -285,23 +425,28 @@ diff -r ff3afd1ce6a6 auto/lib/openssl/conf
CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
-@@ -139,4 +140,28 @@ END
- exit 1
- fi
-
-+ if [ $USE_OPENSSL_QUIC = YES ]; then
+@@ -123,6 +125,35 @@ else
+ CORE_INCS="$CORE_INCS $ngx_feature_path"
+ CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+ OPENSSL=YES
++
++ if [ $USE_OPENSSL_QUIC = YES ]; then
++
++ ngx_feature="OpenSSL QUIC support"
++ ngx_feature_name="NGX_QUIC"
++ ngx_feature_test="SSL_set_quic_method(NULL, NULL)"
++ . auto/feature
+
-+ ngx_feature="OpenSSL QUIC support"
-+ ngx_feature_name="NGX_QUIC"
-+ ngx_feature_run=no
-+ ngx_feature_incs="#include <openssl/ssl.h>"
-+ ngx_feature_path=
-+ ngx_feature_libs="-lssl -lcrypto $NGX_LIBDL $NGX_LIBPTHREAD"
-+ ngx_feature_test="SSL_set_quic_method(NULL, NULL)"
-+ . auto/feature
++ if [ $ngx_found = no ]; then
++ have=NGX_QUIC_OPENSSL_COMPAT . auto/have
+
-+ if [ $ngx_found = no ]; then
++ ngx_feature="OpenSSL QUIC compatibility"
++ ngx_feature_test="SSL_CTX_add_custom_ext(NULL, 0, 0,
++ NULL, NULL, NULL, NULL, NULL)"
++ . auto/feature
++ fi
+
++ if [ $ngx_found = no ]; then
+cat << END
+
+$0: error: certain modules require OpenSSL QUIC support.
@@ -310,13 +455,15 @@ diff -r ff3afd1ce6a6 auto/lib/openssl/conf
+statically from the source with nginx by using --with-openssl=<path> option.
+
+END
-+ exit 1
-+ fi
-+ fi
- fi
-diff -r ff3afd1ce6a6 auto/make
---- a/auto/make Tue Dec 13 18:53:53 2022 +0300
-+++ b/auto/make Tue Jan 31 11:41:14 2023 -0500
++ exit 1
++ fi
++ fi
+ fi
+ fi
+
+diff -r ac779115ed6e auto/make
+--- a/auto/make Tue Mar 28 18:01:53 2023 +0300
++++ b/auto/make Fri Mar 31 00:04:13 2023 -0400
@@ -6,9 +6,10 @@
echo "creating $NGX_MAKEFILE"
@@ -330,9 +477,9 @@ diff -r ff3afd1ce6a6 auto/make
$NGX_OBJS/src/mail \
$NGX_OBJS/src/stream \
$NGX_OBJS/src/misc
-diff -r ff3afd1ce6a6 auto/modules
---- a/auto/modules Tue Dec 13 18:53:53 2022 +0300
-+++ b/auto/modules Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e auto/modules
+--- a/auto/modules Tue Mar 28 18:01:53 2023 +0300
++++ b/auto/modules Fri Mar 31 00:04:13 2023 -0400
@@ -102,7 +102,7 @@ if [ $HTTP = YES ]; then
fi
@@ -431,7 +578,7 @@ diff -r ff3afd1ce6a6 auto/modules
if [ $STREAM_SSL = YES ]; then
USE_OPENSSL=YES
have=NGX_STREAM_SSL . auto/have
-@@ -1272,6 +1326,61 @@ if [ $USE_OPENSSL = YES ]; then
+@@ -1272,6 +1326,63 @@ if [ $USE_OPENSSL = YES ]; then
fi
@@ -451,7 +598,8 @@ diff -r ff3afd1ce6a6 auto/modules
+ src/event/quic/ngx_event_quic_tokens.h \
+ src/event/quic/ngx_event_quic_ack.h \
+ src/event/quic/ngx_event_quic_output.h \
-+ src/event/quic/ngx_event_quic_socket.h"
++ src/event/quic/ngx_event_quic_socket.h \
++ src/event/quic/ngx_event_quic_openssl_compat.h"
+ ngx_module_srcs="src/event/quic/ngx_event_quic.c \
+ src/event/quic/ngx_event_quic_udp.c \
+ src/event/quic/ngx_event_quic_transport.c \
@@ -464,7 +612,8 @@ diff -r ff3afd1ce6a6 auto/modules
+ src/event/quic/ngx_event_quic_tokens.c \
+ src/event/quic/ngx_event_quic_ack.c \
+ src/event/quic/ngx_event_quic_output.c \
-+ src/event/quic/ngx_event_quic_socket.c"
++ src/event/quic/ngx_event_quic_socket.c \
++ src/event/quic/ngx_event_quic_openssl_compat.c"
+
+ ngx_module_libs=
+ ngx_module_link=YES
@@ -493,9 +642,9 @@ diff -r ff3afd1ce6a6 auto/modules
if [ $USE_PCRE = YES ]; then
ngx_module_type=CORE
ngx_module_name=ngx_regex_module
-diff -r ff3afd1ce6a6 auto/options
---- a/auto/options Tue Dec 13 18:53:53 2022 +0300
-+++ b/auto/options Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e auto/options
+--- a/auto/options Tue Mar 28 18:01:53 2023 +0300
++++ b/auto/options Fri Mar 31 00:04:13 2023 -0400
@@ -45,6 +45,8 @@ USE_THREADS=NO
NGX_FILE_AIO=NO
@@ -583,9 +732,9 @@ diff -r ff3afd1ce6a6 auto/options
--with-stream_realip_module enable ngx_stream_realip_module
--with-stream_geoip_module enable ngx_stream_geoip_module
--with-stream_geoip_module=dynamic enable dynamic ngx_stream_geoip_module
-diff -r ff3afd1ce6a6 auto/os/linux
---- a/auto/os/linux Tue Dec 13 18:53:53 2022 +0300
-+++ b/auto/os/linux Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e auto/os/linux
+--- a/auto/os/linux Tue Mar 28 18:01:53 2023 +0300
++++ b/auto/os/linux Fri Mar 31 00:04:13 2023 -0400
@@ -232,6 +232,50 @@ ngx_feature_test="struct crypt_data cd;
ngx_include="sys/vfs.h"; . auto/include
@@ -637,9 +786,9 @@ diff -r ff3afd1ce6a6 auto/os/linux
# UDP segmentation offloading
ngx_feature="UDP_SEGMENT"
-diff -r ff3afd1ce6a6 auto/sources
---- a/auto/sources Tue Dec 13 18:53:53 2022 +0300
-+++ b/auto/sources Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e auto/sources
+--- a/auto/sources Tue Mar 28 18:01:53 2023 +0300
++++ b/auto/sources Fri Mar 31 00:04:13 2023 -0400
@@ -83,7 +83,7 @@ CORE_SRCS="src/core/nginx.c \
EVENT_MODULES="ngx_events_module ngx_event_core_module"
@@ -649,9 +798,9 @@ diff -r ff3afd1ce6a6 auto/sources
EVENT_DEPS="src/event/ngx_event.h \
src/event/ngx_event_timer.h \
-diff -r ff3afd1ce6a6 src/core/nginx.c
---- a/src/core/nginx.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/core/nginx.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/core/nginx.c
+--- a/src/core/nginx.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/core/nginx.c Fri Mar 31 00:04:13 2023 -0400
@@ -680,6 +680,9 @@ ngx_exec_new_binary(ngx_cycle_t *cycle,
ls = cycle->listening.elts;
@@ -662,9 +811,9 @@ diff -r ff3afd1ce6a6 src/core/nginx.c
p = ngx_sprintf(p, "%ud;", ls[i].fd);
}
-diff -r ff3afd1ce6a6 src/core/ngx_bpf.c
+diff -r ac779115ed6e src/core/ngx_bpf.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/ngx_bpf.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/core/ngx_bpf.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,143 @@
+
+/*
@@ -809,9 +958,9 @@ diff -r ff3afd1ce6a6 src/core/ngx_bpf.c
+
+ return ngx_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
+}
-diff -r ff3afd1ce6a6 src/core/ngx_bpf.h
+diff -r ac779115ed6e src/core/ngx_bpf.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/ngx_bpf.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/core/ngx_bpf.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,43 @@
+
+/*
@@ -856,23 +1005,9 @@ diff -r ff3afd1ce6a6 src/core/ngx_bpf.h
+int ngx_bpf_map_lookup(int fd, const void *key, void *value);
+
+#endif /* _NGX_BPF_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/core/ngx_conf_file.c
---- a/src/core/ngx_conf_file.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/core/ngx_conf_file.c Tue Jan 31 11:41:14 2023 -0500
-@@ -544,8 +544,8 @@ ngx_conf_read_token(ngx_conf_t *cf)
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-- "unexpected end of file, "
-- "expecting \";\" or \"}\"");
-+ "unexpected end of file, "
-+ "expecting \";\" or \"}\"");
- return NGX_ERROR;
- }
-
-diff -r ff3afd1ce6a6 src/core/ngx_connection.c
---- a/src/core/ngx_connection.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/core/ngx_connection.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/core/ngx_connection.c
+--- a/src/core/ngx_connection.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/core/ngx_connection.c Fri Mar 31 00:04:13 2023 -0400
@@ -72,10 +72,6 @@ ngx_create_listening(ngx_conf_t *cf, str
ngx_memcpy(ls->addr_text.data, text, len);
@@ -884,15 +1019,6 @@ diff -r ff3afd1ce6a6 src/core/ngx_connection.c
ls->fd = (ngx_socket_t) -1;
ls->type = SOCK_STREAM;
-@@ -660,7 +656,7 @@ ngx_open_listening_sockets(ngx_cycle_t *
- /*
- * on OpenVZ after suspend/resume EADDRINUSE
- * may be returned by listen() instead of bind(), see
-- * https://bugzilla.openvz.org/show_bug.cgi?id=2470
-+ * https://bugs.openvz.org/browse/OVZ-5587
- */
-
- if (err != NGX_EADDRINUSE || !ngx_test_config) {
@@ -1037,6 +1033,12 @@ ngx_close_listening_sockets(ngx_cycle_t
ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
@@ -906,9 +1032,9 @@ diff -r ff3afd1ce6a6 src/core/ngx_connection.c
c = ls[i].connection;
if (c) {
-diff -r ff3afd1ce6a6 src/core/ngx_connection.h
---- a/src/core/ngx_connection.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/core/ngx_connection.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/core/ngx_connection.h
+--- a/src/core/ngx_connection.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/core/ngx_connection.h Fri Mar 31 00:04:13 2023 -0400
@@ -73,6 +73,7 @@ struct ngx_listening_s {
unsigned reuseport:1;
unsigned add_reuseport:1;
@@ -928,9 +1054,9 @@ diff -r ff3afd1ce6a6 src/core/ngx_connection.h
#if (NGX_SSL || NGX_COMPAT)
ngx_ssl_connection_t *ssl;
#endif
-diff -r ff3afd1ce6a6 src/core/ngx_core.h
---- a/src/core/ngx_core.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/core/ngx_core.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/core/ngx_core.h
+--- a/src/core/ngx_core.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/core/ngx_core.h Fri Mar 31 00:04:13 2023 -0400
@@ -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;
@@ -959,9 +1085,9 @@ diff -r ff3afd1ce6a6 src/core/ngx_core.h
#define LF (u_char) '\n'
-diff -r ff3afd1ce6a6 src/event/ngx_event.c
---- a/src/event/ngx_event.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/event/ngx_event.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/event/ngx_event.c
+--- a/src/event/ngx_event.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/event/ngx_event.c Fri Mar 31 00:04:13 2023 -0400
@@ -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)
@@ -1018,10 +1144,29 @@ diff -r ff3afd1ce6a6 src/event/ngx_event.c
#if (NGX_HAVE_REUSEPORT)
-diff -r ff3afd1ce6a6 src/event/ngx_event_openssl.c
---- a/src/event/ngx_event_openssl.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/event/ngx_event_openssl.c Tue Jan 31 11:41:14 2023 -0500
-@@ -3202,6 +3202,13 @@ ngx_ssl_shutdown(ngx_connection_t *c)
+diff -r ac779115ed6e src/event/ngx_event_openssl.c
+--- a/src/event/ngx_event_openssl.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/event/ngx_event_openssl.c Fri Mar 31 00:04:13 2023 -0400
+@@ -33,9 +33,6 @@ static int ngx_ssl_new_client_session(ng
+ #ifdef SSL_READ_EARLY_DATA_SUCCESS
+ static ngx_int_t ngx_ssl_try_early_data(ngx_connection_t *c);
+ #endif
+-#if (NGX_DEBUG)
+-static void ngx_ssl_handshake_log(ngx_connection_t *c);
+-#endif
+ static void ngx_ssl_handshake_handler(ngx_event_t *ev);
+ #ifdef SSL_READ_EARLY_DATA_SUCCESS
+ static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf,
+@@ -2052,7 +2049,7 @@ ngx_ssl_try_early_data(ngx_connection_t
+
+ #if (NGX_DEBUG)
+
+-static void
++void
+ ngx_ssl_handshake_log(ngx_connection_t *c)
+ {
+ char buf[129], *s, *d;
+@@ -3202,6 +3199,13 @@ ngx_ssl_shutdown(ngx_connection_t *c)
ngx_err_t err;
ngx_uint_t tries;
@@ -1035,9 +1180,9 @@ diff -r ff3afd1ce6a6 src/event/ngx_event_openssl.c
rc = NGX_OK;
ngx_ssl_ocsp_cleanup(c);
-diff -r ff3afd1ce6a6 src/event/ngx_event_openssl.h
---- a/src/event/ngx_event_openssl.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/event/ngx_event_openssl.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/event/ngx_event_openssl.h
+--- a/src/event/ngx_event_openssl.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/event/ngx_event_openssl.h Fri Mar 31 00:04:13 2023 -0400
@@ -24,6 +24,14 @@
#include <openssl/engine.h>
#endif
@@ -1053,9 +1198,19 @@ diff -r ff3afd1ce6a6 src/event/ngx_event_openssl.h
#include <openssl/hmac.h>
#ifndef OPENSSL_NO_OCSP
#include <openssl/ocsp.h>
-diff -r ff3afd1ce6a6 src/event/ngx_event_udp.c
---- a/src/event/ngx_event_udp.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/event/ngx_event_udp.c Tue Jan 31 11:41:14 2023 -0500
+@@ -302,6 +310,9 @@ ngx_int_t ngx_ssl_get_client_v_remain(ng
+
+
+ ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);
++#if (NGX_DEBUG)
++void ngx_ssl_handshake_log(ngx_connection_t *c);
++#endif
+ ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size);
+ ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size);
+ ssize_t ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl, off_t limit);
+diff -r ac779115ed6e src/event/ngx_event_udp.c
+--- a/src/event/ngx_event_udp.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/event/ngx_event_udp.c Fri Mar 31 00:04:13 2023 -0400
@@ -12,13 +12,6 @@
#if !(NGX_WIN32)
@@ -1070,18 +1225,9 @@ diff -r ff3afd1ce6a6 src/event/ngx_event_udp.c
static void ngx_close_accepted_udp_connection(ngx_connection_t *c);
static ssize_t ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf,
size_t size);
-@@ -88,7 +81,7 @@ ngx_event_recvmsg(ngx_event_t *ev)
- msg.msg_controllen = sizeof(msg_control);
-
- ngx_memzero(&msg_control, sizeof(msg_control));
-- }
-+ }
- #endif
-
- n = recvmsg(lc->fd, &msg, 0);
-diff -r ff3afd1ce6a6 src/event/ngx_event_udp.h
---- a/src/event/ngx_event_udp.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/event/ngx_event_udp.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/event/ngx_event_udp.h
+--- a/src/event/ngx_event_udp.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/event/ngx_event_udp.h Fri Mar 31 00:04:13 2023 -0400
@@ -23,6 +23,13 @@
#endif
@@ -1096,9 +1242,9 @@ diff -r ff3afd1ce6a6 src/event/ngx_event_udp.h
#if (NGX_HAVE_ADDRINFO_CMSG)
typedef union {
-diff -r ff3afd1ce6a6 src/event/quic/bpf/bpfgen.sh
+diff -r ac779115ed6e src/event/quic/bpf/bpfgen.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/bpf/bpfgen.sh Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/bpf/bpfgen.sh Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,113 @@
+#!/bin/bash
+
@@ -1213,9 +1359,9 @@ diff -r ff3afd1ce6a6 src/event/quic/bpf/bpfgen.sh
+process_section
+generate_tail
+
-diff -r ff3afd1ce6a6 src/event/quic/bpf/makefile
+diff -r ac779115ed6e src/event/quic/bpf/makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/bpf/makefile Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/bpf/makefile Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,30 @@
+CFLAGS=-O2 -Wall
+
@@ -1247,9 +1393,9 @@ diff -r ff3afd1ce6a6 src/event/quic/bpf/makefile
+ llvm-objdump -S -no-show-raw-insn $<
+
+.DELETE_ON_ERROR:
-diff -r ff3afd1ce6a6 src/event/quic/bpf/ngx_quic_reuseport_helper.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/bpf/ngx_quic_reuseport_helper.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,140 @@
+#include <errno.h>
+#include <linux/string.h>
@@ -1391,9 +1537,9 @@ diff -r ff3afd1ce6a6 src/event/quic/bpf/ngx_quic_reuseport_helper.c
+ */
+ return SK_PASS;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,1444 @@
+
+/*
@@ -2839,9 +2985,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic.c
+ ngx_quic_finalize_connection(c, qc->shutdown_code, qc->shutdown_reason);
+ }
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,131 @@
+
+/*
@@ -2974,9 +3120,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic.h
+ ngx_str_t *secret, ngx_str_t *salt, u_char *out, size_t len);
+
+#endif /* _NGX_EVENT_QUIC_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ack.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_ack.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,1194 @@
+
+/*
@@ -4172,9 +4318,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ack.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ack.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_ack.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,30 @@
+
+/*
@@ -4206,9 +4352,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ack.h
+ ngx_quic_send_ctx_t *ctx);
+
+#endif /* _NGX_EVENT_QUIC_ACK_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_bpf.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_bpf.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,657 @@
+
+/*
@@ -4867,9 +5013,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_bpf.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_bpf_code.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_bpf_code.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,88 @@
+/* AUTO-GENERATED, DO NOT EDIT. */
+
@@ -4959,10 +5105,10 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_bpf_code.c
+ .license = "BSD",
+ .type = BPF_PROG_TYPE_SK_REUSEPORT,
+};
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_connection.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,276 @@
++++ b/src/event/quic/ngx_event_quic_connection.h Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) Nginx, Inc.
+ */
@@ -4990,6 +5136,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_connection.h
+typedef struct ngx_quic_path_s ngx_quic_path_t;
+typedef struct ngx_quic_keys_s ngx_quic_keys_t;
+
++#if (NGX_QUIC_OPENSSL_COMPAT)
++#include <ngx_event_quic_openssl_compat.h>
++#endif
+#include <ngx_event_quic_transport.h>
+#include <ngx_event_quic_protection.h>
+#include <ngx_event_quic_frames.h>
@@ -5201,6 +5350,10 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_connection.h
+ ngx_uint_t nshadowbufs;
+#endif
+
++#if (NGX_QUIC_OPENSSL_COMPAT)
++ ngx_quic_compat_t *compat;
++#endif
++
+ ngx_quic_streams_t streams;
+ ngx_quic_congestion_t congestion;
+
@@ -5239,9 +5392,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_connection.h
+#endif
+
+#endif /* _NGX_EVENT_QUIC_CONNECTION_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_connid.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_connid.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,502 @@
+
+/*
@@ -5745,9 +5898,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_connid.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_connid.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_connid.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,29 @@
+
+/*
@@ -5778,9 +5931,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_connid.h
+ ngx_quic_client_id_t *cid);
+
+#endif /* _NGX_EVENT_QUIC_CONNID_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_frames.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_frames.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,891 @@
+
+/*
@@ -6673,9 +6826,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_frames.c
+}
+
+#endif
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_frames.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_frames.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,45 @@
+
+/*
@@ -6722,9 +6875,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_frames.h
+#endif
+
+#endif /* _NGX_EVENT_QUIC_FRAMES_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_migration.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_migration.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,671 @@
+
+/*
@@ -7397,9 +7550,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_migration.c
+ ngx_add_timer(&qc->path_validation, next);
+ }
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_migration.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_migration.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,42 @@
+
+/*
@@ -7443,9 +7596,723 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_migration.h
+void ngx_quic_path_validation_handler(ngx_event_t *ev);
+
+#endif /* _NGX_EVENT_QUIC_MIGRATION_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_output.c
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_openssl_compat.c
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/src/event/quic/ngx_event_quic_openssl_compat.c Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,646 @@
++
++/*
++ * Copyright (C) Nginx, Inc.
++ */
++
++
++#include <ngx_config.h>
++#include <ngx_core.h>
++#include <ngx_event.h>
++#include <ngx_event_quic_connection.h>
++
++
++#if (NGX_QUIC_OPENSSL_COMPAT)
++
++#define NGX_QUIC_COMPAT_RECORD_SIZE 1024
++
++#define NGX_QUIC_COMPAT_SSL_TP_EXT 0x39
++
++#define NGX_QUIC_COMPAT_CLIENT_HANDSHAKE "CLIENT_HANDSHAKE_TRAFFIC_SECRET"
++#define NGX_QUIC_COMPAT_SERVER_HANDSHAKE "SERVER_HANDSHAKE_TRAFFIC_SECRET"
++#define NGX_QUIC_COMPAT_CLIENT_APPLICATION "CLIENT_TRAFFIC_SECRET_0"
++#define NGX_QUIC_COMPAT_SERVER_APPLICATION "SERVER_TRAFFIC_SECRET_0"
++
++
++typedef struct {
++ ngx_quic_secret_t secret;
++ ngx_uint_t cipher;
++} ngx_quic_compat_keys_t;
++
++
++typedef struct {
++ ngx_log_t *log;
++
++ u_char type;
++ ngx_str_t payload;
++ uint64_t number;
++ ngx_quic_compat_keys_t *keys;
++
++ enum ssl_encryption_level_t level;
++} ngx_quic_compat_record_t;
++
++
++struct ngx_quic_compat_s {
++ const SSL_QUIC_METHOD *method;
++
++ enum ssl_encryption_level_t write_level;
++ enum ssl_encryption_level_t read_level;
++
++ uint64_t read_record;
++ ngx_quic_compat_keys_t keys;
++
++ ngx_str_t tp;
++ ngx_str_t ctp;
++};
++
++
++static void ngx_quic_compat_keylog_callback(const SSL *ssl, const char *line);
++static ngx_int_t ngx_quic_compat_set_encryption_secret(ngx_log_t *log,
++ ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level,
++ const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len);
++static int ngx_quic_compat_add_transport_params_callback(SSL *ssl,
++ unsigned int ext_type, unsigned int context, const unsigned char **out,
++ size_t *outlen, X509 *x, size_t chainidx, int *al, void *add_arg);
++static int ngx_quic_compat_parse_transport_params_callback(SSL *ssl,
++ unsigned int ext_type, unsigned int context, const unsigned char *in,
++ size_t inlen, X509 *x, size_t chainidx, int *al, void *parse_arg);
++static void ngx_quic_compat_message_callback(int write_p, int version,
++ int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
++static size_t ngx_quic_compat_create_header(ngx_quic_compat_record_t *rec,
++ u_char *out, ngx_uint_t plain);
++static ngx_int_t ngx_quic_compat_create_record(ngx_quic_compat_record_t *rec,
++ ngx_str_t *res);
++
++
++ngx_int_t
++ngx_quic_compat_init(ngx_conf_t *cf, SSL_CTX *ctx)
++{
++ SSL_CTX_set_keylog_callback(ctx, ngx_quic_compat_keylog_callback);
++
++ if (SSL_CTX_has_client_custom_ext(ctx, NGX_QUIC_COMPAT_SSL_TP_EXT)) {
++ return NGX_OK;
++ }
++
++ if (SSL_CTX_add_custom_ext(ctx, NGX_QUIC_COMPAT_SSL_TP_EXT,
++ SSL_EXT_CLIENT_HELLO
++ |SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
++ ngx_quic_compat_add_transport_params_callback,
++ NULL,
++ NULL,
++ ngx_quic_compat_parse_transport_params_callback,
++ NULL)
++ == 0)
++ {
++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
++ "SSL_CTX_add_custom_ext() failed");
++ return NGX_ERROR;
++ }
++
++ return NGX_OK;
++}
++
++
++static void
++ngx_quic_compat_keylog_callback(const SSL *ssl, const char *line)
++{
++ u_char ch, *p, *start, value;
++ size_t n;
++ ngx_uint_t write;
++ const SSL_CIPHER *cipher;
++ ngx_quic_compat_t *com;
++ ngx_connection_t *c;
++ ngx_quic_connection_t *qc;
++ enum ssl_encryption_level_t level;
++ u_char secret[EVP_MAX_MD_SIZE];
++
++ c = ngx_ssl_get_connection(ssl);
++ if (c->type != SOCK_DGRAM) {
++ return;
++ }
++
++ p = (u_char *) line;
++
++ for (start = p; *p && *p != ' '; p++);
++
++ n = p - start;
++
++ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "quic compat secret %*s", n, start);
++
++ if (n == sizeof(NGX_QUIC_COMPAT_CLIENT_HANDSHAKE) - 1
++ && ngx_strncmp(start, NGX_QUIC_COMPAT_CLIENT_HANDSHAKE, n) == 0)
++ {
++ level = ssl_encryption_handshake;
++ write = 0;
++
++ } else if (n == sizeof(NGX_QUIC_COMPAT_SERVER_HANDSHAKE) - 1
++ && ngx_strncmp(start, NGX_QUIC_COMPAT_SERVER_HANDSHAKE, n) == 0)
++ {
++ level = ssl_encryption_handshake;
++ write = 1;
++
++ } else if (n == sizeof(NGX_QUIC_COMPAT_CLIENT_APPLICATION) - 1
++ && ngx_strncmp(start, NGX_QUIC_COMPAT_CLIENT_APPLICATION, n)
++ == 0)
++ {
++ level = ssl_encryption_application;
++ write = 0;
++
++ } else if (n == sizeof(NGX_QUIC_COMPAT_SERVER_APPLICATION) - 1
++ && ngx_strncmp(start, NGX_QUIC_COMPAT_SERVER_APPLICATION, n)
++ == 0)
++ {
++ level = ssl_encryption_application;
++ write = 1;
++
++ } else {
++ return;
++ }
++
++ if (*p++ == '\0') {
++ return;
++ }
++
++ for ( /* void */ ; *p && *p != ' '; p++);
++
++ if (*p++ == '\0') {
++ return;
++ }
++
++ for (n = 0, start = p; *p; p++) {
++ ch = *p;
++
++ if (ch >= '0' && ch <= '9') {
++ value = ch - '0';
++ goto next;
++ }
++
++ ch = (u_char) (ch | 0x20);
++
++ if (ch >= 'a' && ch <= 'f') {
++ value = ch - 'a' + 10;
++ goto next;
++ }
++
++ ngx_log_error(NGX_LOG_EMERG, c->log, 0,
++ "invalid OpenSSL QUIC secret format");
++
++ return;
++
++ next:
++
++ if ((p - start) % 2) {
++ secret[n++] += value;
++
++ } else {
++ if (n >= EVP_MAX_MD_SIZE) {
++ ngx_log_error(NGX_LOG_EMERG, c->log, 0,
++ "too big OpenSSL QUIC secret");
++ return;
++ }
++
++ secret[n] = (value << 4);
++ }
++ }
++
++ qc = ngx_quic_get_connection(c);
++ com = qc->compat;
++ cipher = SSL_get_current_cipher(ssl);
++
++ if (write) {
++ com->method->set_write_secret((SSL *) ssl, level, cipher, secret, n);
++ com->write_level = level;
++
++ } else {
++ com->method->set_read_secret((SSL *) ssl, level, cipher, secret, n);
++ com->read_level = level;
++ com->read_record = 0;
++
++ (void) ngx_quic_compat_set_encryption_secret(c->log, &com->keys, level,
++ cipher, secret, n);
++ }
++}
++
++
++static ngx_int_t
++ngx_quic_compat_set_encryption_secret(ngx_log_t *log,
++ ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level,
++ const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
++{
++ ngx_int_t key_len;
++ ngx_str_t secret_str;
++ ngx_uint_t i;
++ ngx_quic_hkdf_t seq[2];
++ ngx_quic_secret_t *peer_secret;
++ ngx_quic_ciphers_t ciphers;
++
++ peer_secret = &keys->secret;
++
++ keys->cipher = SSL_CIPHER_get_id(cipher);
++
++ key_len = ngx_quic_ciphers(keys->cipher, &ciphers, level);
++
++ if (key_len == NGX_ERROR) {
++ ngx_ssl_error(NGX_LOG_INFO, log, 0, "unexpected cipher");
++ return NGX_ERROR;
++ }
++
++ if (sizeof(peer_secret->secret.data) < secret_len) {
++ ngx_log_error(NGX_LOG_ALERT, log, 0,
++ "unexpected secret len: %uz", secret_len);
++ return NGX_ERROR;
++ }
++
++ peer_secret->secret.len = secret_len;
++ ngx_memcpy(peer_secret->secret.data, secret, secret_len);
++
++ peer_secret->key.len = key_len;
++ peer_secret->iv.len = NGX_QUIC_IV_LEN;
++
++ secret_str.len = secret_len;
++ secret_str.data = (u_char *) secret;
++
++ ngx_quic_hkdf_set(&seq[0], "tls13 key", &peer_secret->key, &secret_str);
++ ngx_quic_hkdf_set(&seq[1], "tls13 iv", &peer_secret->iv, &secret_str);
++
++ for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
++ if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, log) != NGX_OK) {
++ return NGX_ERROR;
++ }
++ }
++
++ return NGX_OK;
++}
++
++
++static int
++ngx_quic_compat_add_transport_params_callback(SSL *ssl, unsigned int ext_type,
++ unsigned int context, const unsigned char **out, size_t *outlen, X509 *x,
++ size_t chainidx, int *al, void *add_arg)
++{
++ ngx_connection_t *c;
++ ngx_quic_compat_t *com;
++ ngx_quic_connection_t *qc;
++
++ c = ngx_ssl_get_connection(ssl);
++ if (c->type != SOCK_DGRAM) {
++ return 0;
++ }
++
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "quic compat add transport params");
++
++ qc = ngx_quic_get_connection(c);
++ com = qc->compat;
++
++ *out = com->tp.data;
++ *outlen = com->tp.len;
++
++ return 1;
++}
++
++
++static int
++ngx_quic_compat_parse_transport_params_callback(SSL *ssl, unsigned int ext_type,
++ unsigned int context, const unsigned char *in, size_t inlen, X509 *x,
++ size_t chainidx, int *al, void *parse_arg)
++{
++ u_char *p;
++ ngx_connection_t *c;
++ ngx_quic_compat_t *com;
++ ngx_quic_connection_t *qc;
++
++ c = ngx_ssl_get_connection(ssl);
++ if (c->type != SOCK_DGRAM) {
++ return 0;
++ }
++
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "quic compat parse transport params");
++
++ qc = ngx_quic_get_connection(c);
++ com = qc->compat;
++
++ p = ngx_pnalloc(c->pool, inlen);
++ if (p == NULL) {
++ return 0;
++ }
++
++ ngx_memcpy(p, in, inlen);
++
++ com->ctp.data = p;
++ com->ctp.len = inlen;
++
++ return 1;
++}
++
++
++int
++SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method)
++{
++ BIO *rbio, *wbio;
++ ngx_connection_t *c;
++ ngx_quic_compat_t *com;
++ ngx_quic_connection_t *qc;
++
++ c = ngx_ssl_get_connection(ssl);
++
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic compat set method");
++
++ qc = ngx_quic_get_connection(c);
++
++ qc->compat = ngx_pcalloc(c->pool, sizeof(ngx_quic_compat_t));
++ if (qc->compat == NULL) {
++ return 0;
++ }
++
++ com = qc->compat;
++ com->method = quic_method;
++
++ rbio = BIO_new(BIO_s_mem());
++ if (rbio == NULL) {
++ return 0;
++ }
++
++ wbio = BIO_new(BIO_s_null());
++ if (wbio == NULL) {
++ return 0;
++ }
++
++ SSL_set_bio(ssl, rbio, wbio);
++
++ SSL_set_msg_callback(ssl, ngx_quic_compat_message_callback);
++
++ /* early data is not supported */
++ SSL_set_max_early_data(ssl, 0);
++
++ return 1;
++}
++
++
++static void
++ngx_quic_compat_message_callback(int write_p, int version, int content_type,
++ const void *buf, size_t len, SSL *ssl, void *arg)
++{
++ ngx_uint_t alert;
++ ngx_connection_t *c;
++ ngx_quic_compat_t *com;
++ ngx_quic_connection_t *qc;
++ enum ssl_encryption_level_t level;
++
++ if (!write_p) {
++ return;
++ }
++
++ c = ngx_ssl_get_connection(ssl);
++ qc = ngx_quic_get_connection(c);
++
++ if (qc == NULL) {
++ /* closing */
++ return;
++ }
++
++ com = qc->compat;
++ level = com->write_level;
++
++ switch (content_type) {
++
++ case SSL3_RT_HANDSHAKE:
++ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "quic compat tx %s len:%uz ",
++ ngx_quic_level_name(level), len);
++
++ (void) com->method->add_handshake_data(ssl, level, buf, len);
++
++ break;
++
++ case SSL3_RT_ALERT:
++ if (len >= 2) {
++ alert = ((u_char *) buf)[1];
++
++ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "quic compat %s alert:%ui len:%uz ",
++ ngx_quic_level_name(level), alert, len);
++
++ (void) com->method->send_alert(ssl, level, alert);
++ }
++
++ break;
++ }
++}
++
++
++int
++SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level,
++ const uint8_t *data, size_t len)
++{
++ BIO *rbio;
++ size_t n;
++ u_char *p;
++ ngx_str_t res;
++ ngx_connection_t *c;
++ ngx_quic_compat_t *com;
++ ngx_quic_connection_t *qc;
++ ngx_quic_compat_record_t rec;
++ u_char in[NGX_QUIC_COMPAT_RECORD_SIZE + 1];
++ u_char out[NGX_QUIC_COMPAT_RECORD_SIZE + 1
++ + SSL3_RT_HEADER_LENGTH
++ + EVP_GCM_TLS_TAG_LEN];
++
++ c = ngx_ssl_get_connection(ssl);
++
++ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic compat rx %s len:%uz",
++ ngx_quic_level_name(level), len);
++
++ qc = ngx_quic_get_connection(c);
++ com = qc->compat;
++ rbio = SSL_get_rbio(ssl);
++
++ while (len) {
++ ngx_memzero(&rec, sizeof(ngx_quic_compat_record_t));
++
++ rec.type = SSL3_RT_HANDSHAKE;
++ rec.log = c->log;
++ rec.number = com->read_record++;
++ rec.keys = &com->keys;
++
++ if (level == ssl_encryption_initial) {
++ n = ngx_min(len, 65535);
++
++ rec.payload.len = n;
++ rec.payload.data = (u_char *) data;
++
++ ngx_quic_compat_create_header(&rec, out, 1);
++
++ BIO_write(rbio, out, SSL3_RT_HEADER_LENGTH);
++ BIO_write(rbio, data, n);
++
++#if defined(NGX_QUIC_DEBUG_CRYPTO) && defined(NGX_QUIC_DEBUG_PACKETS)
++ ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "quic compat record len:%uz %*xs%*xs",
++ n + SSL3_RT_HEADER_LENGTH,
++ (size_t) SSL3_RT_HEADER_LENGTH, out, n, data);
++#endif
++
++ } else {
++ n = ngx_min(len, NGX_QUIC_COMPAT_RECORD_SIZE);
++
++ p = ngx_cpymem(in, data, n);
++ *p++ = SSL3_RT_HANDSHAKE;
++
++ rec.payload.len = p - in;
++ rec.payload.data = in;
++
++ res.data = out;
++
++ if (ngx_quic_compat_create_record(&rec, &res) != NGX_OK) {
++ return 0;
++ }
++
++#if defined(NGX_QUIC_DEBUG_CRYPTO) && defined(NGX_QUIC_DEBUG_PACKETS)
++ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "quic compat record len:%uz %xV", res.len, &res);
++#endif
++
++ BIO_write(rbio, res.data, res.len);
++ }
++
++ data += n;
++ len -= n;
++ }
++
++ return 1;
++}
++
++
++static size_t
++ngx_quic_compat_create_header(ngx_quic_compat_record_t *rec, u_char *out,
++ ngx_uint_t plain)
++{
++ u_char type;
++ size_t len;
++
++ len = rec->payload.len;
++
++ if (plain) {
++ type = rec->type;
++
++ } else {
++ type = SSL3_RT_APPLICATION_DATA;
++ len += EVP_GCM_TLS_TAG_LEN;
++ }
++
++ out[0] = type;
++ out[1] = 0x03;
++ out[2] = 0x03;
++ out[3] = (len >> 8);
++ out[4] = len;
++
++ return 5;
++}
++
++
++static ngx_int_t
++ngx_quic_compat_create_record(ngx_quic_compat_record_t *rec, ngx_str_t *res)
++{
++ ngx_str_t ad, out;
++ ngx_quic_secret_t *secret;
++ ngx_quic_ciphers_t ciphers;
++ u_char nonce[NGX_QUIC_IV_LEN];
++
++ ad.data = res->data;
++ ad.len = ngx_quic_compat_create_header(rec, ad.data, 0);
++
++ out.len = rec->payload.len + EVP_GCM_TLS_TAG_LEN;
++ out.data = res->data + ad.len;
++
++#ifdef NGX_QUIC_DEBUG_CRYPTO
++ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, rec->log, 0,
++ "quic compat ad len:%uz %xV", ad.len, &ad);
++#endif
++
++ if (ngx_quic_ciphers(rec->keys->cipher, &ciphers, rec->level) == NGX_ERROR)
++ {
++ return NGX_ERROR;
++ }
++
++ secret = &rec->keys->secret;
++
++ ngx_memcpy(nonce, secret->iv.data, secret->iv.len);
++ ngx_quic_compute_nonce(nonce, sizeof(nonce), rec->number);
++
++ if (ngx_quic_tls_seal(ciphers.c, secret, &out,
++ nonce, &rec->payload, &ad, rec->log)
++ != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
++
++ res->len = ad.len + out.len;
++
++ return NGX_OK;
++}
++
++
++enum ssl_encryption_level_t
++SSL_quic_read_level(const SSL *ssl)
++{
++ ngx_connection_t *c;
++ ngx_quic_connection_t *qc;
++
++ c = ngx_ssl_get_connection(ssl);
++ qc = ngx_quic_get_connection(c);
++
++ return qc->compat->read_level;
++}
++
++
++enum ssl_encryption_level_t
++SSL_quic_write_level(const SSL *ssl)
++{
++ ngx_connection_t *c;
++ ngx_quic_connection_t *qc;
++
++ c = ngx_ssl_get_connection(ssl);
++ qc = ngx_quic_get_connection(c);
++
++ return qc->compat->write_level;
++}
++
++
++int
++SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params,
++ size_t params_len)
++{
++ ngx_connection_t *c;
++ ngx_quic_compat_t *com;
++ ngx_quic_connection_t *qc;
++
++ c = ngx_ssl_get_connection(ssl);
++ qc = ngx_quic_get_connection(c);
++ com = qc->compat;
++
++ com->tp.len = params_len;
++ com->tp.data = (u_char *) params;
++
++ return 1;
++}
++
++
++void
++SSL_get_peer_quic_transport_params(const SSL *ssl, const uint8_t **out_params,
++ size_t *out_params_len)
++{
++ ngx_connection_t *c;
++ ngx_quic_compat_t *com;
++ ngx_quic_connection_t *qc;
++
++ c = ngx_ssl_get_connection(ssl);
++ qc = ngx_quic_get_connection(c);
++ com = qc->compat;
++
++ *out_params = com->ctp.data;
++ *out_params_len = com->ctp.len;
++}
++
++#endif /* NGX_QUIC_OPENSSL_COMPAT */
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_openssl_compat.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_output.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_openssl_compat.h Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,60 @@
++
++/*
++ * Copyright (C) Nginx, Inc.
++ */
++
++
++#ifndef _NGX_EVENT_QUIC_OPENSSL_COMPAT_H_INCLUDED_
++#define _NGX_EVENT_QUIC_OPENSSL_COMPAT_H_INCLUDED_
++
++#ifdef TLSEXT_TYPE_quic_transport_parameters
++#undef NGX_QUIC_OPENSSL_COMPAT
++#else
++
++
++#include <ngx_config.h>
++#include <ngx_core.h>
++
++
++typedef struct ngx_quic_compat_s ngx_quic_compat_t;
++
++
++enum ssl_encryption_level_t {
++ ssl_encryption_initial = 0,
++ ssl_encryption_early_data,
++ ssl_encryption_handshake,
++ ssl_encryption_application
++};
++
++
++typedef struct ssl_quic_method_st {
++ int (*set_read_secret)(SSL *ssl, enum ssl_encryption_level_t level,
++ const SSL_CIPHER *cipher,
++ const uint8_t *rsecret, size_t secret_len);
++ int (*set_write_secret)(SSL *ssl, enum ssl_encryption_level_t level,
++ const SSL_CIPHER *cipher,
++ const uint8_t *wsecret, size_t secret_len);
++ int (*add_handshake_data)(SSL *ssl, enum ssl_encryption_level_t level,
++ const uint8_t *data, size_t len);
++ int (*flush_flight)(SSL *ssl);
++ int (*send_alert)(SSL *ssl, enum ssl_encryption_level_t level,
++ uint8_t alert);
++} SSL_QUIC_METHOD;
++
++
++ngx_int_t ngx_quic_compat_init(ngx_conf_t *cf, SSL_CTX *ctx);
++
++int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method);
++int SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level,
++ const uint8_t *data, size_t len);
++enum ssl_encryption_level_t SSL_quic_read_level(const SSL *ssl);
++enum ssl_encryption_level_t SSL_quic_write_level(const SSL *ssl);
++int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params,
++ size_t params_len);
++void SSL_get_peer_quic_transport_params(const SSL *ssl,
++ const uint8_t **out_params, size_t *out_params_len);
++
++
++#endif /* TLSEXT_TYPE_quic_transport_parameters */
++
++#endif /* _NGX_EVENT_QUIC_OPENSSL_COMPAT_H_INCLUDED_ */
+diff -r ac779115ed6e 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 Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,1298 @@
+
+/*
@@ -8093,7 +8960,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_output.c
+ if (len < min_payload) {
+ ngx_memset(p, NGX_QUIC_FT_PADDING, min_payload - len);
+ len = min_payload;
-+ }
++ }
+
+ pkt.payload.data = src;
+ pkt.payload.len = len;
@@ -8703,7 +9570,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_output.c
+ if (len < (ssize_t) min_payload) {
+ ngx_memset(src + len, NGX_QUIC_FT_PADDING, min_payload - len);
+ len = min_payload;
-+ }
++ }
+
+ pkt.payload.data = src;
+ pkt.payload.len = len;
@@ -8745,9 +9612,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_output.c
+
+ return size;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_output.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_output.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,40 @@
+
+/*
@@ -8789,10 +9656,10 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_output.h
+ size_t min, ngx_quic_path_t *path);
+
+#endif /* _NGX_EVENT_QUIC_OUTPUT_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,1126 @@
++++ b/src/event/quic/ngx_event_quic_protection.c Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,1087 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
@@ -8818,37 +9685,6 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.c
+#endif
+
+
-+#ifdef OPENSSL_IS_BORINGSSL
-+#define ngx_quic_cipher_t EVP_AEAD
-+#else
-+#define ngx_quic_cipher_t EVP_CIPHER
-+#endif
-+
-+
-+typedef struct {
-+ const ngx_quic_cipher_t *c;
-+ const EVP_CIPHER *hp;
-+ const EVP_MD *d;
-+} ngx_quic_ciphers_t;
-+
-+
-+typedef struct {
-+ size_t out_len;
-+ u_char *out;
-+
-+ size_t prk_len;
-+ const uint8_t *prk;
-+
-+ size_t label_len;
-+ const u_char *label;
-+} ngx_quic_hkdf_t;
-+
-+#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,
+ const EVP_MD *digest, const u_char *prk, size_t prk_len,
+ const u_char *info, size_t info_len);
@@ -8858,20 +9694,12 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.c
+
+static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
+ uint64_t *largest_pn);
-+static void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn);
-+static ngx_int_t ngx_quic_ciphers(ngx_uint_t id,
-+ ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level);
+
+static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher,
+ ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
+ ngx_str_t *ad, ngx_log_t *log);
-+static ngx_int_t ngx_quic_tls_seal(const ngx_quic_cipher_t *cipher,
-+ ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
-+ ngx_str_t *ad, ngx_log_t *log);
+static ngx_int_t ngx_quic_tls_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
+ ngx_quic_secret_t *s, u_char *out, u_char *in);
-+static ngx_int_t ngx_quic_hkdf_expand(ngx_quic_hkdf_t *hkdf,
-+ const EVP_MD *digest, ngx_log_t *log);
+
+static ngx_int_t ngx_quic_create_packet(ngx_quic_header_t *pkt,
+ ngx_str_t *res);
@@ -8879,7 +9707,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.c
+ ngx_str_t *res);
+
+
-+static ngx_int_t
++ngx_int_t
+ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers,
+ enum ssl_encryption_level_t level)
+{
@@ -9016,7 +9844,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.c
+}
+
+
-+static ngx_int_t
++ngx_int_t
+ngx_quic_hkdf_expand(ngx_quic_hkdf_t *h, const EVP_MD *digest, ngx_log_t *log)
+{
+ size_t info_len;
@@ -9275,7 +10103,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.c
+}
+
+
-+static ngx_int_t
++ngx_int_t
+ngx_quic_tls_seal(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s,
+ ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
+{
@@ -9756,7 +10584,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.c
+}
+
+
-+static void
++void
+ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn)
+{
+ nonce[len - 8] ^= (pn >> 56) & 0x3f;
@@ -9919,10 +10747,10 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,75 @@
++++ b/src/event/quic/ngx_event_quic_protection.h Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,114 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
@@ -9948,6 +10776,13 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.h
+#define NGX_QUIC_MAX_MD_SIZE 48
+
+
++#ifdef OPENSSL_IS_BORINGSSL
++#define ngx_quic_cipher_t EVP_AEAD
++#else
++#define ngx_quic_cipher_t EVP_CIPHER
++#endif
++
++
+typedef struct {
+ size_t len;
+ u_char data[NGX_QUIC_MAX_MD_SIZE];
@@ -9981,6 +10816,30 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.h
+};
+
+
++typedef struct {
++ const ngx_quic_cipher_t *c;
++ const EVP_CIPHER *hp;
++ const EVP_MD *d;
++} ngx_quic_ciphers_t;
++
++
++typedef struct {
++ size_t out_len;
++ u_char *out;
++
++ size_t prk_len;
++ const uint8_t *prk;
++
++ size_t label_len;
++ const u_char *label;
++} ngx_quic_hkdf_t;
++
++#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);
++
++
+ngx_int_t ngx_quic_keys_set_initial_secret(ngx_quic_keys_t *keys,
+ ngx_str_t *secret, ngx_log_t *log);
+ngx_int_t ngx_quic_keys_set_encryption_secret(ngx_log_t *log,
@@ -9995,12 +10854,20 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_protection.h
+ngx_int_t ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys);
+ngx_int_t ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_str_t *res);
+ngx_int_t ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn);
++void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn);
++ngx_int_t ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers,
++ enum ssl_encryption_level_t level);
++ngx_int_t ngx_quic_tls_seal(const ngx_quic_cipher_t *cipher,
++ ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
++ ngx_str_t *ad, ngx_log_t *log);
++ngx_int_t ngx_quic_hkdf_expand(ngx_quic_hkdf_t *hkdf, const EVP_MD *digest,
++ ngx_log_t *log);
+
+
+#endif /* _NGX_EVENT_QUIC_PROTECTION_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_socket.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_socket.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,237 @@
+
+/*
@@ -10239,9 +11106,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_socket.c
+
+ return NULL;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_socket.h
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_socket.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,28 @@
+
+/*
@@ -10271,10 +11138,10 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_socket.h
+
+
+#endif /* _NGX_EVENT_QUIC_SOCKET_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+diff -r ac779115ed6e 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 Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,587 @@
++++ b/src/event/quic/ngx_event_quic_ssl.c Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,600 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
@@ -10287,6 +11154,13 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+#include <ngx_event_quic_connection.h>
+
+
++#if defined OPENSSL_IS_BORINGSSL \
++ || defined LIBRESSL_VERSION_NUMBER \
++ || NGX_QUIC_OPENSSL_COMPAT
++#define NGX_QUIC_BORINGSSL_API 1
++#endif
++
++
+/*
+ * RFC 9000, 7.5. Cryptographic Message Buffering
+ *
@@ -10295,7 +11169,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+#define NGX_QUIC_MAX_BUFFERED 65535
+
+
-+#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
++#if (NGX_QUIC_BORINGSSL_API)
+static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
+ enum ssl_encryption_level_t level, const SSL_CIPHER *cipher,
+ const uint8_t *secret, size_t secret_len);
@@ -10316,7 +11190,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+static ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data);
+
+
-+#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
++#if (NGX_QUIC_BORINGSSL_API)
+
+static int
+ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
@@ -10467,7 +11341,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+ SSL_get0_alpn_selected(ssl_conn, &alpn_data, &alpn_len);
+
+ if (alpn_len == 0) {
-+ qc->error = 0x100 + SSL_AD_NO_APPLICATION_PROTOCOL;
++ qc->error = NGX_QUIC_ERR_CRYPTO(SSL_AD_NO_APPLICATION_PROTOCOL);
+ qc->error_reason = "unsupported protocol in ALPN extension";
+
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
@@ -10578,6 +11452,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+ }
+
+ qc->error = NGX_QUIC_ERR_CRYPTO(alert);
++ qc->error_reason = "handshake failed";
+
+ return 1;
+}
@@ -10699,8 +11574,15 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+ sslerr);
+
+ if (sslerr != SSL_ERROR_WANT_READ) {
++
++ if (c->ssl->handshake_rejected) {
++ ngx_connection_error(c, 0, "handshake rejected");
++ ERR_clear_error();
++
++ return NGX_ERROR;
++ }
++
+ ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "SSL_do_handshake() failed");
-+ qc->error_reason = "handshake failed";
+ return NGX_ERROR;
+ }
+ }
@@ -10717,11 +11599,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+ return NGX_OK;
+ }
+
-+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-+ "quic ssl cipher:%s", SSL_get_cipher(ssl_conn));
-+
-+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
-+ "quic handshake completed successfully");
++#if (NGX_DEBUG)
++ ngx_ssl_handshake_log(c);
++#endif
+
+ c->ssl->handshaked = 1;
+
@@ -10794,7 +11674,7 @@ diff -r ff3afd1ce6a6 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
++#if (NGX_QUIC_BORINGSSL_API)
+ quic_method.set_read_secret = ngx_quic_set_read_secret;
+ quic_method.set_write_secret = ngx_quic_set_write_secret;
+#else
@@ -10862,9 +11742,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.h
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_ssl.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_ssl.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_ssl.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,19 @@
+
+/*
@@ -10885,9 +11765,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_ssl.h
+ ngx_quic_header_t *pkt, ngx_quic_frame_t *frame);
+
+#endif /* _NGX_EVENT_QUIC_SSL_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_streams.c
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_streams.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_streams.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_streams.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,1768 @@
+
+/*
@@ -12053,7 +12933,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_streams.c
+ return NGX_DECLINED;
+ }
+ }
-+ }
++ }
+
+ return NGX_OK;
+}
@@ -12657,9 +13537,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_streams.c
+ ngx_post_event(ev, &ngx_posted_events);
+ }
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_streams.h
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_streams.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_streams.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_streams.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,44 @@
+
+/*
@@ -12705,9 +13585,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_streams.h
+ ngx_quic_connection_t *qc);
+
+#endif /* _NGX_EVENT_QUIC_STREAMS_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_tokens.c
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_tokens.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_tokens.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_tokens.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,289 @@
+
+/*
@@ -12998,9 +13878,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_tokens.c
+
+ return NGX_DECLINED;
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_tokens.h
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_tokens.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_tokens.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_tokens.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,35 @@
+
+/*
@@ -13037,9 +13917,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_tokens.h
+ u_char *key, ngx_quic_header_t *pkt);
+
+#endif /* _NGX_EVENT_QUIC_TOKENS_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_transport.c
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_transport.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_transport.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_transport.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,2199 @@
+
+/*
@@ -13619,7 +14499,7 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_transport.c
+{
+ size_t len;
+
-+ if ngx_quic_short_pkt(pkt->flags) {
++ if (ngx_quic_short_pkt(pkt->flags)) {
+
+ len = 1 + pkt->dcid.len + pkt->num_len + EVP_GCM_TLS_TAG_LEN;
+ if (len > pkt_len) {
@@ -15240,9 +16120,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_transport.c
+{
+ (void) ngx_quic_write_uint64(dcid, key);
+}
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_transport.h
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_transport.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_transport.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_transport.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,397 @@
+
+/*
@@ -15641,9 +16521,9 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_transport.h
+void ngx_quic_dcid_encode_key(u_char *dcid, uint64_t key);
+
+#endif /* _NGX_EVENT_QUIC_TRANSPORT_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_udp.c
+diff -r ac779115ed6e src/event/quic/ngx_event_quic_udp.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/event/quic/ngx_event_quic_udp.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/event/quic/ngx_event_quic_udp.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,473 @@
+
+/*
@@ -16118,10 +16998,32 @@ diff -r ff3afd1ce6a6 src/event/quic/ngx_event_quic_udp.c
+
+ return NULL;
+}
-diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
---- a/src/http/modules/ngx_http_ssl_module.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/modules/ngx_http_ssl_module.c Tue Jan 31 11:41:14 2023 -0500
-@@ -419,16 +419,19 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t
+diff -r ac779115ed6e src/http/modules/ngx_http_ssl_module.c
+--- a/src/http/modules/ngx_http_ssl_module.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/modules/ngx_http_ssl_module.c Fri Mar 31 00:04:13 2023 -0400
+@@ -9,6 +9,10 @@
+ #include <ngx_core.h>
+ #include <ngx_http.h>
+
++#if (NGX_QUIC_OPENSSL_COMPAT)
++#include <ngx_event_quic_openssl_compat.h>
++#endif
++
+
+ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
+ ngx_pool_t *pool, ngx_str_t *s);
+@@ -52,6 +56,10 @@ static char *ngx_http_ssl_conf_command_c
+ void *data);
+
+ static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
++#if (NGX_QUIC_OPENSSL_COMPAT)
++static ngx_int_t ngx_http_ssl_quic_compat_init(ngx_conf_t *cf,
++ ngx_http_conf_addr_t *addr);
++#endif
+
+
+ static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
+@@ -419,16 +427,19 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t
unsigned char *outlen, const unsigned char *in, unsigned int inlen,
void *arg)
{
@@ -16140,7 +17042,7 @@ diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
#endif
-#if (NGX_HTTP_V2 || NGX_DEBUG)
- ngx_connection_t *c;
-+#if (NGX_HTTP_V3 && NGX_HTTP_V3_HQ)
++#if (NGX_HTTP_V3)
+ ngx_http_v3_srv_conf_t *h3scf;
+#endif
+#if (NGX_HTTP_V2 || NGX_HTTP_V3 || NGX_DEBUG)
@@ -16148,7 +17050,7 @@ diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
c = ngx_ssl_get_connection(ssl_conn);
#endif
-@@ -441,14 +444,34 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t
+@@ -441,14 +452,41 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t
}
#endif
@@ -16164,19 +17066,26 @@ diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
} else
#endif
+#if (NGX_HTTP_V3)
-+ if (hc->addr_conf->http3) {
++ if (hc->addr_conf->quic) {
+
-+#if (NGX_HTTP_V3_HQ)
+ h3scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v3_module);
+
-+ if (h3scf->hq) {
++ if (h3scf->enable && h3scf->enable_hq) {
++ srv = (unsigned char *) NGX_HTTP_V3_ALPN_PROTO
++ NGX_HTTP_V3_HQ_ALPN_PROTO;
++ srvlen = sizeof(NGX_HTTP_V3_ALPN_PROTO NGX_HTTP_V3_HQ_ALPN_PROTO)
++ - 1;
++
++ } else if (h3scf->enable_hq) {
+ srv = (unsigned char *) NGX_HTTP_V3_HQ_ALPN_PROTO;
+ srvlen = sizeof(NGX_HTTP_V3_HQ_ALPN_PROTO) - 1;
-+ } else
-+#endif
-+ {
++
++ } else if (h3scf->enable || hc->addr_conf->http3) {
+ srv = (unsigned char *) NGX_HTTP_V3_ALPN_PROTO;
+ srvlen = sizeof(NGX_HTTP_V3_ALPN_PROTO) - 1;
++
++ } else {
++ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+
+ } else
@@ -16184,7 +17093,7 @@ diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
{
srv = (unsigned char *) NGX_HTTP_ALPN_PROTOS;
srvlen = sizeof(NGX_HTTP_ALPN_PROTOS) - 1;
-@@ -1240,6 +1263,7 @@ static ngx_int_t
+@@ -1241,6 +1279,7 @@ static ngx_int_t
ngx_http_ssl_init(ngx_conf_t *cf)
{
ngx_uint_t a, p, s;
@@ -16192,17 +17101,23 @@ diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
ngx_http_conf_addr_t *addr;
ngx_http_conf_port_t *port;
ngx_http_ssl_srv_conf_t *sscf;
-@@ -1289,22 +1313,38 @@ ngx_http_ssl_init(ngx_conf_t *cf)
+@@ -1290,22 +1329,44 @@ ngx_http_ssl_init(ngx_conf_t *cf)
addr = port[p].addrs.elts;
for (a = 0; a < port[p].addrs.nelts; a++) {
- if (!addr[a].opt.ssl) {
-+ if (!addr[a].opt.ssl && !addr[a].opt.http3) {
++ if (!addr[a].opt.ssl && !addr[a].opt.quic) {
continue;
}
-+ if (addr[a].opt.http3) {
-+ name = "http3";
++ if (addr[a].opt.quic) {
++ name = "quic";
++
++#if (NGX_QUIC_OPENSSL_COMPAT)
++ if (ngx_http_ssl_quic_compat_init(cf, &addr[a]) != NGX_OK) {
++ return NGX_ERROR;
++ }
++#endif
+
+ } else {
+ name = "ssl";
@@ -16213,7 +17128,7 @@ diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
if (sscf->certificates) {
+
-+ if (addr[a].opt.http3 && !(sscf->protocols & NGX_SSL_TLSv1_3)) {
++ if (addr[a].opt.quic && !(sscf->protocols & NGX_SSL_TLSv1_3)) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "\"ssl_protocols\" must enable TLSv1.3 for "
+ "the \"listen ... %s\" directive in %s:%ui",
@@ -16234,7 +17149,7 @@ diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
return NGX_ERROR;
}
-@@ -1325,8 +1365,8 @@ ngx_http_ssl_init(ngx_conf_t *cf)
+@@ -1326,8 +1387,8 @@ ngx_http_ssl_init(ngx_conf_t *cf)
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"ssl_certificate\" is defined for "
@@ -16245,9 +17160,41 @@ diff -r ff3afd1ce6a6 src/http/modules/ngx_http_ssl_module.c
return NGX_ERROR;
}
}
-diff -r ff3afd1ce6a6 src/http/ngx_http.c
---- a/src/http/ngx_http.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http.c Tue Jan 31 11:41:14 2023 -0500
+@@ -1335,3 +1396,31 @@ ngx_http_ssl_init(ngx_conf_t *cf)
+
+ return NGX_OK;
+ }
++
++
++#if (NGX_QUIC_OPENSSL_COMPAT)
++
++static ngx_int_t
++ngx_http_ssl_quic_compat_init(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
++{
++ ngx_uint_t s;
++ ngx_http_ssl_srv_conf_t *sscf;
++ ngx_http_core_srv_conf_t **cscfp, *cscf;
++
++ cscfp = addr->servers.elts;
++ for (s = 0; s < addr->servers.nelts; s++) {
++
++ cscf = cscfp[s];
++ sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
++
++ if (sscf->certificates || sscf->reject_handshake) {
++ if (ngx_quic_compat_init(cf, sscf->ssl.ctx) != NGX_OK) {
++ return NGX_ERROR;
++ }
++ }
++ }
++
++ return NGX_OK;
++}
++
++#endif
+diff -r ac779115ed6e src/http/ngx_http.c
+--- a/src/http/ngx_http.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http.c Fri Mar 31 00:04:13 2023 -0400
@@ -1200,7 +1200,10 @@ ngx_http_add_listen(ngx_conf_t *cf, ngx_
port = cmcf->ports->elts;
for (i = 0; i < cmcf->ports->nelts; i++) {
@@ -16268,37 +17215,40 @@ diff -r ff3afd1ce6a6 src/http/ngx_http.c
port->port = p;
port->addrs.elts = NULL;
-@@ -1236,6 +1240,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
+@@ -1237,6 +1241,10 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
#if (NGX_HTTP_V2)
ngx_uint_t http2;
#endif
+#if (NGX_HTTP_V3)
+ ngx_uint_t http3;
++ ngx_uint_t quic;
+#endif
/*
* we cannot compare whole sockaddr struct's as kernel
-@@ -1271,6 +1278,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
- #if (NGX_HTTP_V2)
- http2 = lsopt->http2 || addr[i].opt.http2;
+@@ -1278,6 +1286,10 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
+ protocols |= lsopt->http2 << 2;
+ protocols_prev |= addr[i].opt.http2 << 2;
#endif
+#if (NGX_HTTP_V3)
+ http3 = lsopt->http3 || addr[i].opt.http3;
++ quic = lsopt->quic || addr[i].opt.quic;
+#endif
if (lsopt->set) {
-@@ -1307,6 +1317,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
+@@ -1365,6 +1377,10 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
#if (NGX_HTTP_V2)
addr[i].opt.http2 = http2;
#endif
+#if (NGX_HTTP_V3)
+ addr[i].opt.http3 = http3;
++ addr[i].opt.quic = quic;
+#endif
return NGX_OK;
}
-@@ -1770,6 +1783,7 @@ ngx_http_add_listening(ngx_conf_t *cf, n
+@@ -1831,6 +1847,7 @@ ngx_http_add_listening(ngx_conf_t *cf, n
}
#endif
@@ -16306,7 +17256,7 @@ diff -r ff3afd1ce6a6 src/http/ngx_http.c
ls->backlog = addr->opt.backlog;
ls->rcvbuf = addr->opt.rcvbuf;
ls->sndbuf = addr->opt.sndbuf;
-@@ -1805,6 +1819,19 @@ ngx_http_add_listening(ngx_conf_t *cf, n
+@@ -1866,6 +1883,19 @@ ngx_http_add_listening(ngx_conf_t *cf, n
ls->reuseport = addr->opt.reuseport;
#endif
@@ -16314,7 +17264,7 @@ diff -r ff3afd1ce6a6 src/http/ngx_http.c
+
+#if (NGX_HTTP_V3)
+
-+ ls->quic = addr->opt.http3;
++ ls->quic = addr->opt.quic;
+
+ if (ls->quic) {
+ ngx_rbtree_init(&ls->rbtree, &ls->sentinel,
@@ -16326,29 +17276,31 @@ diff -r ff3afd1ce6a6 src/http/ngx_http.c
return ls;
}
-@@ -1837,6 +1864,9 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h
+@@ -1898,6 +1928,10 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h
#if (NGX_HTTP_V2)
addrs[i].conf.http2 = addr[i].opt.http2;
#endif
+#if (NGX_HTTP_V3)
+ addrs[i].conf.http3 = addr[i].opt.http3;
++ addrs[i].conf.quic = addr[i].opt.quic;
+#endif
addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
if (addr[i].hash.buckets == NULL
-@@ -1902,6 +1932,9 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_
+@@ -1963,6 +1997,10 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_
#if (NGX_HTTP_V2)
addrs6[i].conf.http2 = addr[i].opt.http2;
#endif
+#if (NGX_HTTP_V3)
+ addrs6[i].conf.http3 = addr[i].opt.http3;
++ addrs6[i].conf.quic = addr[i].opt.quic;
+#endif
addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
if (addr[i].hash.buckets == NULL
-diff -r ff3afd1ce6a6 src/http/ngx_http.h
---- a/src/http/ngx_http.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/http/ngx_http.h
+--- a/src/http/ngx_http.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http.h Fri Mar 31 00:04:13 2023 -0400
@@ -20,6 +20,8 @@ typedef struct ngx_http_file_cache_s ng
typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t;
typedef struct ngx_http_chunked_s ngx_http_chunked_t;
@@ -16389,10 +17341,10 @@ diff -r ff3afd1ce6a6 src/http/ngx_http.h
ngx_int_t ngx_http_huff_decode(u_char *state, u_char *src, size_t len,
u_char **dst, ngx_uint_t last, ngx_log_t *log);
size_t ngx_http_huff_encode(u_char *src, size_t len, u_char *dst,
-diff -r ff3afd1ce6a6 src/http/ngx_http_core_module.c
---- a/src/http/ngx_http_core_module.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http_core_module.c Tue Jan 31 11:41:14 2023 -0500
-@@ -3008,6 +3008,7 @@ ngx_http_core_server(ngx_conf_t *cf, ngx
+diff -r ac779115ed6e src/http/ngx_http_core_module.c
+--- a/src/http/ngx_http_core_module.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http_core_module.c Fri Mar 31 00:04:13 2023 -0400
+@@ -3005,6 +3005,7 @@ ngx_http_core_server(ngx_conf_t *cf, ngx
lsopt.socklen = sizeof(struct sockaddr_in);
lsopt.backlog = NGX_LISTEN_BACKLOG;
@@ -16400,7 +17352,7 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_core_module.c
lsopt.rcvbuf = -1;
lsopt.sndbuf = -1;
#if (NGX_HAVE_SETFIB)
-@@ -3989,6 +3990,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
+@@ -3986,6 +3987,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
lsopt.backlog = NGX_LISTEN_BACKLOG;
@@ -16408,12 +17360,16 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_core_module.c
lsopt.rcvbuf = -1;
lsopt.sndbuf = -1;
#if (NGX_HAVE_SETFIB)
-@@ -4187,6 +4189,19 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
+@@ -4184,6 +4186,36 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
#endif
}
+ if (ngx_strcmp(value[n].data, "http3") == 0) {
+#if (NGX_HTTP_V3)
++ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
++ "the \"http3\" parameter is deprecated, "
++ "use \"quic\" parameter instead");
++ lsopt.quic = 1;
+ lsopt.http3 = 1;
+ lsopt.type = SOCK_DGRAM;
+ continue;
@@ -16425,40 +17381,64 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_core_module.c
+#endif
+ }
+
++ if (ngx_strcmp(value[n].data, "quic") == 0) {
++#if (NGX_HTTP_V3)
++ lsopt.quic = 1;
++ lsopt.type = SOCK_DGRAM;
++ continue;
++#else
++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
++ "the \"quic\" parameter requires "
++ "ngx_http_v3_module");
++ return NGX_CONF_ERROR;
++#endif
++ }
++
if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) {
if (ngx_strcmp(&value[n].data[13], "on") == 0) {
-@@ -4288,11 +4303,17 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
+@@ -4285,6 +4317,28 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
return NGX_CONF_ERROR;
}
-+#if (NGX_HTTP_SSL && NGX_HTTP_V3)
-+ if (lsopt.ssl && lsopt.http3) {
-+ return "\"ssl\" parameter is incompatible with \"http3\"";
++#if (NGX_HTTP_V3)
++
++ if (lsopt.quic) {
++#if (NGX_HTTP_SSL)
++ if (lsopt.ssl) {
++ return "\"ssl\" parameter is incompatible with \"quic\"";
++ }
++#endif
++
++#if (NGX_HTTP_V2)
++ if (lsopt.http2) {
++ return "\"http2\" parameter is incompatible with \"quic\"";
++ }
++#endif
++
++ if (lsopt.proxy_protocol) {
++ return "\"proxy_protocol\" parameter is incompatible with \"quic\"";
++ }
+ }
++
+#endif
+
for (n = 0; n < u.naddrs; n++) {
for (i = 0; i < n; i++) {
- if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen,
-- u.addrs[i].sockaddr, u.addrs[i].socklen, 0)
-+ u.addrs[i].sockaddr, u.addrs[i].socklen, 1)
- == NGX_OK)
- {
- goto next;
-diff -r ff3afd1ce6a6 src/http/ngx_http_core_module.h
---- a/src/http/ngx_http_core_module.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http_core_module.h Tue Jan 31 11:41:14 2023 -0500
-@@ -75,6 +75,7 @@ typedef struct {
+diff -r ac779115ed6e src/http/ngx_http_core_module.h
+--- a/src/http/ngx_http_core_module.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http_core_module.h Fri Mar 31 00:04:13 2023 -0400
+@@ -75,6 +75,8 @@ typedef struct {
unsigned wildcard:1;
unsigned ssl:1;
unsigned http2:1;
+ unsigned http3:1;
++ unsigned quic:1;
#if (NGX_HAVE_INET6)
unsigned ipv6only:1;
#endif
-@@ -86,6 +87,7 @@ typedef struct {
+@@ -86,6 +88,7 @@ typedef struct {
int backlog;
int rcvbuf;
int sndbuf;
@@ -16466,15 +17446,16 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_core_module.h
#if (NGX_HAVE_SETFIB)
int setfib;
#endif
-@@ -237,6 +239,7 @@ struct ngx_http_addr_conf_s {
+@@ -237,6 +240,8 @@ struct ngx_http_addr_conf_s {
unsigned ssl:1;
unsigned http2:1;
+ unsigned http3:1;
++ unsigned quic:1;
unsigned proxy_protocol:1;
};
-@@ -266,6 +269,7 @@ typedef struct {
+@@ -266,6 +271,7 @@ typedef struct {
typedef struct {
ngx_int_t family;
@@ -16482,9 +17463,9 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_core_module.h
in_port_t port;
ngx_array_t addrs; /* array of ngx_http_conf_addr_t */
} ngx_http_conf_port_t;
-diff -r ff3afd1ce6a6 src/http/ngx_http_request.c
---- a/src/http/ngx_http_request.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http_request.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/http/ngx_http_request.c
+--- a/src/http/ngx_http_request.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http_request.c Fri Mar 31 00:04:13 2023 -0400
@@ -29,10 +29,6 @@ static ngx_int_t ngx_http_process_connec
static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
@@ -16509,7 +17490,7 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_request.c
#endif
+#if (NGX_HTTP_V3)
-+ if (hc->addr_conf->http3) {
++ if (hc->addr_conf->quic) {
+ ngx_http_v3_init_stream(c);
+ return;
+ }
@@ -16565,7 +17546,7 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_request.c
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (r->main->count != 1) {
-@@ -2924,6 +2941,20 @@ ngx_http_test_reading(ngx_http_request_t
+@@ -2925,6 +2942,20 @@ ngx_http_test_reading(ngx_http_request_t
#endif
@@ -16586,7 +17567,7 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_request.c
#if (NGX_HAVE_KQUEUE)
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
-@@ -3588,7 +3619,7 @@ ngx_http_post_action(ngx_http_request_t
+@@ -3590,7 +3621,7 @@ ngx_http_post_action(ngx_http_request_t
}
@@ -16595,7 +17576,7 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_request.c
ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
{
ngx_connection_t *c;
-@@ -3675,7 +3706,12 @@ ngx_http_free_request(ngx_http_request_t
+@@ -3677,7 +3708,12 @@ ngx_http_free_request(ngx_http_request_t
log->action = "closing request";
@@ -16609,7 +17590,7 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_request.c
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (clcf->reset_timedout_connection) {
-@@ -3748,6 +3784,12 @@ ngx_http_close_connection(ngx_connection
+@@ -3750,6 +3786,12 @@ ngx_http_close_connection(ngx_connection
#endif
@@ -16622,9 +17603,9 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_request.c
#if (NGX_STAT_STUB)
(void) ngx_atomic_fetch_add(ngx_stat_active, -1);
#endif
-diff -r ff3afd1ce6a6 src/http/ngx_http_request.h
---- a/src/http/ngx_http_request.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http_request.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/http/ngx_http_request.h
+--- a/src/http/ngx_http_request.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http_request.h Fri Mar 31 00:04:13 2023 -0400
@@ -24,6 +24,7 @@
#define NGX_HTTP_VERSION_10 1000
#define NGX_HTTP_VERSION_11 1001
@@ -16660,9 +17641,9 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_request.h
unsigned expect_tested:1;
unsigned root_tested:1;
unsigned done:1;
-diff -r ff3afd1ce6a6 src/http/ngx_http_request_body.c
---- a/src/http/ngx_http_request_body.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http_request_body.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/http/ngx_http_request_body.c
+--- a/src/http/ngx_http_request_body.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http_request_body.c Fri Mar 31 00:04:13 2023 -0400
@@ -92,6 +92,13 @@ ngx_http_read_client_request_body(ngx_ht
}
#endif
@@ -16719,9 +17700,9 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_request_body.c
)
{
return NGX_OK;
-diff -r ff3afd1ce6a6 src/http/ngx_http_upstream.c
---- a/src/http/ngx_http_upstream.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http_upstream.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/http/ngx_http_upstream.c
+--- a/src/http/ngx_http_upstream.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http_upstream.c Fri Mar 31 00:04:13 2023 -0400
@@ -521,6 +521,13 @@ ngx_http_upstream_init(ngx_http_request_
}
#endif
@@ -16756,9 +17737,9 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_upstream.c
#if (NGX_HAVE_KQUEUE)
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
-diff -r ff3afd1ce6a6 src/http/ngx_http_write_filter_module.c
---- a/src/http/ngx_http_write_filter_module.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/http/ngx_http_write_filter_module.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/http/ngx_http_write_filter_module.c
+--- a/src/http/ngx_http_write_filter_module.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/http/ngx_http_write_filter_module.c Fri Mar 31 00:04:13 2023 -0400
@@ -240,6 +240,10 @@ ngx_http_write_filter(ngx_http_request_t
r->out = NULL;
c->buffered &= ~NGX_HTTP_WRITE_BUFFERED;
@@ -16781,10 +17762,10 @@ diff -r ff3afd1ce6a6 src/http/ngx_http_write_filter_module.c
if ((c->buffered & NGX_LOWLEVEL_BUFFERED) && r->postponed == NULL) {
return NGX_AGAIN;
}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.c
+diff -r ac779115ed6e src/http/v3/ngx_http_v3.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3.c Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,126 @@
++++ b/src/http/v3/ngx_http_v3.c Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,116 @@
+
+/*
+ * Copyright (C) Roman Arutyunyan
@@ -16804,12 +17785,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.c
+ngx_int_t
+ngx_http_v3_init_session(ngx_connection_t *c)
+{
-+ ngx_pool_cleanup_t *cln;
-+ ngx_http_connection_t *hc;
-+ ngx_http_v3_session_t *h3c;
-+#if (NGX_HTTP_V3_HQ)
-+ ngx_http_v3_srv_conf_t *h3scf;
-+#endif
++ ngx_pool_cleanup_t *cln;
++ ngx_http_connection_t *hc;
++ ngx_http_v3_session_t *h3c;
+
+ hc = c->data;
+
@@ -16823,13 +17801,6 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.c
+ h3c->max_push_id = (uint64_t) -1;
+ h3c->goaway_push_id = (uint64_t) -1;
+
-+#if (NGX_HTTP_V3_HQ)
-+ h3scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v3_module);
-+ if (h3scf->hq) {
-+ h3c->hq = 1;
-+ }
-+#endif
-+
+ ngx_queue_init(&h3c->blocked);
+ ngx_queue_init(&h3c->pushing);
+
@@ -16911,10 +17882,10 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.h
+diff -r ac779115ed6e src/http/v3/ngx_http_v3.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3.h Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,172 @@
++++ b/src/http/v3/ngx_http_v3.h Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,170 @@
+
+/*
+ * Copyright (C) Roman Arutyunyan
@@ -16938,6 +17909,7 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.h
+
+#define NGX_HTTP_V3_ALPN_PROTO "\x02h3"
+#define NGX_HTTP_V3_HQ_ALPN_PROTO "\x0Ahq-interop"
++#define NGX_HTTP_V3_HQ_PROTO "hq-interop"
+
+#define NGX_HTTP_V3_VARLEN_INT_LEN 4
+#define NGX_HTTP_V3_PREFIX_INT_LEN 11
@@ -17018,13 +17990,12 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.h
+
+
+typedef struct {
++ ngx_flag_t enable;
++ ngx_flag_t enable_hq;
+ size_t max_table_capacity;
+ ngx_uint_t max_blocked_streams;
+ ngx_uint_t max_concurrent_pushes;
+ ngx_uint_t max_concurrent_streams;
-+#if (NGX_HTTP_V3_HQ)
-+ ngx_flag_t hq;
-+#endif
+ ngx_quic_conf_t quic;
+} ngx_http_v3_srv_conf_t;
+
@@ -17064,9 +18035,7 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.h
+ off_t payload_bytes;
+
+ unsigned goaway:1;
-+#if (NGX_HTTP_V3_HQ)
+ unsigned hq:1;
-+#endif
+
+ ngx_connection_t *known_streams[NGX_HTTP_V3_MAX_KNOWN_STREAM];
+};
@@ -17087,9 +18056,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3.h
+
+
+#endif /* _NGX_HTTP_V3_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_encode.c
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_encode.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_encode.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_encode.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,304 @@
+
+/*
@@ -17395,9 +18364,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_encode.c
+
+ return (uintptr_t) p;
+}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_encode.h
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_encode.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_encode.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_encode.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,34 @@
+
+/*
@@ -17433,9 +18402,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_encode.h
+
+
+#endif /* _NGX_HTTP_V3_ENCODE_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_filter_module.c
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_filter_module.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_filter_module.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_filter_module.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,1536 @@
+
+/*
@@ -18973,9 +19942,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_filter_module.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_module.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_module.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_module.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,554 @@
+
+/*
@@ -19011,6 +19980,20 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+
+static ngx_command_t ngx_http_v3_commands[] = {
+
++ { ngx_string("http3"),
++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
++ ngx_conf_set_flag_slot,
++ NGX_HTTP_SRV_CONF_OFFSET,
++ offsetof(ngx_http_v3_srv_conf_t, enable),
++ NULL },
++
++ { ngx_string("http3_hq"),
++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
++ ngx_conf_set_flag_slot,
++ NGX_HTTP_SRV_CONF_OFFSET,
++ offsetof(ngx_http_v3_srv_conf_t, enable_hq),
++ NULL },
++
+ { ngx_string("http3_max_concurrent_pushes"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
@@ -19025,15 +20008,6 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+ offsetof(ngx_http_v3_srv_conf_t, max_concurrent_streams),
+ NULL },
+
-+#if (NGX_HTTP_V3_HQ)
-+ { ngx_string("http3_hq"),
-+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
-+ ngx_conf_set_flag_slot,
-+ NGX_HTTP_SRV_CONF_OFFSET,
-+ offsetof(ngx_http_v3_srv_conf_t, hq),
-+ NULL },
-+#endif
-+
+ { ngx_string("http3_push"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_v3_push,
@@ -19139,14 +20113,12 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+ngx_http_v3_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
-+ if (r->connection->quic) {
-+#if (NGX_HTTP_V3_HQ)
-+
-+ ngx_http_v3_srv_conf_t *h3scf;
++ ngx_http_v3_session_t *h3c;
+
-+ h3scf = ngx_http_get_module_srv_conf(r, ngx_http_v3_module);
++ if (r->connection->quic) {
++ h3c = ngx_http_v3_get_session(r->connection);
+
-+ if (h3scf->hq) {
++ if (h3c->hq) {
+ v->len = sizeof("hq") - 1;
+ v->valid = 1;
+ v->no_cacheable = 0;
@@ -19156,8 +20128,6 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+ return NGX_OK;
+ }
+
-+#endif
-+
+ v->len = sizeof("h3") - 1;
+ v->valid = 1;
+ v->no_cacheable = 0;
@@ -19211,12 +20181,12 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+ * h3scf->quic.timeout = 0;
+ * h3scf->max_blocked_streams = 0;
+ */
++
++ h3scf->enable = NGX_CONF_UNSET;
++ h3scf->enable_hq = NGX_CONF_UNSET;
+ h3scf->max_table_capacity = NGX_HTTP_V3_MAX_TABLE_CAPACITY;
+ h3scf->max_concurrent_pushes = NGX_CONF_UNSET_UINT;
+ h3scf->max_concurrent_streams = NGX_CONF_UNSET_UINT;
-+#if (NGX_HTTP_V3_HQ)
-+ h3scf->hq = NGX_CONF_UNSET;
-+#endif
+
+ h3scf->quic.mtu = NGX_CONF_UNSET_SIZE;
+ h3scf->quic.stream_buffer_size = NGX_CONF_UNSET_SIZE;
@@ -19243,6 +20213,10 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+
+ ngx_http_ssl_srv_conf_t *sscf;
+
++ ngx_conf_merge_value(conf->enable, prev->enable, 1);
++
++ ngx_conf_merge_value(conf->enable_hq, prev->enable_hq, 0);
++
+ ngx_conf_merge_uint_value(conf->max_concurrent_pushes,
+ prev->max_concurrent_pushes, 10);
+
@@ -19251,11 +20225,6 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+
+ conf->max_blocked_streams = conf->max_concurrent_streams;
+
-+#if (NGX_HTTP_V3_HQ)
-+ ngx_conf_merge_value(conf->hq, prev->hq, 0);
-+#endif
-+
-+
+ ngx_conf_merge_size_value(conf->quic.mtu, prev->quic.mtu,
+ NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
+
@@ -19531,9 +20500,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_module.c
+
+ return NGX_CONF_OK;
+}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_parse.c
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_parse.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_parse.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_parse.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,2013 @@
+
+/*
@@ -21548,9 +22517,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_parse.c
+ }
+ }
+}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_parse.h
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_parse.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_parse.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_parse.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,146 @@
+
+/*
@@ -21698,10 +22667,10 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_parse.h
+
+
+#endif /* _NGX_HTTP_V3_PARSE_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_request.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_request.c Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,1697 @@
++++ b/src/http/v3/ngx_http_v3_request.c Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,1718 @@
+
+/*
+ * Copyright (C) Roman Arutyunyan
@@ -21814,7 +22783,10 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+ngx_int_t
+ngx_http_v3_init(ngx_connection_t *c)
+{
++ unsigned int len;
++ const unsigned char *data;
+ ngx_http_v3_session_t *h3c;
++ ngx_http_v3_srv_conf_t *h3scf;
+ ngx_http_core_loc_conf_t *clcf;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init");
@@ -21823,11 +22795,23 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+ clcf = ngx_http_v3_get_module_loc_conf(c, ngx_http_core_module);
+ ngx_add_timer(&h3c->keepalive, clcf->keepalive_timeout);
+
-+#if (NGX_HTTP_V3_HQ)
-+ if (h3c->hq) {
-+ return NGX_OK;
++ h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module);
++
++ if (h3scf->enable_hq) {
++ if (!h3scf->enable) {
++ h3c->hq = 1;
++ return NGX_OK;
++ }
++
++ SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
++
++ if (len == sizeof(NGX_HTTP_V3_HQ_PROTO) - 1
++ && ngx_strncmp(data, NGX_HTTP_V3_HQ_PROTO, len) == 0)
++ {
++ h3c->hq = 1;
++ return NGX_OK;
++ }
+ }
-+#endif
+
+ return ngx_http_v3_send_settings(c);
+}
@@ -21851,10 +22835,7 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+ if (!h3c->goaway) {
+ h3c->goaway = 1;
+
-+#if (NGX_HTTP_V3_HQ)
-+ if (!h3c->hq)
-+#endif
-+ {
++ if (!h3c->hq) {
+ (void) ngx_http_v3_send_goaway(c, h3c->next_request_id);
+ }
+
@@ -21909,10 +22890,7 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+ {
+ h3c->goaway = 1;
+
-+#if (NGX_HTTP_V3_HQ)
-+ if (!h3c->hq)
-+#endif
-+ {
++ if (!h3c->hq) {
+ if (ngx_http_v3_send_goaway(c, h3c->next_request_id) != NGX_OK) {
+ ngx_http_close_connection(c);
+ return;
@@ -21940,10 +22918,7 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+
+ rev = c->read;
+
-+#if (NGX_HTTP_V3_HQ)
-+ if (!h3c->hq)
-+#endif
-+ {
++ if (!h3c->hq) {
+ rev->handler = ngx_http_v3_wait_request_handler;
+ c->write->handler = ngx_http_empty_handler;
+ }
@@ -22102,14 +23077,14 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+void
+ngx_http_v3_reset_stream(ngx_connection_t *c)
+{
++ ngx_http_v3_session_t *h3c;
+ ngx_http_v3_srv_conf_t *h3scf;
+
+ h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module);
+
-+ if (h3scf->max_table_capacity > 0 && !c->read->eof
-+#if (NGX_HTTP_V3_HQ)
-+ && !h3scf->hq
-+#endif
++ h3c = ngx_http_v3_get_session(c);
++
++ if (h3scf->max_table_capacity > 0 && !c->read->eof && !h3c->hq
+ && (c->quic->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0)
+ {
+ (void) ngx_http_v3_send_cancel_stream(c, c->quic->id);
@@ -22697,9 +23672,11 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+static ngx_int_t
+ngx_http_v3_process_request_header(ngx_http_request_t *r)
+{
-+ ssize_t n;
-+ ngx_buf_t *b;
-+ ngx_connection_t *c;
++ ssize_t n;
++ ngx_buf_t *b;
++ ngx_connection_t *c;
++ ngx_http_v3_session_t *h3c;
++ ngx_http_v3_srv_conf_t *h3scf;
+
+ c = r->connection;
+
@@ -22707,6 +23684,19 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+ return NGX_ERROR;
+ }
+
++ h3c = ngx_http_v3_get_session(c);
++ h3scf = ngx_http_get_module_srv_conf(r, ngx_http_v3_module);
++
++ if (!r->http_connection->addr_conf->http3) {
++ if ((h3c->hq && !h3scf->enable_hq) || (!h3c->hq && !h3scf->enable)) {
++ ngx_log_error(NGX_LOG_INFO, c->log, 0,
++ "client attempted to request the server name "
++ "for which the negotiated protocol is disabled");
++ ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
++ return NGX_ERROR;
++ }
++ }
++
+ if (ngx_http_v3_construct_cookie_header(r) != NGX_OK) {
+ return NGX_ERROR;
+ }
@@ -23399,9 +24389,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_request.c
+
+ return rc;
+}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_table.c
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_table.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_table.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_table.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,715 @@
+
+/*
@@ -24118,9 +25108,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_table.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_table.h
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_table.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_table.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_table.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,58 @@
+
+/*
@@ -24180,10 +25170,10 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_table.h
+
+
+#endif /* _NGX_HTTP_V3_TABLE_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_uni.c
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_uni.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_uni.c Tue Jan 31 11:41:14 2023 -0500
-@@ -0,0 +1,785 @@
++++ b/src/http/v3/ngx_http_v3_uni.c Fri Mar 31 00:04:13 2023 -0400
+@@ -0,0 +1,781 @@
+
+/*
+ * Copyright (C) Roman Arutyunyan
@@ -24223,12 +25213,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_uni.c
+ngx_http_v3_init_uni_stream(ngx_connection_t *c)
+{
+ uint64_t n;
-+#if (NGX_HTTP_V3_HQ)
+ ngx_http_v3_session_t *h3c;
-+#endif
+ ngx_http_v3_uni_stream_t *us;
+
-+#if (NGX_HTTP_V3_HQ)
+ h3c = ngx_http_v3_get_session(c);
+ if (h3c->hq) {
+ ngx_http_v3_finalize_connection(c,
@@ -24238,7 +25225,6 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_uni.c
+ ngx_http_v3_close_uni_stream(c);
+ return;
+ }
-+#endif
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init uni stream");
+
@@ -24969,9 +25955,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_uni.c
+
+ return NGX_OK;
+}
-diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_uni.h
+diff -r ac779115ed6e src/http/v3/ngx_http_v3_uni.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/http/v3/ngx_http_v3_uni.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/http/v3/ngx_http_v3_uni.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,38 @@
+
+/*
@@ -25011,21 +25997,9 @@ diff -r ff3afd1ce6a6 src/http/v3/ngx_http_v3_uni.h
+
+
+#endif /* _NGX_HTTP_V3_UNI_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/mail/ngx_mail_core_module.c
---- a/src/mail/ngx_mail_core_module.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/mail/ngx_mail_core_module.c Tue Jan 31 11:41:14 2023 -0500
-@@ -572,7 +572,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx
-
- for (i = 0; i < n; i++) {
- if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen,
-- u.addrs[i].sockaddr, u.addrs[i].socklen, 0)
-+ u.addrs[i].sockaddr, u.addrs[i].socklen, 1)
- == NGX_OK)
- {
- goto next;
-diff -r ff3afd1ce6a6 src/os/unix/ngx_socket.h
---- a/src/os/unix/ngx_socket.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/os/unix/ngx_socket.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/os/unix/ngx_socket.h
+--- a/src/os/unix/ngx_socket.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/os/unix/ngx_socket.h Fri Mar 31 00:04:13 2023 -0400
@@ -13,6 +13,8 @@
@@ -25035,21 +26009,9 @@ diff -r ff3afd1ce6a6 src/os/unix/ngx_socket.h
typedef int ngx_socket_t;
-diff -r ff3afd1ce6a6 src/os/unix/ngx_udp_sendmsg_chain.c
---- a/src/os/unix/ngx_udp_sendmsg_chain.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/os/unix/ngx_udp_sendmsg_chain.c Tue Jan 31 11:41:14 2023 -0500
-@@ -335,7 +335,7 @@ ngx_get_srcaddr_cmsg(struct cmsghdr *cms
- #endif
-
-
-- #if (NGX_HAVE_IP_RECVDSTADDR)
-+#if (NGX_HAVE_IP_RECVDSTADDR)
-
- if (cmsg->cmsg_level == IPPROTO_IP
- && cmsg->cmsg_type == IP_RECVDSTADDR
-diff -r ff3afd1ce6a6 src/os/win32/ngx_socket.h
---- a/src/os/win32/ngx_socket.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/os/win32/ngx_socket.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/os/win32/ngx_socket.h
+--- a/src/os/win32/ngx_socket.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/os/win32/ngx_socket.h Fri Mar 31 00:04:13 2023 -0400
@@ -14,6 +14,8 @@
@@ -25059,9 +26021,9 @@ diff -r ff3afd1ce6a6 src/os/win32/ngx_socket.h
typedef SOCKET ngx_socket_t;
-diff -r ff3afd1ce6a6 src/stream/ngx_stream.c
---- a/src/stream/ngx_stream.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/stream/ngx_stream.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/stream/ngx_stream.c
+--- a/src/stream/ngx_stream.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/stream/ngx_stream.c Fri Mar 31 00:04:13 2023 -0400
@@ -518,6 +518,24 @@ ngx_stream_optimize_servers(ngx_conf_t *
ls->reuseport = addr[i].opt.reuseport;
#endif
@@ -25107,9 +26069,9 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream.c
addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
addrs6[i].conf.addr_text = addr[i].opt.addr_text;
}
-diff -r ff3afd1ce6a6 src/stream/ngx_stream.h
---- a/src/stream/ngx_stream.h Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/stream/ngx_stream.h Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/stream/ngx_stream.h
+--- a/src/stream/ngx_stream.h Tue Mar 28 18:01:53 2023 +0300
++++ b/src/stream/ngx_stream.h Fri Mar 31 00:04:13 2023 -0400
@@ -16,6 +16,10 @@
#include <ngx_stream_ssl_module.h>
#endif
@@ -25137,9 +26099,9 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream.h
unsigned proxy_protocol:1;
} ngx_stream_addr_conf_t;
-diff -r ff3afd1ce6a6 src/stream/ngx_stream_core_module.c
---- a/src/stream/ngx_stream_core_module.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/stream/ngx_stream_core_module.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/stream/ngx_stream_core_module.c
+--- a/src/stream/ngx_stream_core_module.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/stream/ngx_stream_core_module.c Fri Mar 31 00:04:13 2023 -0400
@@ -760,6 +760,29 @@ ngx_stream_core_listen(ngx_conf_t *cf, n
#endif
}
@@ -25183,18 +26145,9 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream_core_module.c
if (ls->so_keepalive) {
return "\"so_keepalive\" parameter is incompatible with \"udp\"";
}
-@@ -890,7 +919,7 @@ ngx_stream_core_listen(ngx_conf_t *cf, n
-
- for (i = 0; i < n; i++) {
- if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen,
-- u.addrs[i].sockaddr, u.addrs[i].socklen, 0)
-+ u.addrs[i].sockaddr, u.addrs[i].socklen, 1)
- == NGX_OK)
- {
- goto next;
-diff -r ff3afd1ce6a6 src/stream/ngx_stream_handler.c
---- a/src/stream/ngx_stream_handler.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/stream/ngx_stream_handler.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/stream/ngx_stream_handler.c
+--- a/src/stream/ngx_stream_handler.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/stream/ngx_stream_handler.c Fri Mar 31 00:04:13 2023 -0400
@@ -129,6 +129,10 @@ ngx_stream_init_connection(ngx_connectio
s->ssl = addr_conf->ssl;
#endif
@@ -25228,9 +26181,9 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream_handler.c
rev = c->read;
rev->handler = ngx_stream_session_handler;
-diff -r ff3afd1ce6a6 src/stream/ngx_stream_proxy_module.c
---- a/src/stream/ngx_stream_proxy_module.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/stream/ngx_stream_proxy_module.c Tue Jan 31 11:41:14 2023 -0500
+diff -r ac779115ed6e src/stream/ngx_stream_proxy_module.c
+--- a/src/stream/ngx_stream_proxy_module.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/stream/ngx_stream_proxy_module.c Fri Mar 31 00:04:13 2023 -0400
@@ -1772,6 +1772,21 @@ ngx_stream_proxy_process(ngx_stream_sess
if (dst->type == SOCK_STREAM && pscf->half_close
&& src->read->eof && !u->half_closed && !dst->buffered)
@@ -25253,9 +26206,9 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream_proxy_module.c
if (ngx_shutdown_socket(dst->fd, NGX_WRITE_SHUTDOWN) == -1) {
ngx_connection_error(c, ngx_socket_errno,
ngx_shutdown_socket_n " failed");
-diff -r ff3afd1ce6a6 src/stream/ngx_stream_quic_module.c
+diff -r ac779115ed6e src/stream/ngx_stream_quic_module.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/stream/ngx_stream_quic_module.c Tue Jan 31 11:41:14 2023 -0500
++++ b/src/stream/ngx_stream_quic_module.c Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,377 @@
+
+/*
@@ -25634,9 +26587,9 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream_quic_module.c
+
+ return NGX_CONF_ERROR;
+}
-diff -r ff3afd1ce6a6 src/stream/ngx_stream_quic_module.h
+diff -r ac779115ed6e src/stream/ngx_stream_quic_module.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/stream/ngx_stream_quic_module.h Tue Jan 31 11:41:14 2023 -0500
++++ b/src/stream/ngx_stream_quic_module.h Fri Mar 31 00:04:13 2023 -0400
@@ -0,0 +1,20 @@
+
+/*
@@ -25658,10 +26611,21 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream_quic_module.h
+
+
+#endif /* _NGX_STREAM_QUIC_H_INCLUDED_ */
-diff -r ff3afd1ce6a6 src/stream/ngx_stream_ssl_module.c
---- a/src/stream/ngx_stream_ssl_module.c Tue Dec 13 18:53:53 2022 +0300
-+++ b/src/stream/ngx_stream_ssl_module.c Tue Jan 31 11:41:14 2023 -0500
-@@ -1194,7 +1194,10 @@ ngx_stream_ssl_conf_command_check(ngx_co
+diff -r ac779115ed6e src/stream/ngx_stream_ssl_module.c
+--- a/src/stream/ngx_stream_ssl_module.c Tue Mar 28 18:01:53 2023 +0300
++++ b/src/stream/ngx_stream_ssl_module.c Fri Mar 31 00:04:13 2023 -0400
+@@ -9,6 +9,10 @@
+ #include <ngx_core.h>
+ #include <ngx_stream.h>
+
++#if (NGX_QUIC_OPENSSL_COMPAT)
++#include <ngx_event_quic_openssl_compat.h>
++#endif
++
+
+ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
+ ngx_pool_t *pool, ngx_str_t *s);
+@@ -1195,7 +1199,10 @@ ngx_stream_ssl_conf_command_check(ngx_co
static ngx_int_t
ngx_stream_ssl_init(ngx_conf_t *cf)
{
@@ -25672,7 +26636,7 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream_ssl_module.c
ngx_stream_core_main_conf_t *cmcf;
cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
-@@ -1206,5 +1209,23 @@ ngx_stream_ssl_init(ngx_conf_t *cf)
+@@ -1207,5 +1214,29 @@ ngx_stream_ssl_init(ngx_conf_t *cf)
*h = ngx_stream_ssl_handler;
@@ -25685,6 +26649,12 @@ diff -r ff3afd1ce6a6 src/stream/ngx_stream_ssl_module.c
+
+ scf = listen[i].ctx->srv_conf[ngx_stream_ssl_module.ctx_index];
+
++#if (NGX_QUIC_OPENSSL_COMPAT)
++ if (ngx_quic_compat_init(cf, scf->ssl.ctx) != NGX_OK) {
++ return NGX_ERROR;
++ }
++#endif
++
+ if (scf->certificates && !(scf->protocols & NGX_SSL_TLSv1_3)) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "\"ssl_protocols\" must enable TLSv1.3 for "