mirror of
https://github.com/h2o/h2o.git
synced 2025-04-19 16:09:15 +08:00
remove remaining EBPF-based selective tracing, replacing it with picotls's sampling-based logging; sni-based is turned off for now
This commit is contained in:
parent
0d5a0fb2ee
commit
8827f8d38c
13
h2o-probes.d
13
h2o-probes.d
@ -29,19 +29,6 @@
|
||||
*/
|
||||
|
||||
provider h2o {
|
||||
/**
|
||||
* When a new connection is accepted, h2o invokes this probe to obtain the flags to be associated to the new connection. The
|
||||
* probe MUST write the result into the h2o_return map; see ebpf.h for details. `original_flags` contain the flags that will be
|
||||
* associated when the probe is not attached.
|
||||
*
|
||||
* Do not use it for a tracing event.
|
||||
*/
|
||||
probe _private_socket_lookup_flags(pid_t tid, uint64_t original_flags, struct st_h2o_ebpf_map_key_t *info);
|
||||
/**
|
||||
* Same as `_private_socket_lookup_flags`, expect that this probe is invoked when SNI is being obtained.
|
||||
*/
|
||||
probe _private_socket_lookup_flags_sni(pid_t tid, uint64_t original_flags, const char *server_name, size_t server_name_len);
|
||||
|
||||
/**
|
||||
* socket write at H2O socket abstraction layer
|
||||
*/
|
||||
|
@ -534,7 +534,6 @@
|
||||
E9F677D520074770006476D3 /* roundrobin.c in Sources */ = {isa = PBXBuildFile; fileRef = D08137391FD400F4004679DF /* roundrobin.c */; };
|
||||
E9F677D6200775FF006476D3 /* least_conn.c in Sources */ = {isa = PBXBuildFile; fileRef = D081373D1FD40431004679DF /* least_conn.c */; };
|
||||
E9F677D720077603006476D3 /* roundrobin.c in Sources */ = {isa = PBXBuildFile; fileRef = D081373E1FD40431004679DF /* roundrobin.c */; };
|
||||
E9FB8DC423991D08007BFC59 /* ebpf.h in Headers */ = {isa = PBXBuildFile; fileRef = E908A2A923163CB70039BCEE /* ebpf.h */; };
|
||||
E9FF84BC24C5AA47002577CA /* quicly-probes.d in Sources */ = {isa = PBXBuildFile; fileRef = E9FF84BB24C5AA46002577CA /* quicly-probes.d */; };
|
||||
E9FF84BD24C5AA47002577CA /* quicly-probes.d in Sources */ = {isa = PBXBuildFile; fileRef = E9FF84BB24C5AA46002577CA /* quicly-probes.d */; };
|
||||
E9FF84BE24C5AA52002577CA /* quicly-probes.d in Sources */ = {isa = PBXBuildFile; fileRef = E9FF84BB24C5AA46002577CA /* quicly-probes.d */; };
|
||||
@ -1118,7 +1117,6 @@
|
||||
E901C439213E59A000D17C93 /* qpack.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = qpack.c; sourceTree = "<group>"; };
|
||||
E901C43C213FAE0300D17C93 /* qpack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = qpack.h; sourceTree = "<group>"; };
|
||||
E901C43F2140CCB500D17C93 /* qpack.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = qpack.c; sourceTree = "<group>"; };
|
||||
E908A2A923163CB70039BCEE /* ebpf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ebpf.h; sourceTree = "<group>"; };
|
||||
E908A2AB231CF3D10039BCEE /* 50reverse-proxy-chunked-post-termination.t */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "50reverse-proxy-chunked-post-termination.t"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; };
|
||||
E908A2AE2320AE4C0039BCEE /* check.mk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = check.mk; sourceTree = "<group>"; };
|
||||
E90A95F21E30795100483D6C /* headers_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = headers_util.c; sourceTree = "<group>"; };
|
||||
@ -1993,7 +1991,6 @@
|
||||
10DA969B1CD2BF9000679165 /* cache.h */,
|
||||
1024A3FD1D22546800EB13F1 /* cache_digests.h */,
|
||||
105534D71A3C785000627ECB /* configurator.h */,
|
||||
E908A2A923163CB70039BCEE /* ebpf.h */,
|
||||
107D4D521B5B2412004A9B21 /* file.h */,
|
||||
1044812D1BFD0FBE0007863F /* filecache.h */,
|
||||
7D2DF4ED20297EE0004AD361 /* header.h */,
|
||||
@ -2961,7 +2958,6 @@
|
||||
107923A519A3215F00C52AD6 /* http1.h in Headers */,
|
||||
E901C3E6213E1C3600D17C93 /* ranges.h in Headers */,
|
||||
E98884CA21E7F3AF0060F010 /* sentmap.h in Headers */,
|
||||
E9FB8DC423991D08007BFC59 /* ebpf.h in Headers */,
|
||||
10A3D3D31B4CDF1200327CF9 /* memcached.h in Headers */,
|
||||
E901C3ED213E1C3600D17C93 /* constants.h in Headers */,
|
||||
08790DE01D8015A400A04BC1 /* sds.h in Headers */,
|
||||
|
@ -375,11 +375,6 @@ struct st_h2o_globalconf_t {
|
||||
* setuid user (or NULL)
|
||||
*/
|
||||
char *user;
|
||||
/**
|
||||
* sets up the h2o_return map if true.
|
||||
*/
|
||||
int usdt_selective_tracing;
|
||||
|
||||
/**
|
||||
* SSL handshake timeout
|
||||
*/
|
||||
@ -935,9 +930,9 @@ typedef struct st_h2o_conn_callbacks_t {
|
||||
*/
|
||||
ptls_t *(*get_ptls)(h2o_conn_t *conn);
|
||||
/**
|
||||
* returns if the connection is target of tracing
|
||||
* returns a random number between 0 and 1, unique to the connection (see ptls_log for how it is being used)
|
||||
*/
|
||||
int (*skip_tracing)(h2o_conn_t *conn);
|
||||
float (*log_random)(h2o_conn_t *conn);
|
||||
/**
|
||||
* optional (i.e. may be NULL) callback for server push
|
||||
*/
|
||||
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Fastly Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef h2o__ebpf_h
|
||||
#define h2o__ebpf_h
|
||||
|
||||
/*
|
||||
* This file may be included by a BPF program. A BPF program written in C can include a few system headers, for example
|
||||
* linux/sched.h and inttypes.h. However, most of the standard C/POSIX headers, for example stdio.h and socket.h, are unavailable.
|
||||
* ebpf.h MUST only depend on the include files available to the BPF compiler.
|
||||
*/
|
||||
|
||||
typedef struct st_h2o_ebpf_address_t {
|
||||
uint8_t ip[16];
|
||||
uint16_t port;
|
||||
} h2o_ebpf_address_t;
|
||||
|
||||
typedef struct st_h2o_ebpf_map_key_t {
|
||||
uint8_t family;
|
||||
uint8_t protocol;
|
||||
h2o_ebpf_address_t local, remote;
|
||||
} h2o_ebpf_map_key_t;
|
||||
|
||||
/**
|
||||
* `H2O_EBPF_FLAGS_*` are the value type of the pinned BPF maps: h2o_map and h2o_return
|
||||
*/
|
||||
#define H2O_EBPF_FLAGS_SKIP_TRACING_BIT 0x01
|
||||
|
||||
/**
|
||||
* QUIC_SEND_RETRY bits take 2 bits for 3 state: default, on, off
|
||||
*/
|
||||
#define H2O_EBPF_FLAGS_QUIC_SEND_RETRY_MASK 0x06
|
||||
#define H2O_EBPF_FLAGS_QUIC_SEND_RETRY_BITS_ON 0x02
|
||||
#define H2O_EBPF_FLAGS_QUIC_SEND_RETRY_BITS_OFF 0x04
|
||||
|
||||
/**
|
||||
* A pinned BPF map to control connection flags.
|
||||
* The key type is h2o_ebpf_map_key_t, and the value type is uint64_t that contains `H2O_EBPF_FLAGS_*`.
|
||||
*/
|
||||
#define H2O_EBPF_MAP_PATH "/sys/fs/bpf/h2o_map"
|
||||
|
||||
/**
|
||||
* A pinned BPF map to control connection flags, used together with h2o:socket_lookup_flags probe.
|
||||
* The key type is a thread ID typed as pid_t obtained by `gettid()`, and the value type is uint64_t that contains
|
||||
* `H2O_EBPF_FLAGS_*`.
|
||||
* See also h2o-probes.d.
|
||||
*/
|
||||
#define H2O_EBPF_RETURN_MAP_NAME "h2o_return"
|
||||
#define H2O_EBPF_RETURN_MAP_PATH "/sys/fs/bpf/" H2O_EBPF_RETURN_MAP_NAME
|
||||
|
||||
/**
|
||||
* The size of pinned BPF objects.
|
||||
* The size must be much larger than the number of worker threads and the safe value seems to depend on the system,
|
||||
*/
|
||||
#define H2O_EBPF_RETURN_MAP_SIZE 1024
|
||||
|
||||
#endif
|
@ -53,7 +53,7 @@ void h2o_http3_server_init_context(h2o_context_t *h2o, h2o_quic_ctx_t *ctx, h2o_
|
||||
*/
|
||||
h2o_http3_conn_t *h2o_http3_server_accept(h2o_http3_server_ctx_t *ctx, quicly_address_t *destaddr, quicly_address_t *srcaddr,
|
||||
quicly_decoded_packet_t *packet, quicly_address_token_plaintext_t *address_token,
|
||||
int skip_tracing, const h2o_http3_conn_callbacks_t *h3_callbacks);
|
||||
const h2o_http3_conn_callbacks_t *h3_callbacks);
|
||||
/**
|
||||
* amends the quicly context so that it could be used for the server
|
||||
*/
|
||||
|
@ -37,7 +37,6 @@ extern "C" {
|
||||
#include "picotls.h"
|
||||
#include "picotls/openssl.h" /* for H2O_CAN_OSSL_ASYNC */
|
||||
#include "h2o/cache.h"
|
||||
#include "h2o/ebpf.h"
|
||||
#include "h2o/memory.h"
|
||||
#include "h2o/openssl_backport.h"
|
||||
#include "h2o/string_.h"
|
||||
@ -188,9 +187,9 @@ struct st_h2o_socket_t {
|
||||
*/
|
||||
uint64_t bytes_written;
|
||||
/**
|
||||
* boolean flag to indicate if sock is NOT being traced
|
||||
* see ptls_log
|
||||
*/
|
||||
unsigned _skip_tracing : 1;
|
||||
float _log_random;
|
||||
struct {
|
||||
void (*cb)(void *data);
|
||||
void *data;
|
||||
@ -486,11 +485,11 @@ int h2o_socket_set_df_bit(int fd, int domain);
|
||||
/**
|
||||
* helper to check if socket the socket is target of tracing
|
||||
*/
|
||||
static int h2o_socket_skip_tracing(h2o_socket_t *sock);
|
||||
static float h2o_socket_log_random(h2o_socket_t *sock);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void h2o_socket_set_skip_tracing(h2o_socket_t *sock, int skip_tracing);
|
||||
void h2o_socket_set_log_random(h2o_socket_t *sock, float r);
|
||||
|
||||
#if H2O_CAN_OSSL_ASYNC
|
||||
/**
|
||||
@ -532,28 +531,6 @@ int h2o_socket_recycle_is_empty(void);
|
||||
*/
|
||||
size_t h2o_sendfile(int sockfd, int filefd, off_t off, size_t len);
|
||||
|
||||
/**
|
||||
* Prepares eBPF maps. Requires root privileges and thus should be called before dropping the privileges. Returns a boolean
|
||||
* indicating if operation succeeded.
|
||||
*/
|
||||
int h2o_socket_ebpf_setup(void);
|
||||
/**
|
||||
* Function to lookup if the connection is tagged for special treatment. The result is a union of `H2O_EBPF_FLAGS_*`.
|
||||
*/
|
||||
uint64_t h2o_socket_ebpf_lookup_flags(h2o_loop_t *loop, int (*init_key)(h2o_ebpf_map_key_t *key, void *cbdata), void *cbdata);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
uint64_t h2o_socket_ebpf_lookup_flags_sni(h2o_loop_t *loop, uint64_t flags, const char *server_name, size_t server_name_len);
|
||||
/**
|
||||
* function for initializing the ebpf lookup key from raw information
|
||||
*/
|
||||
int h2o_socket_ebpf_init_key_raw(h2o_ebpf_map_key_t *key, int sock_type, struct sockaddr *local, struct sockaddr *remote);
|
||||
/**
|
||||
* callback for initializing the ebpf lookup key from `h2o_socket_t`
|
||||
*/
|
||||
int h2o_socket_ebpf_init_key(h2o_ebpf_map_key_t *key, void *sock);
|
||||
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
/**
|
||||
* returns SSL_[gs]et_ext_data slot used to store `ptls_async_job_t` for handling async TLS handshake signature generation
|
||||
@ -640,9 +617,9 @@ inline void h2o_sliding_counter_start(h2o_sliding_counter_t *counter, uint64_t n
|
||||
counter->cur.start_at = now;
|
||||
}
|
||||
|
||||
inline int h2o_socket_skip_tracing(h2o_socket_t *sock)
|
||||
inline float h2o_socket_log_random(h2o_socket_t *sock)
|
||||
{
|
||||
return sock->_skip_tracing;
|
||||
return sock->_log_random;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -56,10 +56,6 @@
|
||||
#define TCP_NOTSENT_LOWAT 25
|
||||
#endif
|
||||
|
||||
#if H2O_USE_DTRACE && defined(__linux__)
|
||||
#define H2O_USE_EBPF_MAP 1
|
||||
#endif
|
||||
|
||||
#define OPENSSL_HOSTNAME_VALIDATION_LINKAGE static
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
@ -200,6 +196,7 @@ __thread h2o_mem_recycle_t h2o_socket_zerocopy_buffer_allocator = {&h2o_socket_s
|
||||
__thread size_t h2o_socket_num_zerocopy_buffers_inflight;
|
||||
|
||||
int h2o_socket_use_ktls = 0;
|
||||
uint16_t h2o_socket_trace_ratio = UINT16_MAX;
|
||||
|
||||
const char h2o_socket_error_out_of_memory[] = "out of memory";
|
||||
const char h2o_socket_error_io[] = "I/O error";
|
||||
@ -1944,14 +1941,9 @@ static void proceed_handshake_undetermined(h2o_socket_t *sock)
|
||||
ptls_buffer_t wbuf;
|
||||
ptls_buffer_init(&wbuf, "", 0);
|
||||
|
||||
#if PICOTLS_USE_DTRACE
|
||||
unsigned ptls_skip_tracing_backup = ptls_default_skip_tracing;
|
||||
ptls_default_skip_tracing = sock->_skip_tracing;
|
||||
#endif
|
||||
ptls_log_random_override = &sock->_log_random;
|
||||
ptls_t *ptls = ptls_new(ptls_ctx, 1);
|
||||
#if PICOTLS_USE_DTRACE
|
||||
ptls_default_skip_tracing = ptls_skip_tracing_backup;
|
||||
#endif
|
||||
ptls_log_random_override = NULL;
|
||||
if (ptls == NULL)
|
||||
h2o_fatal("no memory");
|
||||
*ptls_get_data_ptr(ptls) = sock;
|
||||
@ -2303,11 +2295,11 @@ int h2o_socket_set_df_bit(int fd, int domain)
|
||||
#undef SETSOCKOPT
|
||||
}
|
||||
|
||||
void h2o_socket_set_skip_tracing(h2o_socket_t *sock, int skip_tracing)
|
||||
void h2o_socket_set_log_random(h2o_socket_t *sock, float r)
|
||||
{
|
||||
sock->_skip_tracing = skip_tracing;
|
||||
sock->_log_random = r;
|
||||
if (sock->ssl != NULL && sock->ssl->ptls != NULL)
|
||||
ptls_set_skip_tracing(sock->ssl->ptls, skip_tracing);
|
||||
ptls_set_log_random(sock->ssl->ptls, r);
|
||||
}
|
||||
|
||||
void h2o_sliding_counter_stop(h2o_sliding_counter_t *counter, uint64_t now)
|
||||
@ -2451,332 +2443,6 @@ int h2o_socket_recycle_is_empty(void)
|
||||
h2o_mem_recycle_is_empty(&h2o_socket_zerocopy_buffer_allocator);
|
||||
}
|
||||
|
||||
#if H2O_USE_EBPF_MAP
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "h2o/multithread.h"
|
||||
#include "h2o-probes.h"
|
||||
|
||||
static int ebpf_map_create(uint32_t map_type, uint32_t key_size, uint32_t value_size, uint32_t max_entries, const char *map_name)
|
||||
{
|
||||
union bpf_attr attr = {
|
||||
.map_type = map_type,
|
||||
.key_size = key_size,
|
||||
.value_size = value_size,
|
||||
.max_entries = max_entries,
|
||||
};
|
||||
strncpy(attr.map_name, map_name, sizeof(attr.map_name));
|
||||
return syscall(SYS_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static int ebpf_obj_pin(int bpf_fd, const char *pathname)
|
||||
{
|
||||
union bpf_attr attr = {
|
||||
.bpf_fd = (uint32_t)bpf_fd,
|
||||
.pathname = (uint64_t)pathname,
|
||||
};
|
||||
return syscall(SYS_bpf, BPF_OBJ_PIN, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static int ebpf_obj_get(const char *pathname)
|
||||
{
|
||||
union bpf_attr attr = {
|
||||
.pathname = (uint64_t)pathname,
|
||||
};
|
||||
return syscall(SYS_bpf, BPF_OBJ_GET, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static int ebpf_obj_get_info_by_fd(int fd, struct bpf_map_info *info)
|
||||
{
|
||||
union bpf_attr attr = {
|
||||
.info =
|
||||
{
|
||||
.bpf_fd = fd,
|
||||
.info = (uint64_t)info,
|
||||
.info_len = sizeof(*info),
|
||||
},
|
||||
};
|
||||
return syscall(SYS_bpf, BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static int ebpf_map_lookup(int fd, const void *key, void *value)
|
||||
{
|
||||
union bpf_attr attr = {
|
||||
.map_fd = fd,
|
||||
.key = (uint64_t)key,
|
||||
.value = (uint64_t)value,
|
||||
};
|
||||
return syscall(SYS_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static int ebpf_map_delete(int fd, const void *key)
|
||||
{
|
||||
union bpf_attr attr = {
|
||||
.map_fd = fd,
|
||||
.key = (uint64_t)key,
|
||||
};
|
||||
return syscall(SYS_bpf, BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static int return_map_fd = -1; // for h2o_return
|
||||
|
||||
int h2o_socket_ebpf_setup(void)
|
||||
{
|
||||
const struct {
|
||||
int type;
|
||||
uint32_t key_size;
|
||||
uint32_t value_size;
|
||||
} map_attr = {
|
||||
.type = BPF_MAP_TYPE_LRU_HASH,
|
||||
.key_size = sizeof(pid_t),
|
||||
.value_size = sizeof(uint64_t),
|
||||
};
|
||||
|
||||
int fd = -1;
|
||||
if (getuid() != 0) {
|
||||
h2o_error_printf("failed to set up eBPF maps because bpf(2) requires root privileges\n");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
fd = ebpf_obj_get(H2O_EBPF_RETURN_MAP_PATH);
|
||||
if (fd < 0) {
|
||||
if (errno != ENOENT) {
|
||||
h2o_perror("BPF_OBJ_GET failed");
|
||||
goto Error;
|
||||
}
|
||||
/* Pinned eBPF map does not exist. Create one and pin it to the BPF filesystem. */
|
||||
fd = ebpf_map_create(map_attr.type, map_attr.key_size, map_attr.value_size, H2O_EBPF_RETURN_MAP_SIZE,
|
||||
H2O_EBPF_RETURN_MAP_NAME);
|
||||
if (fd < 0) {
|
||||
if (errno == EPERM) {
|
||||
h2o_error_printf("BPF_MAP_CREATE failed with EPERM, maybe because RLIMIT_MEMLOCK is too small.\n");
|
||||
} else {
|
||||
h2o_perror("BPF_MAP_CREATE failed");
|
||||
}
|
||||
goto Error;
|
||||
}
|
||||
if (ebpf_obj_pin(fd, H2O_EBPF_RETURN_MAP_PATH) != 0) {
|
||||
if (errno == ENOENT) {
|
||||
h2o_error_printf("BPF_OBJ_PIN failed with ENOENT, because /sys/fs/bpf is not mounted as a BPF filesystem.\n");
|
||||
} else {
|
||||
h2o_perror("BPF_OBJ_PIN failed");
|
||||
}
|
||||
goto Error;
|
||||
}
|
||||
} else {
|
||||
/* BPF_OBJ_GET successfully opened a pinned eBPF map. Make sure the critical attributes (type, key size, value size) are
|
||||
* correct, otherwise usdt-selective-tracing does not work. */
|
||||
struct bpf_map_info m;
|
||||
if (ebpf_obj_get_info_by_fd(fd, &m) != 0) {
|
||||
h2o_perror("BPF_OBJ_GET_INFO_BY_FD failed");
|
||||
goto Error;
|
||||
}
|
||||
if (m.type != map_attr.type) {
|
||||
h2o_error_printf(H2O_EBPF_RETURN_MAP_PATH " has an unexpected map type: expected %d but got %d\n", map_attr.type,
|
||||
m.type);
|
||||
goto Error;
|
||||
}
|
||||
if (m.key_size != map_attr.key_size) {
|
||||
h2o_error_printf(H2O_EBPF_RETURN_MAP_PATH " has an unexpected map key size: expected %" PRIu32 " but got %" PRIu32 "\n",
|
||||
map_attr.key_size, m.key_size);
|
||||
goto Error;
|
||||
}
|
||||
if (m.value_size != map_attr.value_size) {
|
||||
h2o_error_printf(H2O_EBPF_RETURN_MAP_PATH " has an unexpected map value size: expected %" PRIu32 " but got %" PRIu32
|
||||
"\n",
|
||||
map_attr.value_size, m.value_size);
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
/* success */
|
||||
return_map_fd = fd;
|
||||
return 1;
|
||||
|
||||
Error:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_map_fd(h2o_loop_t *loop, const char *map_path, int *fd, uint64_t *last_attempt)
|
||||
{
|
||||
// only check every second
|
||||
uint64_t now = h2o_now(loop);
|
||||
if (*last_attempt - now < 1000)
|
||||
return;
|
||||
|
||||
*last_attempt = now;
|
||||
|
||||
struct stat s;
|
||||
if (stat(map_path, &s) != 0) {
|
||||
// map path unavailable, cleanup fd if needed and leave
|
||||
if (*fd >= 0) {
|
||||
close(*fd);
|
||||
*fd = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (*fd >= 0)
|
||||
return; // map still exists and we have a fd
|
||||
|
||||
// map exists, try connect
|
||||
*fd = ebpf_obj_get(map_path);
|
||||
if (*fd < 0)
|
||||
h2o_perror("BPF_OBJ_GET failed");
|
||||
}
|
||||
|
||||
static int get_tracing_map_fd(h2o_loop_t *loop)
|
||||
{
|
||||
static __thread int fd = -1;
|
||||
static __thread uint64_t last_attempt = 0;
|
||||
get_map_fd(loop, H2O_EBPF_MAP_PATH, &fd, &last_attempt);
|
||||
return fd;
|
||||
}
|
||||
|
||||
static inline int set_ebpf_map_key_tuples(const struct sockaddr *sa, h2o_ebpf_address_t *ea)
|
||||
{
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (void *)sa;
|
||||
memcpy(ea->ip, &sin->sin_addr, sizeof(sin->sin_addr));
|
||||
ea->port = sin->sin_port;
|
||||
return 1;
|
||||
} else if (sa->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin = (void *)sa;
|
||||
memcpy(ea->ip, &sin->sin6_addr, sizeof(sin->sin6_addr));
|
||||
ea->port = sin->sin6_port;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int h2o_socket_ebpf_init_key_raw(h2o_ebpf_map_key_t *key, int sock_type, struct sockaddr *local, struct sockaddr *remote)
|
||||
{
|
||||
memset(key, 0, sizeof(*key));
|
||||
if (!set_ebpf_map_key_tuples(local, &key->local))
|
||||
return 0;
|
||||
if (!set_ebpf_map_key_tuples(remote, &key->remote))
|
||||
return 0;
|
||||
key->family = local->sa_family == AF_INET6 ? 6 : 4;
|
||||
key->protocol = sock_type;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int h2o_socket_ebpf_init_key(h2o_ebpf_map_key_t *key, void *_sock)
|
||||
{
|
||||
h2o_socket_t *sock = _sock;
|
||||
struct sockaddr_storage local, remote;
|
||||
unsigned int sock_type, sock_type_len = sizeof(sock_type_len);
|
||||
|
||||
/* fetch info */
|
||||
if (h2o_socket_getsockname(sock, (void *)&local) == 0)
|
||||
return 0;
|
||||
if (h2o_socket_getpeername(sock, (void *)&remote) == 0)
|
||||
return 0;
|
||||
if (getsockopt(h2o_socket_get_fd(sock), SOL_SOCKET, SO_TYPE, &sock_type, &sock_type_len) != 0) /* can't the info be cached? */
|
||||
return 0;
|
||||
|
||||
return h2o_socket_ebpf_init_key_raw(key, sock_type, (void *)&local, (void *)&remote);
|
||||
}
|
||||
|
||||
static void report_ebpf_lookup_errors(h2o_error_reporter_t *reporter, uint64_t total_successes, uint64_t cur_successes)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"BPF_MAP_LOOKUP_ELEM failed with ENOENT %" PRIu64 " time%s, succeeded: %" PRIu64 " time%s, over the last minute.\n",
|
||||
reporter->cur_errors, reporter->cur_errors > 1 ? "s" : "", cur_successes, cur_successes > 1 ? "s" : "");
|
||||
}
|
||||
|
||||
static h2o_error_reporter_t track_ebpf_lookup = H2O_ERROR_REPORTER_INITIALIZER(report_ebpf_lookup_errors);
|
||||
|
||||
#define DO_EBPF_RETURN_LOOKUP(func) \
|
||||
do { \
|
||||
if (return_map_fd >= 0) { \
|
||||
pid_t tid = (pid_t)syscall(SYS_gettid); /* gettid() was not available until glibc 2.30 (2019) */ \
|
||||
/* Make sure old flags do not exist, otherwise the subsequent logic will be unreliable. */ \
|
||||
if (ebpf_map_delete(return_map_fd, &tid) == 0 || errno == ENOENT) { \
|
||||
do { \
|
||||
func \
|
||||
} while (0); \
|
||||
if (ebpf_map_lookup(return_map_fd, &tid, &flags) == 0) { \
|
||||
h2o_error_reporter_record_success(&track_ebpf_lookup); \
|
||||
} else { \
|
||||
if (errno == ENOENT) { \
|
||||
/* ENOENT could be issued in some reasons even if BPF tries to insert the entry, for example: \
|
||||
* * the entry in LRU hash was evicted \
|
||||
* * the insert operation in BPF program failed with ENOMEM \
|
||||
* We don't know the frequency for this ENOENT, so cap the number of logs. \
|
||||
* \
|
||||
* Other than the above reasons, ENOENT is issued when the tracer does not set the flags via h2o_return \
|
||||
* map, See h2o:_private_socket_lookup_flags handler in h2olog for details. */ \
|
||||
h2o_error_reporter_record_error(loop, &track_ebpf_lookup, 60000, 0); \
|
||||
} else { \
|
||||
h2o_perror("BPF_MAP_LOOKUP failed"); \
|
||||
} \
|
||||
} \
|
||||
} else { \
|
||||
h2o_perror("BPF_MAP_DELETE failed"); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
uint64_t h2o_socket_ebpf_lookup_flags(h2o_loop_t *loop, int (*init_key)(h2o_ebpf_map_key_t *key, void *cbdata), void *cbdata)
|
||||
{
|
||||
uint64_t flags = 0;
|
||||
|
||||
int tracing_map_fd = get_tracing_map_fd(loop);
|
||||
h2o_ebpf_map_key_t key;
|
||||
if ((tracing_map_fd >= 0 || H2O__PRIVATE_SOCKET_LOOKUP_FLAGS_ENABLED()) && init_key(&key, cbdata)) {
|
||||
if (tracing_map_fd >= 0)
|
||||
ebpf_map_lookup(tracing_map_fd, &key, &flags);
|
||||
|
||||
if (H2O__PRIVATE_SOCKET_LOOKUP_FLAGS_ENABLED())
|
||||
DO_EBPF_RETURN_LOOKUP({ H2O__PRIVATE_SOCKET_LOOKUP_FLAGS(tid, flags, &key); });
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint64_t h2o_socket_ebpf_lookup_flags_sni(h2o_loop_t *loop, uint64_t flags, const char *server_name, size_t server_name_len)
|
||||
{
|
||||
if (H2O__PRIVATE_SOCKET_LOOKUP_FLAGS_SNI_ENABLED())
|
||||
DO_EBPF_RETURN_LOOKUP({ H2O__PRIVATE_SOCKET_LOOKUP_FLAGS_SNI(tid, flags, server_name, server_name_len); });
|
||||
return flags;
|
||||
}
|
||||
|
||||
#undef DO_EBPF_RETURN_LOOKUP
|
||||
|
||||
#else
|
||||
|
||||
int h2o_socket_ebpf_setup(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int h2o_socket_ebpf_init_key_raw(h2o_ebpf_map_key_t *key, int sock_type, struct sockaddr *local, struct sockaddr *remote)
|
||||
{
|
||||
h2o_fatal("unimplemented");
|
||||
}
|
||||
|
||||
int h2o_socket_ebpf_init_key(h2o_ebpf_map_key_t *key, void *sock)
|
||||
{
|
||||
h2o_fatal("unimplemented");
|
||||
}
|
||||
|
||||
uint64_t h2o_socket_ebpf_lookup_flags(h2o_loop_t *loop, int (*init_key)(h2o_ebpf_map_key_t *key, void *cbdata), void *cbdata)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t h2o_socket_ebpf_lookup_flags_sni(h2o_loop_t *loop, uint64_t flags, const char *server_name, size_t server_name_len)
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
|
||||
int h2o_socket_boringssl_get_async_job_index(void)
|
||||
|
@ -728,9 +728,7 @@ h2o_socket_t *h2o_evloop_socket_accept(h2o_socket_t *_listener)
|
||||
|
||||
if (peeraddr != NULL && *peeraddrlen <= sizeof(*peeraddr))
|
||||
h2o_socket_setpeername(sock, (struct sockaddr *)peeraddr, *peeraddrlen);
|
||||
uint64_t flags = h2o_socket_ebpf_lookup_flags(listener->loop, h2o_socket_ebpf_init_key, sock);
|
||||
if ((flags & H2O_EBPF_FLAGS_SKIP_TRACING_BIT) != 0)
|
||||
sock->_skip_tracing = 1;
|
||||
sock->_log_random = ptls_generate_log_random(ptls_openssl_random_bytes);
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
@ -375,9 +375,7 @@ h2o_socket_t *h2o_uv_socket_create(uv_handle_t *handle, uv_close_cb close_cb)
|
||||
sock->close_cb = close_cb;
|
||||
sock->handle->data = sock;
|
||||
h2o_timer_init(&sock->write_cb_timer, on_call_write_success);
|
||||
uint64_t flags = h2o_socket_ebpf_lookup_flags(sock->handle->loop, h2o_socket_ebpf_init_key, &sock->super);
|
||||
if ((flags & H2O_EBPF_FLAGS_SKIP_TRACING_BIT) != 0)
|
||||
sock->super._skip_tracing = 1;
|
||||
sock->super._log_random = ptls_generate_log_random(ptls_openssl_random_bytes);
|
||||
return &sock->super;
|
||||
}
|
||||
|
||||
|
@ -1004,15 +1004,6 @@ static int on_config_stash(h2o_configurator_command_t *cmd, h2o_configurator_con
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_config_usdt_selective_tracing(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node)
|
||||
{
|
||||
ssize_t on;
|
||||
if ((on = h2o_configurator_get_one_of(cmd, node, "OFF,ON")) == -1)
|
||||
return -1;
|
||||
ctx->globalconf->usdt_selective_tracing = (int)on;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h2o_configurator__init_core(h2o_globalconf_t *conf)
|
||||
{
|
||||
/* check if already initialized */
|
||||
@ -1160,9 +1151,6 @@ void h2o_configurator__init_core(h2o_globalconf_t *conf)
|
||||
H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
|
||||
on_config_send_informational);
|
||||
h2o_configurator_define_command(&c->super, "stash", H2O_CONFIGURATOR_FLAG_ALL_LEVELS, on_config_stash);
|
||||
h2o_configurator_define_command(&c->super, "usdt-selective-tracing",
|
||||
H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
|
||||
on_config_usdt_selective_tracing);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
static int on_req(h2o_handler_t *_self, h2o_req_t *req)
|
||||
{
|
||||
struct sockaddr_storage local;
|
||||
float sample_ratio = 1;
|
||||
char *trace = h2o_mem_alloc(req->path.len + 2 /* should be enough */), *trace_tail = trace;
|
||||
h2o_socket_t *sock;
|
||||
h2o_socket_export_t export_info;
|
||||
@ -38,7 +39,13 @@ static int on_req(h2o_handler_t *_self, h2o_req_t *req)
|
||||
const char *name;
|
||||
size_t name_len;
|
||||
while ((name = h2o_next_token(&iter, '&', '&', &name_len, &value)) != NULL) {
|
||||
if (h2o_memis(name, name_len, H2O_STRLIT("trace"))) {
|
||||
if (h2o_memis(name, name_len, H2O_STRLIT("sample-ratio"))) {
|
||||
if (sscanf(h2o_strdup(&req->pool, value.base, value.len).base, "%f", &sample_ratio) != 1 ||
|
||||
!(0 <= sample_ratio && sample_ratio <= 1)) {
|
||||
h2o_send_error_400(req, "Bad Request", "sample-rate must be a number between 0 and 1", 0);
|
||||
return 0;
|
||||
}
|
||||
} else if (h2o_memis(name, name_len, H2O_STRLIT("trace"))) {
|
||||
h2o_memcpy(trace_tail, value.base, value.len);
|
||||
trace_tail += value.len;
|
||||
*trace_tail++ = '\0';
|
||||
@ -58,7 +65,7 @@ static int on_req(h2o_handler_t *_self, h2o_req_t *req)
|
||||
(void)write(export_info.fd, H2O_STRLIT("HTTP/1.1 200 OK\r\n\r\n"));
|
||||
|
||||
/* register log fd after writing HTTP response, as log is written by multiple threads */
|
||||
if (ptls_log_add_fd(export_info.fd, trace) != 0)
|
||||
if (ptls_log_add_fd(export_info.fd, sample_ratio, trace) != 0)
|
||||
h2o_fatal("failed to add fd to h2olog");
|
||||
|
||||
return 0;
|
||||
|
@ -408,7 +408,7 @@ static socklen_t get_peername(h2o_conn_t *_conn, struct sockaddr *sa)
|
||||
return conn->remote.len;
|
||||
}
|
||||
|
||||
static int skip_tracing(h2o_conn_t *conn)
|
||||
static float log_random(h2o_conn_t *conn)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -638,7 +638,7 @@ static struct st_mruby_subreq_t *create_subreq(h2o_mruby_context_t *ctx, mrb_val
|
||||
static const h2o_conn_callbacks_t callbacks = {
|
||||
.get_sockname = get_sockname,
|
||||
.get_peername = get_peername,
|
||||
.skip_tracing = skip_tracing,
|
||||
.log_random = log_random,
|
||||
.get_req_id = get_req_id,
|
||||
};
|
||||
|
||||
|
@ -1151,10 +1151,10 @@ static ptls_t *get_ptls(h2o_conn_t *_conn)
|
||||
return h2o_socket_get_ptls(conn->sock);
|
||||
}
|
||||
|
||||
static int skip_tracing(h2o_conn_t *_conn)
|
||||
static float log_random(h2o_conn_t *_conn)
|
||||
{
|
||||
struct st_h2o_http1_conn_t *conn = (void *)_conn;
|
||||
return h2o_socket_skip_tracing(conn->sock);
|
||||
return h2o_socket_log_random(conn->sock);
|
||||
}
|
||||
|
||||
static int can_zerocopy(h2o_conn_t *_conn)
|
||||
@ -1228,7 +1228,7 @@ static const h2o_conn_callbacks_t h1_callbacks = {
|
||||
.get_sockname = get_sockname,
|
||||
.get_peername = get_peername,
|
||||
.get_ptls = get_ptls,
|
||||
.skip_tracing = skip_tracing,
|
||||
.log_random = log_random,
|
||||
.close_idle_connection = close_idle_connection,
|
||||
.foreach_request = foreach_request,
|
||||
.request_shutdown = initiate_graceful_shutdown,
|
||||
|
@ -1620,11 +1620,11 @@ static ptls_t *get_ptls(h2o_conn_t *_conn)
|
||||
return h2o_socket_get_ptls(conn->sock);
|
||||
}
|
||||
|
||||
static int skip_tracing(h2o_conn_t *_conn)
|
||||
static float log_random(h2o_conn_t *_conn)
|
||||
{
|
||||
struct st_h2o_http2_conn_t *conn = (void *)_conn;
|
||||
assert(conn->sock != NULL && "it never becomes NULL, right?");
|
||||
return h2o_socket_skip_tracing(conn->sock);
|
||||
return h2o_socket_log_random(conn->sock);
|
||||
}
|
||||
|
||||
static uint64_t get_req_id(h2o_req_t *req)
|
||||
@ -1756,7 +1756,7 @@ static h2o_http2_conn_t *create_conn(h2o_context_t *ctx, h2o_hostconf_t **hosts,
|
||||
.get_sockname = get_sockname,
|
||||
.get_peername = get_peername,
|
||||
.get_ptls = get_ptls,
|
||||
.skip_tracing = skip_tracing,
|
||||
.log_random = log_random,
|
||||
.get_req_id = get_req_id,
|
||||
.push_path = push_path,
|
||||
.get_debug_state = h2o_http2_get_debug_state,
|
||||
|
@ -561,10 +561,10 @@ static ptls_t *get_ptls(h2o_conn_t *_conn)
|
||||
return quicly_get_tls(conn->h3.super.quic);
|
||||
}
|
||||
|
||||
static int get_skip_tracing(h2o_conn_t *conn)
|
||||
static float log_random(h2o_conn_t *conn)
|
||||
{
|
||||
ptls_t *ptls = get_ptls(conn);
|
||||
return ptls_skip_tracing(ptls);
|
||||
return ptls_log_random(ptls);
|
||||
}
|
||||
|
||||
static uint64_t get_req_id(h2o_req_t *req)
|
||||
@ -2150,13 +2150,13 @@ void h2o_http3_server_init_context(h2o_context_t *h2o, h2o_quic_ctx_t *ctx, h2o_
|
||||
|
||||
h2o_http3_conn_t *h2o_http3_server_accept(h2o_http3_server_ctx_t *ctx, quicly_address_t *destaddr, quicly_address_t *srcaddr,
|
||||
quicly_decoded_packet_t *packet, quicly_address_token_plaintext_t *address_token,
|
||||
int skip_tracing, const h2o_http3_conn_callbacks_t *h3_callbacks)
|
||||
const h2o_http3_conn_callbacks_t *h3_callbacks)
|
||||
{
|
||||
static const h2o_conn_callbacks_t conn_callbacks = {
|
||||
.get_sockname = get_sockname,
|
||||
.get_peername = get_peername,
|
||||
.get_ptls = get_ptls,
|
||||
.skip_tracing = get_skip_tracing,
|
||||
.log_random = log_random,
|
||||
.get_req_id = get_req_id,
|
||||
.close_idle_connection = close_idle_connection,
|
||||
.foreach_request = foreach_request,
|
||||
@ -2218,18 +2218,11 @@ h2o_http3_conn_t *h2o_http3_server_accept(h2o_http3_server_ctx_t *ctx, quicly_ad
|
||||
|
||||
/* accept connection */
|
||||
assert(ctx->super.next_cid != NULL && "to set next_cid, h2o_quic_set_context_identifier must be called");
|
||||
#if PICOTLS_USE_DTRACE
|
||||
unsigned orig_skip_tracing = ptls_default_skip_tracing;
|
||||
ptls_default_skip_tracing = skip_tracing;
|
||||
#endif
|
||||
quicly_conn_t *qconn;
|
||||
int accept_ret = quicly_accept(
|
||||
&qconn, ctx->super.quic, &destaddr->sa, &srcaddr->sa, packet, address_token, ctx->super.next_cid,
|
||||
&conn->handshake_properties,
|
||||
&conn->h3 /* back pointer is set up here so that callbacks being called while parsing ClientHello can refer to `conn` */);
|
||||
#if PICOTLS_USE_DTRACE
|
||||
ptls_default_skip_tracing = orig_skip_tracing;
|
||||
#endif
|
||||
if (accept_ret != 0) {
|
||||
h2o_http3_conn_t *ret = NULL;
|
||||
if (accept_ret == QUICLY_ERROR_DECRYPTION_FAILED)
|
||||
|
@ -31,9 +31,7 @@
|
||||
if (!ptls_log_point_is_active(&logpoint)) \
|
||||
break; \
|
||||
h2o_conn_t *conn_ = (_conn); \
|
||||
if (conn_->callbacks->skip_tracing(conn_)) \
|
||||
break; \
|
||||
PTLS_LOG__DO_LOG(h2o, _name, { \
|
||||
PTLS_LOG__DO_LOG(h2o, _name, conn_->callbacks->log_random(conn_), { \
|
||||
PTLS_LOG_ELEMENT_UNSIGNED(conn_id, conn_->id); \
|
||||
do { \
|
||||
_block \
|
||||
@ -150,7 +148,8 @@ static inline void h2o_probe_log_request(h2o_req_t *req, uint64_t req_index)
|
||||
|
||||
PTLS_LOG_DEFINE_POINT(h2o, receive_request_header, receive_request_header_logpoint);
|
||||
if (PTLS_UNLIKELY(H2O_RECEIVE_REQUEST_HEADER_ENABLED()) ||
|
||||
(ptls_log_point_is_active(&receive_request_header_logpoint) && !req->conn->callbacks->skip_tracing(req->conn))) {
|
||||
(ptls_log_point_is_active(&receive_request_header_logpoint) &&
|
||||
req->conn->callbacks->log_random(req->conn) < ptls_log__max_sample_ratio)) {
|
||||
if (req->input.authority.base != NULL)
|
||||
h2o_probe_request_header(req, req_index, H2O_TOKEN_AUTHORITY->buf, req->input.authority);
|
||||
if (req->input.method.base != NULL)
|
||||
@ -176,7 +175,8 @@ static inline void h2o_probe_log_response(h2o_req_t *req, uint64_t req_index)
|
||||
});
|
||||
PTLS_LOG_DEFINE_POINT(h2o, send_response_header, send_response_header_logpoint);
|
||||
if (PTLS_UNLIKELY(H2O_SEND_RESPONSE_HEADER_ENABLED()) ||
|
||||
(ptls_log_point_is_active(&send_response_header_logpoint) && !req->conn->callbacks->skip_tracing(req->conn))) {
|
||||
(ptls_log_point_is_active(&send_response_header_logpoint) &&
|
||||
req->conn->callbacks->log_random(req->conn) < ptls_log__max_sample_ratio)) {
|
||||
if (req->res.content_length != SIZE_MAX) {
|
||||
char buf[sizeof(H2O_SIZE_T_LONGEST_STR)];
|
||||
size_t len = (size_t)sprintf(buf, "%zu", req->res.content_length);
|
||||
|
38
src/main.c
38
src/main.c
@ -910,6 +910,7 @@ static void setup_ecc_key(SSL_CTX *ssl_ctx)
|
||||
|
||||
static void on_sni_update_tracing(void *conn, int is_quic, const char *server_name, size_t server_name_len)
|
||||
{
|
||||
#if 0 /* FIXME */
|
||||
int cur_skip_tracing;
|
||||
|
||||
if (is_quic) {
|
||||
@ -930,6 +931,7 @@ static void on_sni_update_tracing(void *conn, int is_quic, const char *server_na
|
||||
h2o_socket_set_skip_tracing(conn, new_skip_tracing);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct listener_ssl_config_t *resolve_sni(struct listener_config_t *listener, const char *name, size_t name_len)
|
||||
@ -3909,16 +3911,6 @@ static void on_accept(h2o_socket_t *listener, const char *err)
|
||||
} while (--num_accepts != 0);
|
||||
}
|
||||
|
||||
struct init_ebpf_key_info_t {
|
||||
struct sockaddr *local, *remote;
|
||||
};
|
||||
|
||||
static int init_ebpf_key(h2o_ebpf_map_key_t *key, void *_info)
|
||||
{
|
||||
struct init_ebpf_key_info_t *info = _info;
|
||||
return h2o_socket_ebpf_init_key_raw(key, SOCK_DGRAM, info->local, info->remote);
|
||||
}
|
||||
|
||||
static int validate_token(h2o_http3_server_ctx_t *ctx, struct sockaddr *remote, ptls_iovec_t client_cid, ptls_iovec_t server_cid,
|
||||
quicly_address_token_plaintext_t *token)
|
||||
{
|
||||
@ -3970,12 +3962,6 @@ static h2o_quic_conn_t *on_http3_accept(h2o_quic_ctx_t *_ctx, quicly_address_t *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct init_ebpf_key_info_t ebpf_key_info = {
|
||||
.local = &destaddr->sa,
|
||||
.remote = &srcaddr->sa,
|
||||
};
|
||||
uint64_t flags = h2o_socket_ebpf_lookup_flags(ctx->super.loop, init_ebpf_key, &ebpf_key_info);
|
||||
|
||||
quicly_address_token_plaintext_t *token = NULL, token_buf;
|
||||
h2o_http3_conn_t *conn = NULL;
|
||||
|
||||
@ -3999,18 +3985,7 @@ static h2o_quic_conn_t *on_http3_accept(h2o_quic_ctx_t *_ctx, quicly_address_t *
|
||||
|
||||
/* send retry if necessary */
|
||||
if (token == NULL || token->type != QUICLY_ADDRESS_TOKEN_TYPE_RETRY) {
|
||||
int send_retry = ctx->send_retry;
|
||||
switch (flags & H2O_EBPF_FLAGS_QUIC_SEND_RETRY_MASK) {
|
||||
case H2O_EBPF_FLAGS_QUIC_SEND_RETRY_BITS_ON:
|
||||
send_retry = 1;
|
||||
break;
|
||||
case H2O_EBPF_FLAGS_QUIC_SEND_RETRY_BITS_OFF:
|
||||
send_retry = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (send_retry) {
|
||||
if (ctx->send_retry) {
|
||||
static __thread struct {
|
||||
ptls_aead_context_t *v1;
|
||||
ptls_aead_context_t *draft29;
|
||||
@ -4048,8 +4023,7 @@ static h2o_quic_conn_t *on_http3_accept(h2o_quic_ctx_t *_ctx, quicly_address_t *
|
||||
}
|
||||
|
||||
/* accept the connection */
|
||||
conn = h2o_http3_server_accept(ctx, destaddr, srcaddr, packet, token, (H2O_EBPF_FLAGS_SKIP_TRACING_BIT & flags) != 0,
|
||||
&conf.quic.conn_callbacks);
|
||||
conn = h2o_http3_server_accept(ctx, destaddr, srcaddr, packet, token, &conf.quic.conn_callbacks);
|
||||
if (conn == NULL || &conn->super == &h2o_quic_accept_conn_decryption_failed) {
|
||||
goto Exit;
|
||||
} else if (conn == &h2o_http3_accept_conn_closed) {
|
||||
@ -4943,10 +4917,6 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
setup_signal_handlers();
|
||||
if (conf.globalconf.usdt_selective_tracing && !h2o_socket_ebpf_setup()) {
|
||||
h2o_error_printf("usdt-selective-tracing is set to ON but failed to setup eBPF\n");
|
||||
return EX_CONFIG;
|
||||
}
|
||||
|
||||
/* open the log file to redirect STDIN/STDERR to, before calling setuid */
|
||||
if (conf.error_log != NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user