diff options
author | Roman Arutyunyan <arut@nginx.com> | 2023-05-19 21:46:36 +0400 |
---|---|---|
committer | Roman Arutyunyan <arut@nginx.com> | 2023-05-19 21:46:36 +0400 |
commit | 4b0266174814e6cf60a275321121dbaab084ee64 (patch) | |
tree | 1c47a0b456cb1bb6d6dd08aa2d94342d738b56c6 /src/core | |
parent | 1a8ef991d92d22eb8aded7f49595dd31a639e8a4 (diff) | |
parent | 94941bd840ce7b011a36f7fe33f3fc7f4c600688 (diff) | |
download | nginx-4b0266174814e6cf60a275321121dbaab084ee64.tar.gz nginx-4b0266174814e6cf60a275321121dbaab084ee64.zip |
Merged with the quic branch.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/nginx.c | 3 | ||||
-rw-r--r-- | src/core/ngx_bpf.c | 143 | ||||
-rw-r--r-- | src/core/ngx_bpf.h | 43 | ||||
-rw-r--r-- | src/core/ngx_connection.c | 78 | ||||
-rw-r--r-- | src/core/ngx_connection.h | 5 | ||||
-rw-r--r-- | src/core/ngx_core.h | 7 |
6 files changed, 279 insertions, 0 deletions
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); } diff --git a/src/core/ngx_bpf.c b/src/core/ngx_bpf.c new file mode 100644 index 000000000..363a02c7d --- /dev/null +++ b/src/core/ngx_bpf.c @@ -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 --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 <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 --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 36823451a..10f4d9b91 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -1014,6 +1014,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 } return; @@ -1037,6 +1109,12 @@ 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; if (c) { diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index 36e1be27c..c90f0ea50 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -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 --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 7ecdca0cb..88db7dc98 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -27,6 +27,7 @@ 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; @@ -82,6 +83,9 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #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)(ngx_connection_t *c); #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' |