details: https://hg.nginx.org/nginx/rev/235d482ef6bc branches: changeset: 9110:235d482ef6bc user: Roman Arutyunyan <a...@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