From 26ac1c73f0fe90c77cbad84a6b4ef5712e35ba52 Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Fri, 28 Feb 2020 13:09:51 +0300 Subject: Initial QUIC support in http. --- src/core/ngx_connection.h | 7 ++++--- src/core/ngx_core.h | 36 +++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 20 deletions(-) (limited to 'src/core') diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index ad6556d0c..0d7e2166b 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -147,13 +147,14 @@ struct ngx_connection_s { socklen_t socklen; ngx_str_t addr_text; - ngx_proxy_protocol_t *proxy_protocol; + ngx_proxy_protocol_t *proxy_protocol; #if (NGX_SSL || NGX_COMPAT) - ngx_ssl_connection_t *ssl; + ngx_quic_connection_t *quic; + ngx_ssl_connection_t *ssl; #endif - ngx_udp_connection_t *udp; + ngx_udp_connection_t *udp; struct sockaddr *local_sockaddr; socklen_t local_socklen; diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 7ecdca0cb..549fae084 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -12,23 +12,24 @@ #include -typedef struct ngx_module_s ngx_module_t; -typedef struct ngx_conf_s ngx_conf_t; -typedef struct ngx_cycle_s ngx_cycle_t; -typedef struct ngx_pool_s ngx_pool_t; -typedef struct ngx_chain_s ngx_chain_t; -typedef struct ngx_log_s ngx_log_t; -typedef struct ngx_open_file_s ngx_open_file_t; -typedef struct ngx_command_s ngx_command_t; -typedef struct ngx_file_s ngx_file_t; -typedef struct ngx_event_s ngx_event_t; -typedef struct ngx_event_aio_s ngx_event_aio_t; -typedef struct ngx_connection_s ngx_connection_t; -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_ssl_connection_s ngx_ssl_connection_t; -typedef struct ngx_udp_connection_s ngx_udp_connection_t; +typedef struct ngx_module_s ngx_module_t; +typedef struct ngx_conf_s ngx_conf_t; +typedef struct ngx_cycle_s ngx_cycle_t; +typedef struct ngx_pool_s ngx_pool_t; +typedef struct ngx_chain_s ngx_chain_t; +typedef struct ngx_log_s ngx_log_t; +typedef struct ngx_open_file_s ngx_open_file_t; +typedef struct ngx_command_s ngx_command_t; +typedef struct ngx_file_s ngx_file_t; +typedef struct ngx_event_s ngx_event_t; +typedef struct ngx_event_aio_s ngx_event_aio_t; +typedef struct ngx_connection_s ngx_connection_t; +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_connection_s ngx_quic_connection_t; +typedef struct ngx_ssl_connection_s ngx_ssl_connection_t; +typedef struct ngx_udp_connection_s ngx_udp_connection_t; typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); @@ -82,6 +83,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #include #if (NGX_OPENSSL) #include +#include #endif #include #include -- cgit From 4f4f56f013eb0dbe5eb66bb2f22584aec26b13e6 Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Thu, 12 Mar 2020 16:54:43 +0300 Subject: HTTP/QUIC interface reworked. - events handling moved into src/event/ngx_event_quic.c - http invokes once ngx_quic_run() and passes stream callback (diff to original http_request.c is now minimal) - streams are stored in rbtree using ID as a key - when a new stream is registered, appropriate callback is called - ngx_quic_stream_t type represents STREAM and stored in c->qs --- src/core/ngx_connection.h | 1 + src/core/ngx_core.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src/core') diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index 0d7e2166b..b3a36cf05 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -151,6 +151,7 @@ struct ngx_connection_s { #if (NGX_SSL || NGX_COMPAT) ngx_quic_connection_t *quic; + ngx_quic_stream_t *qs; ngx_ssl_connection_t *ssl; #endif diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 549fae084..4594b54fd 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -28,6 +28,7 @@ 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_connection_s ngx_quic_connection_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; -- cgit From 11dfc1c9439a79881c2d2e73ab1e2c5c71f88499 Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Fri, 13 Mar 2020 20:44:32 +0300 Subject: Fixed sanitizer errors. --- src/core/ngx_connection.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/core') diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 33682532a..9ec1cd7ac 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -1178,11 +1178,6 @@ ngx_close_connection(ngx_connection_t *c) ngx_uint_t log_error, level; ngx_socket_t fd; - if (c->fd == (ngx_socket_t) -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); - return; - } - if (c->read->timer_set) { ngx_del_timer(c->read); } @@ -1191,7 +1186,7 @@ ngx_close_connection(ngx_connection_t *c) ngx_del_timer(c->write); } - if (!c->shared) { + if (!c->shared && c->fd != (ngx_socket_t) -1) { if (ngx_del_conn) { ngx_del_conn(c, NGX_CLOSE_EVENT); @@ -1223,6 +1218,11 @@ ngx_close_connection(ngx_connection_t *c) ngx_free_connection(c); + if (c->fd == (ngx_socket_t) -1) { + ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, "connection has no fd"); + return; + } + fd = c->fd; c->fd = (ngx_socket_t) -1; -- cgit From d0ebfa4cb97dc212aac4cde740286bc4e4cde30e Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Mon, 16 Mar 2020 19:00:47 +0300 Subject: Split transport and crypto parts into separate files. New files: src/event/ngx_event_quic_protection.h src/event/ngx_event_quic_protection.c The protection.h header provides interface to the crypto part of the QUIC: 2 functions to initialize corresponding secrets: ngx_quic_set_initial_secret() ngx_quic_set_encryption_secret() and 2 functions to deal with packet processing: ngx_quic_encrypt() ngx_quic_decrypt() Also, structures representing secrets are defined there. All functions require SSL connection and a pool, only crypto operations inside, no access to nginx connections or events. Currently pool->log is used for the logging (instead of original c->log). --- src/core/ngx_core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 4594b54fd..a5f7b7af5 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -85,6 +85,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #if (NGX_OPENSSL) #include #include +#include #endif #include #include -- cgit From 23dc6a68a4c94300896c76e2161d18d11d89d3ee Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Wed, 18 Mar 2020 12:58:27 +0300 Subject: Extracted transport part of the code into separate file. All code dealing with serializing/deserializing is moved int srv/event/ngx_event_quic_transport.c/h file. All macros for dealing with data are internal to source file. The header file exposes frame types and error codes. The exported functions are currently packet header parsers and writers and frames parser/writer. The ngx_quic_header_t structure is updated with 'log' member. This avoids passing extra argument to parsing functions that need to report errors. --- src/core/ngx_core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index a5f7b7af5..eb3acd663 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -85,6 +85,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #if (NGX_OPENSSL) #include #include +#include #include #endif #include -- cgit From b7b3aca7040a0c734a555efd8775249a29b5ac5d Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Thu, 30 Apr 2020 15:47:43 +0300 Subject: Configure: unbreak with old OpenSSL, --with-http_v3_module added. --- src/core/ngx_core.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core') diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index eb3acd663..a8959ddcc 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -84,10 +84,12 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #include #if (NGX_OPENSSL) #include +#if (NGX_OPENSSL_QUIC) #include #include #include #endif +#endif #include #include #include -- cgit From 9d465009149c67325d9ac49503891cc84e5eaef8 Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Tue, 23 Jun 2020 11:57:00 +0300 Subject: Do not close QUIC sockets in ngx_close_listening_sockets(). This breaks graceful shutdown of QUIC connections in terms of quic-transport. --- src/core/ngx_connection.c | 4 ++++ src/core/ngx_connection.h | 1 + 2 files changed, 5 insertions(+) (limited to 'src/core') diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 9ec1cd7ac..5bae54502 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -1034,6 +1034,10 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle) ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { + if (ls[i].quic) { + continue; + } + c = ls[i].connection; if (c) { diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index b3a36cf05..294d4b212 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -75,6 +75,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; -- cgit From b813b9ec358862a2a94868bc057420d6eca5c05d Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Tue, 21 Jul 2020 23:09:22 +0300 Subject: QUIC: added "quic" listen parameter. The parameter allows processing HTTP/0.9-2 over QUIC. Also, introduced ngx_http_quic_module and moved QUIC settings there --- src/core/ngx_connection.c | 2 ++ src/core/ngx_connection.h | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index ba07c63e8..1fb569d30 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -1034,9 +1034,11 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle) 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; diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index 294d4b212..2ce0f153b 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -150,9 +150,12 @@ struct ngx_connection_s { ngx_proxy_protocol_t *proxy_protocol; -#if (NGX_SSL || NGX_COMPAT) +#if (NGX_QUIC || NGX_COMPAT) ngx_quic_connection_t *quic; ngx_quic_stream_t *qs; +#endif + +#if (NGX_SSL || NGX_COMPAT) ngx_ssl_connection_t *ssl; #endif -- cgit From ca0b9871bc74d7d4548d76eb4d4c2a3a5ebb22ec Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Wed, 22 Jul 2020 14:48:49 +0300 Subject: QUIC: fixed bulding perl module by reducing header pollution. The ngx_http_perl_module module doesn't have a notion of including additional search paths through --with-cc-opt, which results in compile error incomplete type 'enum ssl_encryption_level_t' when building nginx without QUIC support. The enum is visible from quic event headers and eventually pollutes ngx_core.h. The fix is to limit including headers to compile units that are real consumers. --- src/core/ngx_core.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core') diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index a8959ddcc..ade35be73 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -86,8 +86,6 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #include #if (NGX_OPENSSL_QUIC) #include -#include -#include #endif #endif #include -- cgit From 4b41b1478f108800d30bff981204bb0b85fc809e Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Tue, 10 Nov 2020 18:38:42 +0000 Subject: QUIC: got rid of the c->quic field. Now QUIC connection is accessed via the c->udp field. --- src/core/ngx_connection.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core') diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index 2ce0f153b..a075d84a3 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -151,7 +151,6 @@ struct ngx_connection_s { ngx_proxy_protocol_t *proxy_protocol; #if (NGX_QUIC || NGX_COMPAT) - ngx_quic_connection_t *quic; ngx_quic_stream_t *qs; #endif -- cgit From 2fd31c8959fbae8f069d09b61f339358214e75d1 Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Tue, 10 Nov 2020 19:40:00 +0000 Subject: QUIC: renamed c->qs to c->quic. --- src/core/ngx_connection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index a075d84a3..3ac6205e2 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -151,7 +151,7 @@ struct ngx_connection_s { ngx_proxy_protocol_t *proxy_protocol; #if (NGX_QUIC || NGX_COMPAT) - ngx_quic_stream_t *qs; + ngx_quic_stream_t *quic; #endif #if (NGX_SSL || NGX_COMPAT) -- cgit From 375b47efb3558c7871c61f682547c2f3a5fc9992 Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Fri, 13 Nov 2020 15:11:27 +0000 Subject: Core: reduced diff to the default branch. It became feasible to reduce after feec2cc762f6 that removes ngx_quic_connection_t from ngx_connection_s. --- src/core/ngx_connection.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core') diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index 3ac6205e2..edc1ccbc2 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -148,17 +148,17 @@ struct ngx_connection_s { socklen_t socklen; ngx_str_t addr_text; - ngx_proxy_protocol_t *proxy_protocol; + ngx_proxy_protocol_t *proxy_protocol; #if (NGX_QUIC || NGX_COMPAT) - ngx_quic_stream_t *quic; + ngx_quic_stream_t *quic; #endif #if (NGX_SSL || NGX_COMPAT) - ngx_ssl_connection_t *ssl; + ngx_ssl_connection_t *ssl; #endif - ngx_udp_connection_t *udp; + ngx_udp_connection_t *udp; struct sockaddr *local_sockaddr; socklen_t local_socklen; -- cgit From 7046a10134a8b15c0c769197502663bfe67ed63b Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Fri, 13 Nov 2020 15:11:29 +0000 Subject: Core: hide "struct ngx_quic_connection_s" and further reduce diffs. As with the previous change, it became feasible with feec2cc762f6 that removes ngx_quic_connection_t from ngx_connection_s. --- src/core/ngx_core.h | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'src/core') diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index ade35be73..8e6c756c9 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -12,25 +12,24 @@ #include -typedef struct ngx_module_s ngx_module_t; -typedef struct ngx_conf_s ngx_conf_t; -typedef struct ngx_cycle_s ngx_cycle_t; -typedef struct ngx_pool_s ngx_pool_t; -typedef struct ngx_chain_s ngx_chain_t; -typedef struct ngx_log_s ngx_log_t; -typedef struct ngx_open_file_s ngx_open_file_t; -typedef struct ngx_command_s ngx_command_t; -typedef struct ngx_file_s ngx_file_t; -typedef struct ngx_event_s ngx_event_t; -typedef struct ngx_event_aio_s ngx_event_aio_t; -typedef struct ngx_connection_s ngx_connection_t; -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_connection_s ngx_quic_connection_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; +typedef struct ngx_module_s ngx_module_t; +typedef struct ngx_conf_s ngx_conf_t; +typedef struct ngx_cycle_s ngx_cycle_t; +typedef struct ngx_pool_s ngx_pool_t; +typedef struct ngx_chain_s ngx_chain_t; +typedef struct ngx_log_s ngx_log_t; +typedef struct ngx_open_file_s ngx_open_file_t; +typedef struct ngx_command_s ngx_command_t; +typedef struct ngx_file_s ngx_file_t; +typedef struct ngx_event_s ngx_event_t; +typedef struct ngx_event_aio_s ngx_event_aio_t; +typedef struct ngx_connection_s ngx_connection_t; +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; typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); -- cgit From b20b58ca7d1323664c5e8f91231ade0edf0d0f31 Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Tue, 15 Dec 2020 15:23:07 +0300 Subject: Core: added interface to linux bpf() system call. It contains wrappers for operations with BPF maps and for loading BPF programs. --- src/core/ngx_bpf.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/core/ngx_bpf.h | 43 ++++++++++++++++ src/core/ngx_core.h | 3 ++ 3 files changed, 189 insertions(+) create mode 100644 src/core/ngx_bpf.c create mode 100644 src/core/ngx_bpf.h (limited to 'src/core') diff --git a/src/core/ngx_bpf.c b/src/core/ngx_bpf.c new file mode 100644 index 000000000..6b2611708 --- /dev/null +++ b/src/core/ngx_bpf.c @@ -0,0 +1,143 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + + +#include +#include + +#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 = (uint64_t) program->license; + attr.prog_type = program->type; + attr.insns = (uint64_t) program->ins; + attr.insn_cnt = program->nins; + +#if (NGX_DEBUG) + /* for verifier errors */ + attr.log_buf = (uint64_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 = (uint64_t) key; + attr.value = (uint64_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 = (uint64_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 = (uint64_t) key; + attr.value = (uint64_t) value; + + return ngx_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); +} diff --git a/src/core/ngx_bpf.h b/src/core/ngx_bpf.h new file mode 100644 index 000000000..f62a36e11 --- /dev/null +++ b/src/core/ngx_bpf.h @@ -0,0 +1,43 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_BPF_H_INCLUDED_ +#define _NGX_BPF_H_INCLUDED_ + + +#include +#include + +#include + + +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 --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 8e6c756c9..256836546 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -95,6 +95,9 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #include #include #include +#if (NGX_HAVE_BPF) +#include +#endif #define LF (u_char) '\n' -- cgit From c4f31ccca174ff617a594b49ef255354e979b72d Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Fri, 25 Dec 2020 15:01:15 +0300 Subject: QUIC: ngx_quic_bpf module. The quic kernel bpf helper inspects packet payload for DCID, extracts key and routes the packet into socket matching the key. Due to reuseport feature, each worker owns a personal socket, which is identified by the same key, used to create DCID. BPF objects are locked in RAM and are subject to RLIMIT_MEMLOCK. The "ulimit -l" command may be used to setup proper limits, if maps cannot be created with EPERM or updated with ETOOLONG. --- src/core/nginx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core') diff --git a/src/core/nginx.c b/src/core/nginx.c index 48a20e9fd..062ab0898 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -680,6 +680,9 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv) 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); } -- cgit From d8fd0b31619ed7302690abf1b27a7c7ec99fbc9d Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Tue, 23 Mar 2021 10:58:18 +0300 Subject: Core: fixed build with BPF on non-64bit platforms (ticket #2152). --- src/core/ngx_bpf.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/core') diff --git a/src/core/ngx_bpf.c b/src/core/ngx_bpf.c index 6b2611708..363a02c7d 100644 --- a/src/core/ngx_bpf.c +++ b/src/core/ngx_bpf.c @@ -45,14 +45,14 @@ ngx_bpf_load_program(ngx_log_t *log, ngx_bpf_program_t *program) ngx_memzero(&attr, sizeof(union bpf_attr)); - attr.license = (uint64_t) program->license; + attr.license = (uintptr_t) program->license; attr.prog_type = program->type; - attr.insns = (uint64_t) program->ins; + attr.insns = (uintptr_t) program->ins; attr.insn_cnt = program->nins; #if (NGX_DEBUG) /* for verifier errors */ - attr.log_buf = (uint64_t) buf; + attr.log_buf = (uintptr_t) buf; attr.log_size = NGX_BPF_LOGBUF_SIZE; attr.log_level = 1; #endif @@ -106,8 +106,8 @@ ngx_bpf_map_update(int fd, const void *key, const void *value, uint64_t flags) ngx_memzero(&attr, sizeof(union bpf_attr)); attr.map_fd = fd; - attr.key = (uint64_t) key; - attr.value = (uint64_t) value; + attr.key = (uintptr_t) key; + attr.value = (uintptr_t) value; attr.flags = flags; return ngx_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); @@ -122,7 +122,7 @@ ngx_bpf_map_delete(int fd, const void *key) ngx_memzero(&attr, sizeof(union bpf_attr)); attr.map_fd = fd; - attr.key = (uint64_t) key; + attr.key = (uintptr_t) key; return ngx_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr)); } @@ -136,8 +136,8 @@ ngx_bpf_map_lookup(int fd, const void *key, void *value) ngx_memzero(&attr, sizeof(union bpf_attr)); attr.map_fd = fd; - attr.key = (uint64_t) key; - attr.value = (uint64_t) value; + attr.key = (uintptr_t) key; + attr.value = (uintptr_t) value; return ngx_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); } -- cgit From 465362e0664a4fe31cb5df8e757bc99b3c68f5fa Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Mon, 6 Sep 2021 16:59:00 +0300 Subject: QUIC: store QUIC connection fd in stream fake connection. Previously it had -1 as fd. This fixes proxying, which relies on downstream connection having a real fd. Also, this reduces diff to the default branch for ngx_close_connection(). --- src/core/ngx_connection.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/core') diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 974f48c9a..4a7d2fe79 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -1185,6 +1185,11 @@ ngx_close_connection(ngx_connection_t *c) ngx_uint_t log_error, level; ngx_socket_t fd; + if (c->fd == (ngx_socket_t) -1) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); + return; + } + if (c->read->timer_set) { ngx_del_timer(c->read); } @@ -1193,7 +1198,7 @@ ngx_close_connection(ngx_connection_t *c) ngx_del_timer(c->write); } - if (!c->shared && c->fd != (ngx_socket_t) -1) { + if (!c->shared) { if (ngx_del_conn) { ngx_del_conn(c, NGX_CLOSE_EVENT); @@ -1225,11 +1230,6 @@ ngx_close_connection(ngx_connection_t *c) ngx_free_connection(c); - if (c->fd == (ngx_socket_t) -1) { - ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, "connection has no fd"); - return; - } - fd = c->fd; c->fd = (ngx_socket_t) -1; -- cgit From bd89c448b7e7beb15409e2abe2f174a36a7a0823 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 14 Sep 2021 12:09:13 +0300 Subject: Removed NGX_OPENSSL_QUIC macro, NGX_QUIC is enough. --- src/core/ngx_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 256836546..88db7dc98 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -83,7 +83,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #include #if (NGX_OPENSSL) #include -#if (NGX_OPENSSL_QUIC) +#if (NGX_QUIC) #include #endif #endif -- cgit From 9d81ef744cdaacf1e52bcaec4224d375af5ba59b Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Wed, 20 Apr 2022 16:01:17 +0400 Subject: QUIC: separate UDP framework for QUIC. Previously, QUIC used the existing UDP framework, which was created for UDP in Stream. However the way QUIC connections are created and looked up is different from the way UDP connections in Stream are created and looked up. Now these two implementations are decoupled. --- src/core/ngx_connection.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/core') diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 4a7d2fe79..cbd5803be 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -72,10 +72,6 @@ ngx_create_listening(ngx_conf_t *cf, struct sockaddr *sockaddr, ngx_memcpy(ls->addr_text.data, text, len); -#if !(NGX_WIN32) - ngx_rbtree_init(&ls->rbtree, &ls->sentinel, ngx_udp_rbtree_insert_value); -#endif - ls->fd = (ngx_socket_t) -1; ls->type = SOCK_STREAM; -- cgit From 1465a34067b927963b311136bf15a79981cb9d6e Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Sat, 6 May 2023 16:23:27 +0400 Subject: QUIC: disabled datagram fragmentation. As per RFC 9000, Section 14: UDP datagrams MUST NOT be fragmented at the IP layer. --- src/core/ngx_connection.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'src/core') diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 57c5a8aa1..5e5683928 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -1009,6 +1009,78 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle) } } +#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 } -- cgit From 0a3c79614521d7612b63eff4e09c25ed219fb65b Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Sun, 14 May 2023 12:30:11 +0400 Subject: Common tree insert function for QUIC and UDP connections. Previously, ngx_udp_rbtree_insert_value() was used for plain UDP and ngx_quic_rbtree_insert_value() was used for QUIC. Because of this it was impossible to initialize connection tree in ngx_create_listening() since this function is not aware what kind of listening it creates. Now ngx_udp_rbtree_insert_value() is used for both QUIC and UDP. To make is possible, a generic key field is added to ngx_udp_connection_t. It keeps client address for UDP and connection ID for QUIC. --- src/core/ngx_connection.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/core') diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 5e5683928..10f4d9b91 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -72,6 +72,10 @@ ngx_create_listening(ngx_conf_t *cf, struct sockaddr *sockaddr, ngx_memcpy(ls->addr_text.data, text, len); +#if !(NGX_WIN32) + ngx_rbtree_init(&ls->rbtree, &ls->sentinel, ngx_udp_rbtree_insert_value); +#endif + ls->fd = (ngx_socket_t) -1; ls->type = SOCK_STREAM; -- cgit