mirror of
https://github.com/nginx/nginx.git
synced 2026-10-20 19:11:05 +00:00
QUIC: support BPF reload and binary upgrade
Some checks are pending
buildbot / buildbot (push) Waiting to run
Some checks are pending
buildbot / buildbot (push) Waiting to run
The SO_COOKIE dependency is removed. QUIC BPF dispatching now uses separate sockets for new and established connections: listener sockets handle new connections, while per-worker sockets handle established ones. Server connection IDs encode a random worker key, which BPF uses to route established packets directly to the correct worker socket. New connections are routed through listen keys using a dual slot scheme that enables both reload and binary upgrade. On reload, new workers register new sockets and keys while old workers continue receiving established connections through their encoded keys. On binary upgrade, the new master uses the opposite slot, and exiting masters clear their entries so traffic shifts to the surviving instance. Co-authored-by: Roman Arutyunyan <arut@nginx.com>
This commit is contained in:
parent
ce6e7d6c12
commit
63af971a1e
17 changed files with 1079 additions and 283 deletions
|
|
@ -1455,11 +1455,11 @@ if [ $USE_OPENSSL_QUIC = YES ]; then
|
|||
|
||||
. auto/module
|
||||
|
||||
if [ $QUIC_BPF = YES -a $SO_COOKIE_FOUND = YES ]; then
|
||||
if [ $QUIC_BPF = YES ]; then
|
||||
ngx_module_type=CORE
|
||||
ngx_module_name=ngx_quic_bpf_module
|
||||
ngx_module_incs=
|
||||
ngx_module_deps=
|
||||
ngx_module_deps=src/event/quic/ngx_event_quic_bpf.h
|
||||
ngx_module_srcs="src/event/quic/ngx_event_quic_bpf.c \
|
||||
src/event/quic/ngx_event_quic_bpf_code.c"
|
||||
ngx_module_libs=
|
||||
|
|
|
|||
|
|
@ -178,8 +178,6 @@ USE_GEOIP=NO
|
|||
NGX_GOOGLE_PERFTOOLS=NO
|
||||
NGX_CPP_TEST=NO
|
||||
|
||||
SO_COOKIE_FOUND=NO
|
||||
|
||||
NGX_LIBATOMIC=NO
|
||||
|
||||
NGX_CPU_CACHE_LINE=
|
||||
|
|
|
|||
|
|
@ -249,7 +249,10 @@ 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);
|
||||
|
||||
attr.map_flags = 0;
|
||||
attr.map_type = BPF_MAP_TYPE_ARRAY;
|
||||
syscall(__NR_bpf, 0, &attr, 0);"
|
||||
. auto/feature
|
||||
|
||||
|
|
@ -263,23 +266,6 @@ if [ $ngx_found = yes ]; then
|
|||
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"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
#define NGX_BPF_LOGBUF_SIZE (16 * 1024)
|
||||
#define NGX_BPF_LOGBUF_SIZE (32 * 1024)
|
||||
|
||||
|
||||
static ngx_inline int
|
||||
|
|
|
|||
|
|
@ -1142,7 +1142,9 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
|
|||
for (i = 0; i < cycle->listening.nelts; i++) {
|
||||
|
||||
#if (NGX_QUIC)
|
||||
if (ls[i].quic) {
|
||||
if (ls[i].quic
|
||||
&& (!ls[i].reuseport || !ngx_quic_bpf_enabled(cycle)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ struct ngx_event_s {
|
|||
/* to test on worker exit */
|
||||
unsigned channel:1;
|
||||
unsigned resolver:1;
|
||||
unsigned quic:1;
|
||||
|
||||
unsigned cancelable:1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
CFLAGS=-O2 -Wall
|
||||
|
||||
# Copyright (C) Nginx, Inc.
|
||||
|
||||
CFLAGS=-O2 -Wall $(MAKE_CFLAGS)
|
||||
|
||||
LICENSE=BSD
|
||||
|
||||
|
|
|
|||
|
|
@ -54,17 +54,23 @@ char _license[] SEC("license") = LICENSE;
|
|||
((__u64)(p)[6] << 8) | \
|
||||
((__u64)(p)[7]))
|
||||
|
||||
#define ngx_quic_bpf_listen_key(worker) \
|
||||
(((__u64) 0xFF << 56) | ((__u64) (worker) & 0xFFFFFFFFFFFFULL))
|
||||
|
||||
|
||||
/*
|
||||
* actual map object is created by the "bpf" system call,
|
||||
* all pointers to this variable are replaced by the bpf loader
|
||||
*/
|
||||
extern int ngx_quic_sockmap;
|
||||
struct {} ngx_quic_sockmap SEC(".maps");
|
||||
struct {} ngx_quic_worker_counts SEC(".maps");
|
||||
|
||||
|
||||
SEC(PROGNAME)
|
||||
int ngx_quic_select_socket_by_dcid(struct sk_reuseport_md *ctx)
|
||||
{
|
||||
int rc;
|
||||
int rc, worker_idx;
|
||||
__u32 wc_key, *wc0, *wc1, n, m;
|
||||
__u64 key;
|
||||
size_t offset;
|
||||
unsigned char *start, *end, *dcid, byte, buf[NGX_QUIC_SERVER_CID_LEN];
|
||||
|
|
@ -98,7 +104,7 @@ int ngx_quic_select_socket_by_dcid(struct sk_reuseport_md *ctx)
|
|||
}
|
||||
|
||||
if (byte != NGX_QUIC_SERVER_CID_LEN) {
|
||||
return SK_PASS;
|
||||
goto new;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -118,30 +124,84 @@ int ngx_quic_select_socket_by_dcid(struct sk_reuseport_md *ctx)
|
|||
|
||||
key = ngx_quic_parse_uint64(dcid);
|
||||
|
||||
rc = bpf_sk_select_reuseport(ctx, &ngx_quic_sockmap, &key, 0);
|
||||
|
||||
switch (rc) {
|
||||
case 0:
|
||||
debugmsg("nginx quic socket selected by key 0x%llx", key);
|
||||
return SK_PASS;
|
||||
|
||||
/* kernel returns positive error numbers, errno.h defines positive */
|
||||
case -ENOENT:
|
||||
debugmsg("nginx quic default route for key 0x%llx", key);
|
||||
/* let the default reuseport logic decide which socket to choose */
|
||||
return SK_PASS;
|
||||
|
||||
default:
|
||||
debugmsg("nginx quic bpf_sk_select_reuseport err: %d key 0x%llx",
|
||||
rc, key);
|
||||
goto failed;
|
||||
if ((key >> 56) == 0xFF) {
|
||||
goto new;
|
||||
}
|
||||
|
||||
rc = bpf_sk_select_reuseport(ctx, &ngx_quic_sockmap, &key, 0);
|
||||
|
||||
if (rc == 0) {
|
||||
debugmsg("nginx quic worker socket selected by dcid");
|
||||
return SK_PASS;
|
||||
}
|
||||
|
||||
if (rc != -ENOENT) {
|
||||
debugmsg("nginx quic bpf_sk_select_reuseport() failed: %d", rc);
|
||||
return SK_DROP;
|
||||
}
|
||||
|
||||
new:
|
||||
|
||||
wc_key = 0;
|
||||
wc0 = bpf_map_lookup_elem(&ngx_quic_worker_counts, &wc_key);
|
||||
if (wc0 == NULL) {
|
||||
debugmsg("nginx quic worker count 0 undefined");
|
||||
return SK_DROP;
|
||||
}
|
||||
|
||||
wc_key = 1;
|
||||
wc1 = bpf_map_lookup_elem(&ngx_quic_worker_counts, &wc_key);
|
||||
if (wc1 == NULL) {
|
||||
debugmsg("nginx quic worker count 1 undefined");
|
||||
return SK_DROP;
|
||||
}
|
||||
|
||||
n = *wc0 > *wc1 ? *wc0 : *wc1;
|
||||
|
||||
if (n == 0) {
|
||||
debugmsg("nginx quic no active workers");
|
||||
return SK_DROP;
|
||||
}
|
||||
|
||||
worker_idx = ctx->hash % n;
|
||||
key = ngx_quic_bpf_listen_key(worker_idx);
|
||||
|
||||
rc = bpf_sk_select_reuseport(ctx, &ngx_quic_sockmap, &key, 0);
|
||||
|
||||
if (rc == 0) {
|
||||
debugmsg("nginx quic listener socket selected worker index:%d",
|
||||
worker_idx);
|
||||
return SK_PASS;
|
||||
}
|
||||
|
||||
if (rc != -ENOENT) {
|
||||
debugmsg("nginx quic bpf_sk_select_reuseport() failed: %d", rc);
|
||||
return SK_DROP;
|
||||
}
|
||||
|
||||
m = *wc0 < *wc1 ? *wc0 : *wc1;
|
||||
|
||||
if (m && m != n) {
|
||||
worker_idx = ctx->hash % m;
|
||||
key = ngx_quic_bpf_listen_key(worker_idx);
|
||||
|
||||
rc = bpf_sk_select_reuseport(ctx, &ngx_quic_sockmap, &key, 0);
|
||||
|
||||
if (rc == 0) {
|
||||
debugmsg("nginx quic listener socket selected "
|
||||
"worker index:%d (fallback)", worker_idx);
|
||||
return SK_PASS;
|
||||
}
|
||||
|
||||
debugmsg("nginx quic bpf_sk_select_reuseport() fallback "
|
||||
"failed: %d", rc);
|
||||
}
|
||||
|
||||
return SK_DROP;
|
||||
|
||||
failed:
|
||||
/*
|
||||
* SK_DROP will generate ICMP, but we may want to process "invalid" packet
|
||||
* in userspace quic to investigate further and finally react properly
|
||||
* (maybe ignore, maybe send something in response or close connection)
|
||||
*/
|
||||
return SK_PASS;
|
||||
|
||||
debugmsg("nginx quic bad datagram");
|
||||
|
||||
return SK_DROP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,4 +142,10 @@ ngx_int_t ngx_quic_get_packet_dcid(ngx_log_t *log, u_char *data, size_t len,
|
|||
ngx_int_t ngx_quic_derive_key(ngx_log_t *log, const char *label,
|
||||
ngx_str_t *secret, ngx_str_t *salt, u_char *out, size_t len);
|
||||
|
||||
#if (NGX_QUIC_BPF)
|
||||
ngx_uint_t ngx_quic_bpf_enabled(ngx_cycle_t *cycle);
|
||||
#else
|
||||
#define ngx_quic_bpf_enabled(c) 0
|
||||
#endif
|
||||
|
||||
#endif /* _NGX_EVENT_QUIC_H_INCLUDED_ */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
20
src/event/quic/ngx_event_quic_bpf.h
Normal file
20
src/event/quic/ngx_event_quic_bpf.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Nginx, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_EVENT_QUIC_BPF_H_INCLUDED_
|
||||
#define _NGX_EVENT_QUIC_BPF_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
ngx_int_t ngx_quic_bpf_get_worker_fd(ngx_connection_t *lc,
|
||||
ngx_socket_t *fd);
|
||||
ngx_int_t ngx_quic_bpf_get_worker_key(ngx_connection_t *c, uint64_t *key);
|
||||
|
||||
|
||||
#endif /* _NGX_EVENT_QUIC_BPF_H_INCLUDED_ */
|
||||
|
|
@ -7,93 +7,194 @@
|
|||
|
||||
|
||||
static ngx_bpf_reloc_t bpf_reloc_prog_ngx_quic_reuseport_helper[] = {
|
||||
{ "ngx_quic_sockmap", 77 },
|
||||
{ "ngx_quic_sockmap", 81 },
|
||||
{ "ngx_quic_worker_counts", 97 },
|
||||
{ "ngx_quic_worker_counts", 106 },
|
||||
{ "ngx_quic_sockmap", 133 },
|
||||
{ "ngx_quic_sockmap", 170 },
|
||||
};
|
||||
|
||||
static struct bpf_insn bpf_insn_prog_ngx_quic_reuseport_helper[] = {
|
||||
/* opcode dst src offset imm */
|
||||
{ 0xbf, BPF_REG_6, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x79, BPF_REG_8, BPF_REG_6, (int16_t) 8, 0x0 },
|
||||
{ 0x79, BPF_REG_7, BPF_REG_6, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_7, (int16_t) 0, 0x0 },
|
||||
{ 0x79, BPF_REG_9, BPF_REG_6, (int16_t) 8, 0x0 },
|
||||
{ 0x79, BPF_REG_8, BPF_REG_6, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_8, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x8 },
|
||||
{ 0x2d, BPF_REG_8, BPF_REG_1, (int16_t) 10, 0x0 },
|
||||
{ 0x2d, BPF_REG_9, BPF_REG_1, (int16_t) 11, 0x0 },
|
||||
{ 0xbf, BPF_REG_3, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff7 },
|
||||
{ 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xffffffef },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 },
|
||||
{ 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x8 },
|
||||
{ 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x1 },
|
||||
{ 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1a },
|
||||
{ 0xb7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x15, BPF_REG_0, BPF_REG_0, (int16_t) 1, 0x0 },
|
||||
{ 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 67, 0x0 },
|
||||
{ 0x71, BPF_REG_1, BPF_REG_10, (int16_t) 65527, 0x0 },
|
||||
{ 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 163, 0x0 },
|
||||
{ 0x71, BPF_REG_1, BPF_REG_10, (int16_t) 65519, 0x0 },
|
||||
{ 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 2, 0x0 },
|
||||
{ 0x71, BPF_REG_1, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x73, BPF_REG_10, BPF_REG_1, (int16_t) 65527, 0x0 },
|
||||
{ 0x73, BPF_REG_10, BPF_REG_1, (int16_t) 65519, 0x0 },
|
||||
{ 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x9 },
|
||||
{ 0x67, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x38 },
|
||||
{ 0xc7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x38 },
|
||||
{ 0x65, BPF_REG_1, BPF_REG_0, (int16_t) 18, 0xffffffff },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_7, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_8, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0xd },
|
||||
{ 0x2d, BPF_REG_8, BPF_REG_1, (int16_t) 11, 0x0 },
|
||||
{ 0x2d, BPF_REG_9, BPF_REG_1, (int16_t) 11, 0x0 },
|
||||
{ 0xbf, BPF_REG_3, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff7 },
|
||||
{ 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xffffffef },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 },
|
||||
{ 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xd },
|
||||
{ 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x1 },
|
||||
{ 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1a },
|
||||
{ 0x55, BPF_REG_0, BPF_REG_0, (int16_t) 49, 0x0 },
|
||||
{ 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xe },
|
||||
{ 0x71, BPF_REG_1, BPF_REG_10, (int16_t) 65527, 0x0 },
|
||||
{ 0x15, BPF_REG_1, BPF_REG_0, (int16_t) 5, 0x14 },
|
||||
{ 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 45, 0x0 },
|
||||
{ 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xe },
|
||||
{ 0xb7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x15, BPF_REG_0, BPF_REG_0, (int16_t) 1, 0x0 },
|
||||
{ 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 143, 0x0 },
|
||||
{ 0x71, BPF_REG_1, BPF_REG_10, (int16_t) 65519, 0x0 },
|
||||
{ 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 2, 0x0 },
|
||||
{ 0x71, BPF_REG_1, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x73, BPF_REG_10, BPF_REG_1, (int16_t) 65527, 0x0 },
|
||||
{ 0x55, BPF_REG_1, BPF_REG_0, (int16_t) 41, 0x14 },
|
||||
{ 0xf, BPF_REG_7, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_7, (int16_t) 0, 0x0 },
|
||||
{ 0x73, BPF_REG_10, BPF_REG_1, (int16_t) 65519, 0x0 },
|
||||
{ 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xe },
|
||||
{ 0x55, BPF_REG_1, BPF_REG_0, (int16_t) 52, 0x14 },
|
||||
{ 0xf, BPF_REG_8, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_8, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x14 },
|
||||
{ 0x3d, BPF_REG_8, BPF_REG_1, (int16_t) 7, 0x0 },
|
||||
{ 0xbf, BPF_REG_7, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0xffffffe3 },
|
||||
{ 0x3d, BPF_REG_9, BPF_REG_1, (int16_t) 8, 0x0 },
|
||||
{ 0xbf, BPF_REG_8, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_8, BPF_REG_0, (int16_t) 0, 0xffffffdb },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_3, BPF_REG_7, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_3, BPF_REG_8, (int16_t) 0, 0x0 },
|
||||
{ 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x14 },
|
||||
{ 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1a },
|
||||
{ 0x55, BPF_REG_0, BPF_REG_0, (int16_t) 30, 0x0 },
|
||||
{ 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 0, 0x0 },
|
||||
{ 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x38 },
|
||||
{ 0x71, BPF_REG_1, BPF_REG_7, (int16_t) 1, 0x0 },
|
||||
{ 0xb7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x55, BPF_REG_0, BPF_REG_0, (int16_t) 125, 0x0 },
|
||||
{ 0x71, BPF_REG_1, BPF_REG_8, (int16_t) 1, 0x0 },
|
||||
{ 0x67, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x30 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 2, 0x0 },
|
||||
{ 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x28 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 3, 0x0 },
|
||||
{ 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 4, 0x0 },
|
||||
{ 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x18 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 5, 0x0 },
|
||||
{ 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x10 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 6, 0x0 },
|
||||
{ 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x8 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 7, 0x0 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x7b, BPF_REG_10, BPF_REG_1, (int16_t) 65528, 0x0 },
|
||||
{ 0x71, BPF_REG_2, BPF_REG_8, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_3, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x67, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0x38 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_3, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_3, BPF_REG_8, (int16_t) 2, 0x0 },
|
||||
{ 0x67, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0x28 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_3, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_3, BPF_REG_8, (int16_t) 3, 0x0 },
|
||||
{ 0x67, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_3, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_3, BPF_REG_8, (int16_t) 4, 0x0 },
|
||||
{ 0x67, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0x18 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_3, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_3, BPF_REG_8, (int16_t) 5, 0x0 },
|
||||
{ 0x67, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0x10 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_3, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_3, BPF_REG_8, (int16_t) 7, 0x0 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_3, (int16_t) 0, 0x0 },
|
||||
{ 0x71, BPF_REG_3, BPF_REG_8, (int16_t) 6, 0x0 },
|
||||
{ 0x67, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0x8 },
|
||||
{ 0x4f, BPF_REG_1, BPF_REG_3, (int16_t) 0, 0x0 },
|
||||
{ 0x7b, BPF_REG_10, BPF_REG_1, (int16_t) 65520, 0x0 },
|
||||
{ 0x15, BPF_REG_2, BPF_REG_0, (int16_t) 15, 0xff },
|
||||
{ 0xbf, BPF_REG_3, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff8 },
|
||||
{ 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 },
|
||||
{ 0x18, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x52 },
|
||||
{ 0xb7, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1 },
|
||||
{ 0xb7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0x1 },
|
||||
{ 0x67, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x77, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x15, BPF_REG_0, BPF_REG_0, (int16_t) 89, 0x0 },
|
||||
{ 0x18, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0xfffffffe },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x1d, BPF_REG_0, BPF_REG_1, (int16_t) 1, 0x0 },
|
||||
{ 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 84, 0x0 },
|
||||
{ 0xb7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x63, BPF_REG_10, BPF_REG_7, (int16_t) 65532, 0x0 },
|
||||
{ 0xbf, BPF_REG_2, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xfffffffc },
|
||||
{ 0x18, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1 },
|
||||
{ 0xbf, BPF_REG_8, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x15, BPF_REG_8, BPF_REG_0, (int16_t) 76, 0x0 },
|
||||
{ 0xb7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x1 },
|
||||
{ 0x63, BPF_REG_10, BPF_REG_1, (int16_t) 65532, 0x0 },
|
||||
{ 0xbf, BPF_REG_2, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xfffffffc },
|
||||
{ 0x18, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1 },
|
||||
{ 0x15, BPF_REG_0, BPF_REG_0, (int16_t) 68, 0x0 },
|
||||
{ 0x61, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x61, BPF_REG_9, BPF_REG_8, (int16_t) 0, 0x0 },
|
||||
{ 0x2d, BPF_REG_9, BPF_REG_1, (int16_t) 1, 0x0 },
|
||||
{ 0xbf, BPF_REG_9, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x15, BPF_REG_9, BPF_REG_0, (int16_t) 63, 0x0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_9, (int16_t) 0, 0x0 },
|
||||
{ 0x67, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x77, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0xbf, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x61, BPF_REG_2, BPF_REG_6, (int16_t) 32, 0x0 },
|
||||
{ 0x9f, BPF_REG_2, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0xc7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x18, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0xffffffff },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0xffff },
|
||||
{ 0x5f, BPF_REG_2, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x18, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0xff000000 },
|
||||
{ 0x4f, BPF_REG_2, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x7b, BPF_REG_10, BPF_REG_2, (int16_t) 65520, 0x0 },
|
||||
{ 0xbf, BPF_REG_3, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 },
|
||||
{ 0x18, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x52 },
|
||||
{ 0xbf, BPF_REG_2, BPF_REG_7, (int16_t) 0, 0x0 },
|
||||
{ 0xb7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0x1 },
|
||||
{ 0x67, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x77, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x15, BPF_REG_0, BPF_REG_0, (int16_t) 36, 0x0 },
|
||||
{ 0x18, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0xfffffffe },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x1d, BPF_REG_0, BPF_REG_1, (int16_t) 1, 0x0 },
|
||||
{ 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 31, 0x0 },
|
||||
{ 0x61, BPF_REG_1, BPF_REG_8, (int16_t) 0, 0x0 },
|
||||
{ 0x61, BPF_REG_2, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x2d, BPF_REG_2, BPF_REG_1, (int16_t) 1, 0x0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 },
|
||||
{ 0x15, BPF_REG_1, BPF_REG_0, (int16_t) 26, 0x0 },
|
||||
{ 0x67, BPF_REG_9, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x77, BPF_REG_9, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x67, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x77, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x1d, BPF_REG_1, BPF_REG_9, (int16_t) 21, 0x0 },
|
||||
{ 0x61, BPF_REG_2, BPF_REG_6, (int16_t) 32, 0x0 },
|
||||
{ 0x9f, BPF_REG_2, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0xc7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x18, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0xffffffff },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0xffff },
|
||||
{ 0x5f, BPF_REG_2, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x18, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0xff000000 },
|
||||
{ 0x4f, BPF_REG_2, BPF_REG_1, (int16_t) 0, 0x0 },
|
||||
{ 0x7b, BPF_REG_10, BPF_REG_2, (int16_t) 65520, 0x0 },
|
||||
{ 0xbf, BPF_REG_3, BPF_REG_10, (int16_t) 0, 0x0 },
|
||||
{ 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff0 },
|
||||
{ 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 },
|
||||
{ 0x18, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x52 },
|
||||
{ 0x67, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x77, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x20 },
|
||||
{ 0x15, BPF_REG_0, BPF_REG_0, (int16_t) 1, 0x0 },
|
||||
{ 0xb7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
{ 0xbf, BPF_REG_0, BPF_REG_7, (int16_t) 0, 0x0 },
|
||||
{ 0x95, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ typedef struct ngx_quic_keys_s ngx_quic_keys_t;
|
|||
#include <ngx_event_quic_ack.h>
|
||||
#include <ngx_event_quic_output.h>
|
||||
#include <ngx_event_quic_socket.h>
|
||||
#if (NGX_QUIC_BPF)
|
||||
#include <ngx_event_quic_bpf.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* RFC 9002, 6.2.2. Handshakes and New Paths: kInitialRtt */
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ ngx_quic_create_server_id(ngx_connection_t *c, u_char *id)
|
|||
if (ngx_quic_bpf_attach_id(c, id) != NGX_OK) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
||||
"quic bpf failed to generate socket key");
|
||||
/* ignore error, things still may work */
|
||||
return NGX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -47,22 +47,21 @@ ngx_quic_create_server_id(ngx_connection_t *c, u_char *id)
|
|||
static ngx_int_t
|
||||
ngx_quic_bpf_attach_id(ngx_connection_t *c, u_char *id)
|
||||
{
|
||||
int fd;
|
||||
uint64_t cookie;
|
||||
socklen_t optlen;
|
||||
uint64_t key;
|
||||
ngx_int_t rc;
|
||||
|
||||
fd = c->listening->fd;
|
||||
rc = ngx_quic_bpf_get_worker_key(c, &key);
|
||||
|
||||
optlen = sizeof(cookie);
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_COOKIE, &cookie, &optlen) == -1) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
|
||||
"quic getsockopt(SO_COOKIE) failed");
|
||||
if (rc == NGX_DECLINED) {
|
||||
/* BPF not applicable for this listener, leave DCID as random */
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_quic_dcid_encode_key(id, cookie);
|
||||
ngx_quic_dcid_encode_key(id, key);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1085,7 +1085,6 @@ ngx_quic_send_retry(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
|||
pkt.odcid = inpkt->dcid;
|
||||
pkt.dcid = inpkt->scid;
|
||||
|
||||
/* TODO: generate routable dcid */
|
||||
if (RAND_bytes(dcid, NGX_QUIC_SERVER_CID_LEN) != 1) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ ngx_quic_recvmsg(ngx_event_t *ev)
|
|||
ngx_err_t err;
|
||||
socklen_t socklen, local_socklen;
|
||||
ngx_event_t *rev, *wev;
|
||||
ngx_socket_t cfd;
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
ngx_sockaddr_t sa, lsa;
|
||||
|
|
@ -168,7 +169,7 @@ ngx_quic_recvmsg(ngx_event_t *ev)
|
|||
c->log->handler = NULL;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic recvmsg: fd:%d n:%z", c->fd, n);
|
||||
"quic recvmsg: fd:%d n:%z", lc->fd, n);
|
||||
|
||||
c->log->handler = handler;
|
||||
}
|
||||
|
|
@ -204,6 +205,14 @@ ngx_quic_recvmsg(ngx_event_t *ev)
|
|||
goto next;
|
||||
}
|
||||
|
||||
#if (NGX_QUIC_BPF)
|
||||
if (lc->read->quic) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"quic new connection on worker socket, dropped");
|
||||
goto next;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_STAT_STUB)
|
||||
(void) ngx_atomic_fetch_add(ngx_stat_accepted, 1);
|
||||
#endif
|
||||
|
|
@ -211,7 +220,15 @@ ngx_quic_recvmsg(ngx_event_t *ev)
|
|||
ngx_accept_disabled = ngx_cycle->connection_n / 8
|
||||
- ngx_cycle->free_connection_n;
|
||||
|
||||
c = ngx_get_connection(lc->fd, ev->log);
|
||||
cfd = lc->fd;
|
||||
|
||||
#if (NGX_QUIC_BPF)
|
||||
if (ngx_quic_bpf_get_worker_fd(lc, &cfd) != NGX_OK) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
c = ngx_get_connection(cfd, ev->log);
|
||||
if (c == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -327,7 +344,7 @@ ngx_quic_recvmsg(ngx_event_t *ev)
|
|||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, log, 0,
|
||||
"*%uA quic recvmsg: %V fd:%d n:%z",
|
||||
c->number, &addr, c->fd, n);
|
||||
c->number, &addr, lc->fd, n);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -989,7 +989,8 @@ ngx_worker_process_exit(ngx_cycle_t *cycle)
|
|||
&& c[i].read
|
||||
&& !c[i].read->accept
|
||||
&& !c[i].read->channel
|
||||
&& !c[i].read->resolver)
|
||||
&& !c[i].read->resolver
|
||||
&& !c[i].read->quic)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
"*%uA open socket #%d left in connection %ui",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue