details: https://hg.nginx.org/nginx/rev/235d482ef6bc
branches:
changeset: 9110:235d482ef6bc
user: Roman Arutyunyan <arut@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,
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel