[nginx] Merged with the quic branch.

Roman Arutyunyan arut at nginx.com
Fri May 19 17:51:16 UTC 2023


details:   https://hg.nginx.org/nginx/rev/235d482ef6bc
branches:  
changeset: 9110:235d482ef6bc
user:      Roman Arutyunyan <arut at nginx.com>
date:      Fri May 19 21:46:36 2023 +0400
description:
Merged with the quic branch.

diffstat:

 auto/lib/openssl/conf                          |    43 +-
 auto/make                                      |     5 +-
 auto/modules                                   |    99 +-
 auto/options                                   |    12 +
 auto/os/linux                                  |    44 +
 auto/sources                                   |     2 +-
 auto/unix                                      |    48 +
 src/core/nginx.c                               |     3 +
 src/core/ngx_bpf.c                             |   143 +
 src/core/ngx_bpf.h                             |    43 +
 src/core/ngx_connection.c                      |    78 +
 src/core/ngx_connection.h                      |     5 +
 src/core/ngx_core.h                            |     7 +
 src/event/ngx_event.c                          |    34 +-
 src/event/ngx_event_openssl.c                  |    12 +-
 src/event/ngx_event_openssl.h                  |    11 +
 src/event/ngx_event_udp.c                      |    13 +-
 src/event/ngx_event_udp.h                      |     8 +
 src/event/quic/bpf/bpfgen.sh                   |   113 +
 src/event/quic/bpf/makefile                    |    30 +
 src/event/quic/bpf/ngx_quic_reuseport_helper.c |   140 +
 src/event/quic/ngx_event_quic.c                |  1445 +++++++++++++++
 src/event/quic/ngx_event_quic.h                |   128 +
 src/event/quic/ngx_event_quic_ack.c            |  1192 +++++++++++++
 src/event/quic/ngx_event_quic_ack.h            |    30 +
 src/event/quic/ngx_event_quic_bpf.c            |   657 +++++++
 src/event/quic/ngx_event_quic_bpf_code.c       |    88 +
 src/event/quic/ngx_event_quic_connection.h     |   283 +++
 src/event/quic/ngx_event_quic_connid.c         |   502 +++++
 src/event/quic/ngx_event_quic_connid.h         |    29 +
 src/event/quic/ngx_event_quic_frames.c         |   894 +++++++++
 src/event/quic/ngx_event_quic_frames.h         |    45 +
 src/event/quic/ngx_event_quic_migration.c      |   711 +++++++
 src/event/quic/ngx_event_quic_migration.h      |    42 +
 src/event/quic/ngx_event_quic_openssl_compat.c |   646 +++++++
 src/event/quic/ngx_event_quic_openssl_compat.h |    60 +
 src/event/quic/ngx_event_quic_output.c         |  1293 ++++++++++++++
 src/event/quic/ngx_event_quic_output.h         |    40 +
 src/event/quic/ngx_event_quic_protection.c     |  1087 +++++++++++
 src/event/quic/ngx_event_quic_protection.h     |   114 +
 src/event/quic/ngx_event_quic_socket.c         |   238 ++
 src/event/quic/ngx_event_quic_socket.h         |    28 +
 src/event/quic/ngx_event_quic_ssl.c            |   600 ++++++
 src/event/quic/ngx_event_quic_ssl.h            |    19 +
 src/event/quic/ngx_event_quic_streams.c        |  1807 +++++++++++++++++++
 src/event/quic/ngx_event_quic_streams.h        |    44 +
 src/event/quic/ngx_event_quic_tokens.c         |   289 +++
 src/event/quic/ngx_event_quic_tokens.h         |    35 +
 src/event/quic/ngx_event_quic_transport.c      |  2199 ++++++++++++++++++++++++
 src/event/quic/ngx_event_quic_transport.h      |   397 ++++
 src/event/quic/ngx_event_quic_udp.c            |   420 ++++
 src/http/modules/ngx_http_ssl_module.c         |   115 +-
 src/http/ngx_http.c                            |    28 +-
 src/http/ngx_http.h                            |    12 +-
 src/http/ngx_http_core_module.c                |    37 +
 src/http/ngx_http_core_module.h                |     4 +
 src/http/ngx_http_request.c                    |    60 +-
 src/http/ngx_http_request.h                    |     7 +
 src/http/ngx_http_request_body.c               |    28 +
 src/http/ngx_http_upstream.c                   |    20 +
 src/http/ngx_http_write_filter_module.c        |     8 +
 src/http/v3/ngx_http_v3.c                      |   109 +
 src/http/v3/ngx_http_v3.h                      |   157 +
 src/http/v3/ngx_http_v3_encode.c               |   304 +++
 src/http/v3/ngx_http_v3_encode.h               |    34 +
 src/http/v3/ngx_http_v3_filter_module.c        |   851 +++++++++
 src/http/v3/ngx_http_v3_module.c               |   389 ++++
 src/http/v3/ngx_http_v3_parse.c                |  1931 +++++++++++++++++++++
 src/http/v3/ngx_http_v3_parse.h                |   146 +
 src/http/v3/ngx_http_v3_request.c              |  1716 ++++++++++++++++++
 src/http/v3/ngx_http_v3_table.c                |   715 +++++++
 src/http/v3/ngx_http_v3_table.h                |    58 +
 src/http/v3/ngx_http_v3_uni.c                  |   624 ++++++
 src/http/v3/ngx_http_v3_uni.h                  |    32 +
 src/os/unix/ngx_socket.h                       |     2 +
 src/os/win32/ngx_socket.h                      |     2 +
 76 files changed, 23593 insertions(+), 51 deletions(-)

diffs (truncated from 24605 to 1000 lines):

diff -r b71e69247483 -r 235d482ef6bc auto/lib/openssl/conf
--- a/auto/lib/openssl/conf	Mon May 01 19:16:05 2023 +0400
+++ b/auto/lib/openssl/conf	Fri May 19 21:46:36 2023 +0400
@@ -5,12 +5,17 @@
 
 if [ $OPENSSL != NONE ]; then
 
+    have=NGX_OPENSSL . auto/have
+    have=NGX_SSL . auto/have
+
+    if [ $USE_OPENSSL_QUIC = YES ]; then
+        have=NGX_QUIC . auto/have
+        have=NGX_QUIC_OPENSSL_COMPAT . auto/have
+    fi
+
     case "$CC" in
 
         cl | bcc32)
-            have=NGX_OPENSSL . auto/have
-            have=NGX_SSL . auto/have
-
             CFLAGS="$CFLAGS -DNO_SYS_TYPES_H"
 
             CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
@@ -33,9 +38,6 @@ if [ $OPENSSL != NONE ]; then
         ;;
 
         *)
-            have=NGX_OPENSSL . auto/have
-            have=NGX_SSL . auto/have
-
             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"
@@ -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
+
+                if [ $ngx_found = no ]; then
+                    have=NGX_QUIC_OPENSSL_COMPAT . auto/have
+
+                    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.
+You can either do not enable the modules, or install the OpenSSL library with
+QUIC support into the system, or build the OpenSSL library with QUIC support
+statically from the source with nginx by using --with-openssl=<path> option.
+
+END
+                        exit 1
+                fi
+            fi
         fi
     fi
 
diff -r b71e69247483 -r 235d482ef6bc auto/make
--- a/auto/make	Mon May 01 19:16:05 2023 +0400
+++ b/auto/make	Fri May 19 21:46:36 2023 +0400
@@ -6,9 +6,10 @@
 echo "creating $NGX_MAKEFILE"
 
 mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \
+         $NGX_OBJS/src/event/quic \
          $NGX_OBJS/src/os/unix $NGX_OBJS/src/os/win32 \
-         $NGX_OBJS/src/http $NGX_OBJS/src/http/v2 $NGX_OBJS/src/http/modules \
-         $NGX_OBJS/src/http/modules/perl \
+         $NGX_OBJS/src/http $NGX_OBJS/src/http/v2 $NGX_OBJS/src/http/v3 \
+         $NGX_OBJS/src/http/modules $NGX_OBJS/src/http/modules/perl \
          $NGX_OBJS/src/mail \
          $NGX_OBJS/src/stream \
          $NGX_OBJS/src/misc
diff -r b71e69247483 -r 235d482ef6bc auto/modules
--- a/auto/modules	Mon May 01 19:16:05 2023 +0400
+++ b/auto/modules	Fri May 19 21:46:36 2023 +0400
@@ -102,7 +102,7 @@ if [ $HTTP = YES ]; then
     fi
 
 
-    if [ $HTTP_V2 = YES ]; then
+    if [ $HTTP_V2 = YES -o $HTTP_V3 = YES ]; then
         HTTP_SRCS="$HTTP_SRCS $HTTP_HUFF_SRCS"
     fi
 
@@ -124,6 +124,7 @@ if [ $HTTP = YES ]; then
     #     ngx_http_header_filter
     #     ngx_http_chunked_filter
     #     ngx_http_v2_filter
+    #     ngx_http_v3_filter
     #     ngx_http_range_header_filter
     #     ngx_http_gzip_filter
     #     ngx_http_postpone_filter
@@ -156,6 +157,7 @@ if [ $HTTP = YES ]; then
                       ngx_http_header_filter_module \
                       ngx_http_chunked_filter_module \
                       ngx_http_v2_filter_module \
+                      ngx_http_v3_filter_module \
                       ngx_http_range_header_filter_module \
                       ngx_http_gzip_filter_module \
                       ngx_http_postpone_filter_module \
@@ -217,6 +219,17 @@ if [ $HTTP = YES ]; then
         . auto/module
     fi
 
+    if [ $HTTP_V3 = YES ]; then
+        ngx_module_name=ngx_http_v3_filter_module
+        ngx_module_incs=
+        ngx_module_deps=
+        ngx_module_srcs=src/http/v3/ngx_http_v3_filter_module.c
+        ngx_module_libs=
+        ngx_module_link=$HTTP_V3
+
+        . auto/module
+    fi
+
     if :; then
         ngx_module_name=ngx_http_range_header_filter_module
         ngx_module_incs=
@@ -426,6 +439,33 @@ if [ $HTTP = YES ]; then
         . auto/module
     fi
 
+    if [ $HTTP_V3 = YES ]; then
+        USE_OPENSSL_QUIC=YES
+        HTTP_SSL=YES
+
+        have=NGX_HTTP_V3 . auto/have
+        have=NGX_HTTP_HEADERS . auto/have
+
+        ngx_module_name=ngx_http_v3_module
+        ngx_module_incs=src/http/v3
+        ngx_module_deps="src/http/v3/ngx_http_v3.h \
+                         src/http/v3/ngx_http_v3_encode.h \
+                         src/http/v3/ngx_http_v3_parse.h \
+                         src/http/v3/ngx_http_v3_table.h \
+                         src/http/v3/ngx_http_v3_uni.h"
+        ngx_module_srcs="src/http/v3/ngx_http_v3.c \
+                         src/http/v3/ngx_http_v3_encode.c \
+                         src/http/v3/ngx_http_v3_parse.c \
+                         src/http/v3/ngx_http_v3_table.c \
+                         src/http/v3/ngx_http_v3_uni.c \
+                         src/http/v3/ngx_http_v3_request.c \
+                         src/http/v3/ngx_http_v3_module.c"
+        ngx_module_libs=
+        ngx_module_link=$HTTP_V3
+
+        . auto/module
+    fi
+
     if :; then
         ngx_module_name=ngx_http_static_module
         ngx_module_incs=
@@ -1272,6 +1312,63 @@ if [ $USE_OPENSSL = YES ]; then
 fi
 
 
+if [ $USE_OPENSSL_QUIC = YES ]; then
+    ngx_module_type=CORE
+    ngx_module_name=ngx_quic_module
+    ngx_module_incs=
+    ngx_module_deps="src/event/quic/ngx_event_quic.h \
+                     src/event/quic/ngx_event_quic_transport.h \
+                     src/event/quic/ngx_event_quic_protection.h \
+                     src/event/quic/ngx_event_quic_connection.h \
+                     src/event/quic/ngx_event_quic_frames.h \
+                     src/event/quic/ngx_event_quic_connid.h \
+                     src/event/quic/ngx_event_quic_migration.h \
+                     src/event/quic/ngx_event_quic_streams.h \
+                     src/event/quic/ngx_event_quic_ssl.h \
+                     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_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 \
+                     src/event/quic/ngx_event_quic_protection.c \
+                     src/event/quic/ngx_event_quic_frames.c \
+                     src/event/quic/ngx_event_quic_connid.c \
+                     src/event/quic/ngx_event_quic_migration.c \
+                     src/event/quic/ngx_event_quic_streams.c \
+                     src/event/quic/ngx_event_quic_ssl.c \
+                     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_openssl_compat.c"
+
+    ngx_module_libs=
+    ngx_module_link=YES
+    ngx_module_order=
+
+    . auto/module
+
+    if [ $QUIC_BPF = YES -a $SO_COOKIE_FOUND = YES ]; then
+        ngx_module_type=CORE
+        ngx_module_name=ngx_quic_bpf_module
+        ngx_module_incs=
+        ngx_module_deps=
+        ngx_module_srcs="src/event/quic/ngx_event_quic_bpf.c \
+                         src/event/quic/ngx_event_quic_bpf_code.c"
+        ngx_module_libs=
+        ngx_module_link=YES
+        ngx_module_order=
+
+        . auto/module
+
+        have=NGX_QUIC_BPF . auto/have
+    fi
+fi
+
+
 if [ $USE_PCRE = YES ]; then
     ngx_module_type=CORE
     ngx_module_name=ngx_regex_module
diff -r b71e69247483 -r 235d482ef6bc auto/options
--- a/auto/options	Mon May 01 19:16:05 2023 +0400
+++ b/auto/options	Fri May 19 21:46:36 2023 +0400
@@ -45,6 +45,8 @@ USE_THREADS=NO
 
 NGX_FILE_AIO=NO
 
+QUIC_BPF=NO
+
 HTTP=YES
 
 NGX_HTTP_LOG_PATH=
@@ -59,6 +61,7 @@ HTTP_CHARSET=YES
 HTTP_GZIP=YES
 HTTP_SSL=NO
 HTTP_V2=NO
+HTTP_V3=NO
 HTTP_SSI=YES
 HTTP_REALIP=NO
 HTTP_XSLT=NO
@@ -149,6 +152,7 @@ PCRE_JIT=NO
 PCRE2=YES
 
 USE_OPENSSL=NO
+USE_OPENSSL_QUIC=NO
 OPENSSL=NONE
 
 USE_ZLIB=NO
@@ -166,6 +170,8 @@ USE_GEOIP=NO
 NGX_GOOGLE_PERFTOOLS=NO
 NGX_CPP_TEST=NO
 
+SO_COOKIE_FOUND=NO
+
 NGX_LIBATOMIC=NO
 
 NGX_CPU_CACHE_LINE=
@@ -211,6 +217,8 @@ do
 
         --with-file-aio)                 NGX_FILE_AIO=YES           ;;
 
+        --without-quic_bpf_module)       QUIC_BPF=NONE              ;;
+
         --with-ipv6)
             NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
 $0: warning: the \"--with-ipv6\" option is deprecated"
@@ -228,6 +236,7 @@ do
 
         --with-http_ssl_module)          HTTP_SSL=YES               ;;
         --with-http_v2_module)           HTTP_V2=YES                ;;
+        --with-http_v3_module)           HTTP_V3=YES                ;;
         --with-http_realip_module)       HTTP_REALIP=YES            ;;
         --with-http_addition_module)     HTTP_ADDITION=YES          ;;
         --with-http_xslt_module)         HTTP_XSLT=YES              ;;
@@ -443,8 +452,11 @@ cat << END
 
   --with-file-aio                    enable file AIO support
 
+  --without-quic_bpf_module          disable ngx_quic_bpf_module
+
   --with-http_ssl_module             enable ngx_http_ssl_module
   --with-http_v2_module              enable ngx_http_v2_module
+  --with-http_v3_module              enable ngx_http_v3_module
   --with-http_realip_module          enable ngx_http_realip_module
   --with-http_addition_module        enable ngx_http_addition_module
   --with-http_xslt_module            enable ngx_http_xslt_module
diff -r b71e69247483 -r 235d482ef6bc auto/os/linux
--- a/auto/os/linux	Mon May 01 19:16:05 2023 +0400
+++ b/auto/os/linux	Fri May 19 21:46:36 2023 +0400
@@ -232,6 +232,50 @@ ngx_feature_test="struct crypt_data  cd;
 ngx_include="sys/vfs.h";     . auto/include
 
 
+# BPF sockhash
+
+ngx_feature="BPF sockhash"
+ngx_feature_name="NGX_HAVE_BPF"
+ngx_feature_run=no
+ngx_feature_incs="#include <linux/bpf.h>
+                  #include <sys/syscall.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="union bpf_attr attr = { 0 };
+
+                  attr.map_flags = 0;
+                  attr.map_type = BPF_MAP_TYPE_SOCKHASH;
+
+                  syscall(__NR_bpf, 0, &attr, 0);"
+. auto/feature
+
+if [ $ngx_found = yes ]; then
+    CORE_SRCS="$CORE_SRCS src/core/ngx_bpf.c"
+    CORE_DEPS="$CORE_DEPS src/core/ngx_bpf.h"
+
+    if [ $QUIC_BPF != NONE ]; then
+        QUIC_BPF=YES
+    fi
+fi
+
+
+ngx_feature="SO_COOKIE"
+ngx_feature_name="NGX_HAVE_SO_COOKIE"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+                  $NGX_INCLUDE_INTTYPES_H"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="socklen_t optlen = sizeof(uint64_t);
+                  uint64_t cookie;
+                  getsockopt(0, SOL_SOCKET, SO_COOKIE, &cookie, &optlen)"
+. auto/feature
+
+if [ $ngx_found = yes ]; then
+    SO_COOKIE_FOUND=YES
+fi
+
+
 # UDP segmentation offloading
 
 ngx_feature="UDP_SEGMENT"
diff -r b71e69247483 -r 235d482ef6bc auto/sources
--- a/auto/sources	Mon May 01 19:16:05 2023 +0400
+++ b/auto/sources	Fri May 19 21:46:36 2023 +0400
@@ -83,7 +83,7 @@ CORE_SRCS="src/core/nginx.c \
 
 EVENT_MODULES="ngx_events_module ngx_event_core_module"
 
-EVENT_INCS="src/event src/event/modules"
+EVENT_INCS="src/event src/event/modules src/event/quic"
 
 EVENT_DEPS="src/event/ngx_event.h \
             src/event/ngx_event_timer.h \
diff -r b71e69247483 -r 235d482ef6bc auto/unix
--- a/auto/unix	Mon May 01 19:16:05 2023 +0400
+++ b/auto/unix	Fri May 19 21:46:36 2023 +0400
@@ -448,6 +448,54 @@ ngx_feature_test="setsockopt(0, IPPROTO_
 . auto/feature
 
 
+# IP packet fragmentation
+
+ngx_feature="IP_MTU_DISCOVER"
+ngx_feature_name="NGX_HAVE_IP_MTU_DISCOVER"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+                  #include <netinet/in.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="(void) IP_PMTUDISC_DO;
+                  setsockopt(0, IPPROTO_IP, IP_MTU_DISCOVER, NULL, 0)"
+. auto/feature
+
+
+ngx_feature="IPV6_MTU_DISCOVER"
+ngx_feature_name="NGX_HAVE_IPV6_MTU_DISCOVER"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+                  #include <netinet/in.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="(void) IPV6_PMTUDISC_DO;
+                  setsockopt(0, IPPROTO_IPV6, IPV6_MTU_DISCOVER, NULL, 0)"
+. auto/feature
+
+
+ngx_feature="IP_DONTFRAG"
+ngx_feature_name="NGX_HAVE_IP_DONTFRAG"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+                  #include <netinet/in.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_DONTFRAG, NULL, 0)"
+. auto/feature
+
+
+ngx_feature="IPV6_DONTFRAG"
+ngx_feature_name="NGX_HAVE_IPV6_DONTFRAG"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+                  #include <netinet/in.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, IPPROTO_IP, IPV6_DONTFRAG, NULL, 0)"
+. auto/feature
+
+
 ngx_feature="TCP_DEFER_ACCEPT"
 ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT"
 ngx_feature_run=no
diff -r b71e69247483 -r 235d482ef6bc src/core/nginx.c
--- a/src/core/nginx.c	Mon May 01 19:16:05 2023 +0400
+++ b/src/core/nginx.c	Fri May 19 21:46:36 2023 +0400
@@ -680,6 +680,9 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, 
 
     ls = cycle->listening.elts;
     for (i = 0; i < cycle->listening.nelts; i++) {
+        if (ls[i].ignore) {
+            continue;
+        }
         p = ngx_sprintf(p, "%ud;", ls[i].fd);
     }
 
diff -r b71e69247483 -r 235d482ef6bc src/core/ngx_bpf.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/ngx_bpf.c	Fri May 19 21:46:36 2023 +0400
@@ -0,0 +1,143 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+#define NGX_BPF_LOGBUF_SIZE  (16 * 1024)
+
+
+static ngx_inline int
+ngx_bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size)
+{
+    return syscall(__NR_bpf, cmd, attr, size);
+}
+
+
+void
+ngx_bpf_program_link(ngx_bpf_program_t *program, const char *symbol, int fd)
+{
+    ngx_uint_t        i;
+    ngx_bpf_reloc_t  *rl;
+
+    rl = program->relocs;
+
+    for (i = 0; i < program->nrelocs; i++) {
+        if (ngx_strcmp(rl[i].name, symbol) == 0) {
+            program->ins[rl[i].offset].src_reg = 1;
+            program->ins[rl[i].offset].imm = fd;
+        }
+    }
+}
+
+
+int
+ngx_bpf_load_program(ngx_log_t *log, ngx_bpf_program_t *program)
+{
+    int             fd;
+    union bpf_attr  attr;
+#if (NGX_DEBUG)
+    char            buf[NGX_BPF_LOGBUF_SIZE];
+#endif
+
+    ngx_memzero(&attr, sizeof(union bpf_attr));
+
+    attr.license = (uintptr_t) program->license;
+    attr.prog_type = program->type;
+    attr.insns = (uintptr_t) program->ins;
+    attr.insn_cnt = program->nins;
+
+#if (NGX_DEBUG)
+    /* for verifier errors */
+    attr.log_buf = (uintptr_t) buf;
+    attr.log_size = NGX_BPF_LOGBUF_SIZE;
+    attr.log_level = 1;
+#endif
+
+    fd = ngx_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+    if (fd < 0) {
+        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+                      "failed to load BPF program");
+
+        ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
+                       "bpf verifier: %s", buf);
+
+        return -1;
+    }
+
+    return fd;
+}
+
+
+int
+ngx_bpf_map_create(ngx_log_t *log, enum bpf_map_type type, int key_size,
+    int value_size, int max_entries, uint32_t map_flags)
+{
+    int             fd;
+    union bpf_attr  attr;
+
+    ngx_memzero(&attr, sizeof(union bpf_attr));
+
+    attr.map_type = type;
+    attr.key_size = key_size;
+    attr.value_size = value_size;
+    attr.max_entries = max_entries;
+    attr.map_flags = map_flags;
+
+    fd = ngx_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
+    if (fd < 0) {
+        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+                      "failed to create BPF map");
+        return NGX_ERROR;
+    }
+
+    return fd;
+}
+
+
+int
+ngx_bpf_map_update(int fd, const void *key, const void *value, uint64_t flags)
+{
+    union bpf_attr attr;
+
+    ngx_memzero(&attr, sizeof(union bpf_attr));
+
+    attr.map_fd = fd;
+    attr.key = (uintptr_t) key;
+    attr.value = (uintptr_t) value;
+    attr.flags = flags;
+
+    return ngx_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
+}
+
+
+int
+ngx_bpf_map_delete(int fd, const void *key)
+{
+    union bpf_attr attr;
+
+    ngx_memzero(&attr, sizeof(union bpf_attr));
+
+    attr.map_fd = fd;
+    attr.key = (uintptr_t) key;
+
+    return ngx_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
+}
+
+
+int
+ngx_bpf_map_lookup(int fd, const void *key, void *value)
+{
+    union bpf_attr attr;
+
+    ngx_memzero(&attr, sizeof(union bpf_attr));
+
+    attr.map_fd = fd;
+    attr.key = (uintptr_t) key;
+    attr.value = (uintptr_t) value;
+
+    return ngx_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
+}
diff -r b71e69247483 -r 235d482ef6bc src/core/ngx_bpf.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/ngx_bpf.h	Fri May 19 21:46:36 2023 +0400
@@ -0,0 +1,43 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_BPF_H_INCLUDED_
+#define _NGX_BPF_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+#include <linux/bpf.h>
+
+
+typedef struct {
+    char                *name;
+    int                  offset;
+} ngx_bpf_reloc_t;
+
+typedef struct {
+    char                *license;
+    enum bpf_prog_type   type;
+    struct bpf_insn     *ins;
+    size_t               nins;
+    ngx_bpf_reloc_t     *relocs;
+    size_t               nrelocs;
+} ngx_bpf_program_t;
+
+
+void ngx_bpf_program_link(ngx_bpf_program_t *program, const char *symbol,
+    int fd);
+int ngx_bpf_load_program(ngx_log_t *log, ngx_bpf_program_t *program);
+
+int ngx_bpf_map_create(ngx_log_t *log, enum bpf_map_type type, int key_size,
+    int value_size, int max_entries, uint32_t map_flags);
+int ngx_bpf_map_update(int fd, const void *key, const void *value,
+    uint64_t flags);
+int ngx_bpf_map_delete(int fd, const void *key);
+int ngx_bpf_map_lookup(int fd, const void *key, void *value);
+
+#endif /* _NGX_BPF_H_INCLUDED_ */
diff -r b71e69247483 -r 235d482ef6bc src/core/ngx_connection.c
--- a/src/core/ngx_connection.c	Mon May 01 19:16:05 2023 +0400
+++ b/src/core/ngx_connection.c	Fri May 19 21:46:36 2023 +0400
@@ -1014,6 +1014,78 @@ ngx_configure_listening_sockets(ngx_cycl
         }
 
 #endif
+
+#if (NGX_HAVE_IP_MTU_DISCOVER)
+
+        if (ls[i].quic && ls[i].sockaddr->sa_family == AF_INET) {
+            value = IP_PMTUDISC_DO;
+
+            if (setsockopt(ls[i].fd, IPPROTO_IP, IP_MTU_DISCOVER,
+                           (const void *) &value, sizeof(int))
+                == -1)
+            {
+                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
+                              "setsockopt(IP_MTU_DISCOVER) "
+                              "for %V failed, ignored",
+                              &ls[i].addr_text);
+            }
+        }
+
+#elif (NGX_HAVE_IP_DONTFRAG)
+
+        if (ls[i].quic && ls[i].sockaddr->sa_family == AF_INET) {
+            value = 1;
+
+            if (setsockopt(ls[i].fd, IPPROTO_IP, IP_DONTFRAG,
+                           (const void *) &value, sizeof(int))
+                == -1)
+            {
+                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
+                              "setsockopt(IP_DONTFRAG) "
+                              "for %V failed, ignored",
+                              &ls[i].addr_text);
+            }
+        }
+
+#endif
+
+#if (NGX_HAVE_INET6)
+
+#if (NGX_HAVE_IPV6_MTU_DISCOVER)
+
+        if (ls[i].quic && ls[i].sockaddr->sa_family == AF_INET6) {
+            value = IPV6_PMTUDISC_DO;
+
+            if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+                           (const void *) &value, sizeof(int))
+                == -1)
+            {
+                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
+                              "setsockopt(IPV6_MTU_DISCOVER) "
+                              "for %V failed, ignored",
+                              &ls[i].addr_text);
+            }
+        }
+
+#elif (NGX_HAVE_IP_DONTFRAG)
+
+        if (ls[i].quic && ls[i].sockaddr->sa_family == AF_INET6) {
+            value = 1;
+
+            if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_DONTFRAG,
+                           (const void *) &value, sizeof(int))
+                == -1)
+            {
+                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
+                              "setsockopt(IPV6_DONTFRAG) "
+                              "for %V failed, ignored",
+                              &ls[i].addr_text);
+            }
+        }
+
+#endif
+
+#endif
     }
 
     return;
@@ -1037,6 +1109,12 @@ ngx_close_listening_sockets(ngx_cycle_t 
     ls = cycle->listening.elts;
     for (i = 0; i < cycle->listening.nelts; i++) {
 
+#if (NGX_QUIC)
+        if (ls[i].quic) {
+            continue;
+        }
+#endif
+
         c = ls[i].connection;
 
         if (c) {
diff -r b71e69247483 -r 235d482ef6bc src/core/ngx_connection.h
--- a/src/core/ngx_connection.h	Mon May 01 19:16:05 2023 +0400
+++ b/src/core/ngx_connection.h	Fri May 19 21:46:36 2023 +0400
@@ -73,6 +73,7 @@ struct ngx_listening_s {
     unsigned            reuseport:1;
     unsigned            add_reuseport:1;
     unsigned            keepalive:2;
+    unsigned            quic:1;
 
     unsigned            deferred_accept:1;
     unsigned            delete_deferred:1;
@@ -147,6 +148,10 @@ struct ngx_connection_s {
 
     ngx_proxy_protocol_t  *proxy_protocol;
 
+#if (NGX_QUIC || NGX_COMPAT)
+    ngx_quic_stream_t     *quic;
+#endif
+
 #if (NGX_SSL || NGX_COMPAT)
     ngx_ssl_connection_t  *ssl;
 #endif
diff -r b71e69247483 -r 235d482ef6bc src/core/ngx_core.h
--- a/src/core/ngx_core.h	Mon May 01 19:16:05 2023 +0400
+++ b/src/core/ngx_core.h	Fri May 19 21:46:36 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;
 typedef struct ngx_proxy_protocol_s  ngx_proxy_protocol_t;
+typedef struct ngx_quic_stream_s     ngx_quic_stream_t;
 typedef struct ngx_ssl_connection_s  ngx_ssl_connection_t;
 typedef struct ngx_udp_connection_s  ngx_udp_connection_t;
 
@@ -82,6 +83,9 @@ typedef void (*ngx_connection_handler_pt
 #include <ngx_resolver.h>
 #if (NGX_OPENSSL)
 #include <ngx_event_openssl.h>
+#if (NGX_QUIC)
+#include <ngx_event_quic.h>
+#endif
 #endif
 #include <ngx_process_cycle.h>
 #include <ngx_conf_file.h>
@@ -91,6 +95,9 @@ typedef void (*ngx_connection_handler_pt
 #include <ngx_connection.h>
 #include <ngx_syslog.h>
 #include <ngx_proxy_protocol.h>
+#if (NGX_HAVE_BPF)
+#include <ngx_bpf.h>
+#endif
 
 
 #define LF     (u_char) '\n'
diff -r b71e69247483 -r 235d482ef6bc src/event/ngx_event.c
--- a/src/event/ngx_event.c	Mon May 01 19:16:05 2023 +0400
+++ b/src/event/ngx_event.c	Fri May 19 21:46:36 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)
 {
+#if (NGX_QUIC)
+
+    ngx_connection_t  *c;
+
+    c = rev->data;
+
+    if (c->quic) {
+        return NGX_OK;
+    }
+
+#endif
+
     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
 
         /* kqueue, epoll */
@@ -337,9 +349,15 @@ ngx_handle_write_event(ngx_event_t *wev,
 {
     ngx_connection_t  *c;
 
+    c = wev->data;
+
+#if (NGX_QUIC)
+    if (c->quic) {
+        return NGX_OK;
+    }
+#endif
+
     if (lowat) {
-        c = wev->data;
-
         if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
             return NGX_ERROR;
         }
@@ -873,8 +891,16 @@ ngx_event_process_init(ngx_cycle_t *cycl
 
 #else
 
-        rev->handler = (c->type == SOCK_STREAM) ? ngx_event_accept
-                                                : ngx_event_recvmsg;
+        if (c->type == SOCK_STREAM) {
+            rev->handler = ngx_event_accept;
+
+#if (NGX_QUIC)
+        } else if (ls[i].quic) {
+            rev->handler = ngx_quic_recvmsg;
+#endif
+        } else {
+            rev->handler = ngx_event_recvmsg;
+        }
 
 #if (NGX_HAVE_REUSEPORT)
 
diff -r b71e69247483 -r 235d482ef6bc src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c	Mon May 01 19:16:05 2023 +0400
+++ b/src/event/ngx_event_openssl.c	Fri May 19 21:46:36 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;
 
+#if (NGX_QUIC)
+    if (c->quic) {
+        /* QUIC streams inherit SSL object */
+        return NGX_OK;
+    }
+#endif
+
     rc = NGX_OK;
 
     ngx_ssl_ocsp_cleanup(c);
diff -r b71e69247483 -r 235d482ef6bc src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h	Mon May 01 19:16:05 2023 +0400
+++ b/src/event/ngx_event_openssl.h	Fri May 19 21:46:36 2023 +0400
@@ -24,6 +24,14 @@
 #include <openssl/engine.h>
 #endif
 #include <openssl/evp.h>
+#if (NGX_QUIC)
+#ifdef OPENSSL_IS_BORINGSSL
+#include <openssl/hkdf.h>
+#include <openssl/chacha.h>
+#else
+#include <openssl/kdf.h>
+#endif
+#endif
 #include <openssl/hmac.h>
 #ifndef OPENSSL_NO_OCSP
 #include <openssl/ocsp.h>
@@ -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 b71e69247483 -r 235d482ef6bc src/event/ngx_event_udp.c
--- a/src/event/ngx_event_udp.c	Mon May 01 19:16:05 2023 +0400
+++ b/src/event/ngx_event_udp.c	Fri May 19 21:46:36 2023 +0400
@@ -12,13 +12,6 @@
 
 #if !(NGX_WIN32)
 
-struct ngx_udp_connection_s {
-    ngx_rbtree_node_t   node;
-    ngx_connection_t   *connection;
-    ngx_buf_t          *buffer;
-};
-
-
 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);
@@ -424,8 +417,8 @@ ngx_udp_rbtree_insert_value(ngx_rbtree_n
             udpt = (ngx_udp_connection_t *) temp;
             ct = udpt->connection;
 
-            rc = ngx_cmp_sockaddr(c->sockaddr, c->socklen,
-                                  ct->sockaddr, ct->socklen, 1);
+            rc = ngx_memn2cmp(udp->key.data, udpt->key.data,
+                              udp->key.len, udpt->key.len);
 
             if (rc == 0 && c->listening->wildcard) {
                 rc = ngx_cmp_sockaddr(c->local_sockaddr, c->local_socklen,
@@ -478,6 +471,8 @@ ngx_insert_udp_connection(ngx_connection
     ngx_crc32_final(hash);
 
     udp->node.key = hash;
+    udp->key.data = (u_char *) c->sockaddr;
+    udp->key.len = c->socklen;
 
     cln = ngx_pool_cleanup_add(c->pool, 0);
     if (cln == NULL) {
diff -r b71e69247483 -r 235d482ef6bc src/event/ngx_event_udp.h
--- a/src/event/ngx_event_udp.h	Mon May 01 19:16:05 2023 +0400
+++ b/src/event/ngx_event_udp.h	Fri May 19 21:46:36 2023 +0400
@@ -23,6 +23,14 @@
 #endif
 
 
+struct ngx_udp_connection_s {
+    ngx_rbtree_node_t   node;
+    ngx_connection_t   *connection;
+    ngx_buf_t          *buffer;
+    ngx_str_t           key;
+};
+
+
 #if (NGX_HAVE_ADDRINFO_CMSG)
 
 typedef union {
diff -r b71e69247483 -r 235d482ef6bc src/event/quic/bpf/bpfgen.sh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/event/quic/bpf/bpfgen.sh	Fri May 19 21:46:36 2023 +0400
@@ -0,0 +1,113 @@
+#!/bin/bash
+
+export LANG=C
+
+set -e
+
+if [ $# -lt 1 ]; then
+    echo "Usage: PROGNAME=foo LICENSE=bar $0 <bpf object file>"
+    exit 1
+fi
+
+
+self=$0
+filename=$1
+funcname=$PROGNAME
+
+generate_head()
+{
+    cat << END
+/* AUTO-GENERATED, DO NOT EDIT. */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "ngx_bpf.h"
+
+
+END
+}
+
+generate_tail()
+{
+    cat << END
+
+ngx_bpf_program_t $PROGNAME = {
+    .relocs = bpf_reloc_prog_$funcname,
+    .nrelocs = sizeof(bpf_reloc_prog_$funcname)
+               / sizeof(bpf_reloc_prog_$funcname[0]),
+    .ins = bpf_insn_prog_$funcname,
+    .nins = sizeof(bpf_insn_prog_$funcname)
+            / sizeof(bpf_insn_prog_$funcname[0]),
+    .license = "$LICENSE",
+    .type = BPF_PROG_TYPE_SK_REUSEPORT,


More information about the nginx-devel mailing list