diff --git a/bpf/go_common.h b/bpf/go_common.h index 2331746b2..d30de993d 100644 --- a/bpf/go_common.h +++ b/bpf/go_common.h @@ -232,7 +232,7 @@ server_trace_parent(void *goroutine_addr, tp_info_t *tp, tp_info_t *found_tp) { } else { // If not, we then look up the information in the black-box context map - same node. bpf_dbg_printk("Looking up traceparent for connection info"); - tp_info_pid_t *tp_p = trace_info_for_connection(&conn); + tp_info_pid_t *tp_p = trace_info_for_connection(&conn, TRACE_TYPE_CLIENT); if (!disable_black_box_cp && tp_p) { if (correlated_request_with_current(tp_p)) { bpf_dbg_printk("Found traceparent from trace map, another process."); diff --git a/bpf/go_nethttp.h b/bpf/go_nethttp.h index 963ca52de..6515561cd 100644 --- a/bpf/go_nethttp.h +++ b/bpf/go_nethttp.h @@ -1107,7 +1107,7 @@ int uprobe_persistConnRoundTrip(struct pt_regs *ctx) { // Must sort the connection info, this map is shared with kprobes which use sorted connection // info always. sort_connection_info(&conn); - set_trace_info_for_connection(&conn, &tp_p); + set_trace_info_for_connection(&conn, TRACE_TYPE_CLIENT, &tp_p); // Setup information for the TC context propagation. // We need the PID id to be able to query ongoing_http and update diff --git a/bpf/http_types.h b/bpf/http_types.h index 360ed3980..352ff31f8 100644 --- a/bpf/http_types.h +++ b/bpf/http_types.h @@ -96,6 +96,7 @@ typedef struct tp_info_pid { tp_info_t tp; u32 pid; u8 valid; + u8 req_type; } tp_info_pid_t; // Here we keep the information that is sent on the ring buffer diff --git a/bpf/k_tracer.h b/bpf/k_tracer.h index dc5cb8490..eab76860b 100644 --- a/bpf/k_tracer.h +++ b/bpf/k_tracer.h @@ -605,7 +605,7 @@ int socket__http_filter(struct __sk_buff *skb) { partial->tcp_seq = tcp.seq; __builtin_memcpy(partial->s_addr, conn.s_addr, sizeof(partial->s_addr)); - tp_info_pid_t *trace_info = trace_info_for_connection(&conn); + tp_info_pid_t *trace_info = trace_info_for_connection(&conn, TRACE_TYPE_CLIENT); if (trace_info) { if (cookie) { // we have an actual socket associated bpf_map_update_elem(&tcp_connection_map, partial, &conn, BPF_ANY); @@ -614,14 +614,15 @@ int socket__http_filter(struct __sk_buff *skb) { connection_info_t *prev_conn = bpf_map_lookup_elem(&tcp_connection_map, partial); if (prev_conn) { - tp_info_pid_t *trace_info = trace_info_for_connection(prev_conn); + tp_info_pid_t *trace_info = + trace_info_for_connection(prev_conn, TRACE_TYPE_CLIENT); if (trace_info) { if (current_immediate_epoch(trace_info->tp.ts) == current_immediate_epoch(bpf_ktime_get_ns())) { //bpf_dbg_printk("Found trace info on another interface, setting it up for this connection"); tp_info_pid_t other_info = {0}; __builtin_memcpy(&other_info, trace_info, sizeof(tp_info_pid_t)); - set_trace_info_for_connection(&conn, &other_info); + set_trace_info_for_connection(&conn, TRACE_TYPE_CLIENT, &other_info); } } } diff --git a/bpf/k_tracer_defs.h b/bpf/k_tracer_defs.h index 30025aa66..da691a2fb 100644 --- a/bpf/k_tracer_defs.h +++ b/bpf/k_tracer_defs.h @@ -87,7 +87,8 @@ static __always_inline void handle_buf_with_args(void *ctx, call_protocol_args_t tp_info_pid_t *existing = bpf_map_lookup_elem(&server_traces, &t_key); if (existing) { __builtin_memcpy(&existing->tp, &info->tp, sizeof(tp_info_t)); - set_trace_info_for_connection(&args->pid_conn.conn, existing); + set_trace_info_for_connection( + &args->pid_conn.conn, TRACE_TYPE_SERVER, existing); } else { bpf_dbg_printk("Didn't find existing trace, this might be a bug!"); } diff --git a/bpf/protocol_http.h b/bpf/protocol_http.h index 6baa1d4c3..a559a676e 100644 --- a/bpf/protocol_http.h +++ b/bpf/protocol_http.h @@ -34,6 +34,110 @@ static __always_inline http_info_t *empty_http_info() { return value; } +static __always_inline u32 trace_type_from_meta(http_connection_metadata_t *meta) { + if (meta->type == EVENT_HTTP_CLIENT) { + return TRACE_TYPE_CLIENT; + } + + return TRACE_TYPE_SERVER; +} + +static __always_inline void http_get_or_create_trace_info(http_connection_metadata_t *meta, + u32 pid, + connection_info_t *conn, + void *u_buf, + int bytes_len, + s32 capture_header_buffer) { + tp_info_pid_t *tp_p = tp_buf(); + + if (!tp_p) { + return; + } + + tp_p->tp.ts = bpf_ktime_get_ns(); + tp_p->tp.flags = 1; + tp_p->valid = 1; + tp_p->pid = pid; // used for avoiding finding stale server requests with client port reuse + tp_p->req_type = (meta) ? meta->type : 0; + + urand_bytes(tp_p->tp.span_id, SPAN_ID_SIZE_BYTES); + + u8 found_tp = 0; + + if (meta) { + if (meta->type == EVENT_HTTP_CLIENT) { + pid_connection_info_t p_conn = {.pid = pid}; + __builtin_memcpy(&p_conn.conn, conn, sizeof(connection_info_t)); + found_tp = find_trace_for_client_request(&p_conn, &tp_p->tp); + } else { + //bpf_dbg_printk("Looking up existing trace for connection"); + //dbg_print_http_connection_info(conn); + + // For server requests, we first look for TCP info (setup by TC ingress) and then we fall back to black-box info. + found_tp = find_trace_for_server_request(conn, &tp_p->tp); + } + } + + if (!found_tp) { + bpf_dbg_printk("Generating new traceparent id"); + new_trace_id(&tp_p->tp); + __builtin_memset(tp_p->tp.parent_id, 0, sizeof(tp_p->tp.span_id)); + } else { + bpf_dbg_printk("Using old traceparent id"); + } + + //unsigned char tp_buf[TP_MAX_VAL_LENGTH]; + //make_tp_string(tp_buf, &tp_p->tp); + //bpf_dbg_printk("tp: %s", tp_buf); + +#ifdef BPF_TRACEPARENT + // The below buffer scan can be expensive on high volume of requests. We make it optional + // for customers to enable it. Off by default. + if (!capture_header_buffer) { + if (meta) { + u32 type = trace_type_from_meta(meta); + set_trace_info_for_connection(conn, type, tp_p); + server_or_client_trace(meta->type, conn, tp_p); + } + return; + } + + unsigned char *buf = tp_char_buf(); + if (buf) { + int buf_len = bytes_len; + bpf_clamp_umax(buf_len, TRACE_BUF_SIZE - 1); + + bpf_probe_read(buf, buf_len, u_buf); + unsigned char *res = bpf_strstr_tp_loop(buf, buf_len); + + if (res) { + bpf_dbg_printk("Found traceparent %s", res); + unsigned char *t_id = extract_trace_id(res); + unsigned char *s_id = extract_span_id(res); + unsigned char *f_id = extract_flags(res); + + decode_hex(tp_p->tp.trace_id, t_id, TRACE_ID_CHAR_LEN); + decode_hex((unsigned char *)&tp_p->tp.flags, f_id, FLAGS_CHAR_LEN); + if (meta && meta->type == EVENT_HTTP_CLIENT) { + decode_hex(tp_p->tp.span_id, s_id, SPAN_ID_CHAR_LEN); + } else { + decode_hex(tp_p->tp.parent_id, s_id, SPAN_ID_CHAR_LEN); + } + } else { + bpf_dbg_printk("No traceparent, making a new trace_id", res); + } + } else { + return; + } +#endif + + if (meta) { + u32 type = trace_type_from_meta(meta); + set_trace_info_for_connection(conn, type, tp_p); + server_or_client_trace(meta->type, conn, tp_p); + } +} + static __always_inline u8 is_http(const unsigned char *p, u32 len, u8 *packet_type) { if (len < MIN_HTTP_SIZE) { return 0; @@ -250,15 +354,16 @@ int protocol_http(void *ctx) { http_connection_metadata_t *meta = connection_meta_by_direction(&args->pid_conn, args->direction, PACKET_TYPE_REQUEST); - get_or_create_trace_info(meta, - args->pid_conn.pid, - &args->pid_conn.conn, - (void *)args->u_buf, - args->bytes_len, - capture_header_buffer); + http_get_or_create_trace_info(meta, + args->pid_conn.pid, + &args->pid_conn.conn, + (void *)args->u_buf, + args->bytes_len, + capture_header_buffer); if (meta) { - tp_info_pid_t *tp_p = trace_info_for_connection(&args->pid_conn.conn); + u32 type = trace_type_from_meta(meta); + tp_info_pid_t *tp_p = trace_info_for_connection(&args->pid_conn.conn, type); if (tp_p) { info->tp = tp_p->tp; } else { diff --git a/bpf/protocol_tcp.h b/bpf/protocol_tcp.h index 9de0c40d0..6943ec067 100644 --- a/bpf/protocol_tcp.h +++ b/bpf/protocol_tcp.h @@ -34,6 +34,56 @@ static __always_inline tcp_req_t *empty_tcp_req() { return value; } +static __always_inline void init_new_trace(tp_info_t *tp) { + new_trace_id(tp); + __builtin_memset(tp->parent_id, 0, sizeof(tp->span_id)); +} + +static __always_inline void +set_tcp_trace_info(u32 type, connection_info_t *conn, tp_info_t *tp, u32 pid) { + tp_info_pid_t *tp_p = tp_buf(); + + if (!tp_p) { + return; + } + + tp_p->tp = *tp; + tp_p->tp.flags = 1; + tp_p->valid = 1; + tp_p->pid = pid; // used for avoiding finding stale server requests with client port reuse + tp_p->req_type = EVENT_TCP_REQUEST; + + set_trace_info_for_connection(conn, type, tp_p); + bpf_dbg_printk("Set traceinfo for conn"); + dbg_print_http_connection_info(conn); + + server_or_client_trace(type, conn, tp_p); +} + +static __always_inline void tcp_get_or_set_trace_info(tcp_req_t *req, + pid_connection_info_t *pid_conn) { + if (req->direction == TCP_SEND) { // Client + u8 found = find_trace_for_client_request(pid_conn, &req->tp); + bpf_dbg_printk("Looking up client trace info, found %d", found); + if (found) { + urand_bytes(req->tp.span_id, SPAN_ID_SIZE_BYTES); + } else { + init_new_trace(&req->tp); + } + + set_tcp_trace_info(TRACE_TYPE_CLIENT, &pid_conn->conn, &req->tp, pid_conn->pid); + } else { // Server + u8 found = find_trace_for_server_request(&pid_conn->conn, &req->tp); + bpf_dbg_printk("Looking up server trace info, found %d", found); + if (found) { + urand_bytes(req->tp.span_id, SPAN_ID_SIZE_BYTES); + } else { + init_new_trace(&req->tp); + } + set_tcp_trace_info(TRACE_TYPE_SERVER, &pid_conn->conn, &req->tp, pid_conn->pid); + } +} + static __always_inline void handle_unknown_tcp_connection(pid_connection_info_t *pid_conn, void *u_buf, int bytes_len, @@ -54,16 +104,11 @@ static __always_inline void handle_unknown_tcp_connection(pid_connection_info_t task_pid(&req->pid); bpf_probe_read(req->buf, K_TCP_MAX_LEN, u_buf); - tp_info_pid_t *server_tp = find_parent_trace(pid_conn); + req->tp.ts = bpf_ktime_get_ns(); - if (server_tp && server_tp->valid && valid_trace(server_tp->tp.trace_id)) { - bpf_dbg_printk("Found existing server tp for client call"); - __builtin_memcpy( - req->tp.trace_id, server_tp->tp.trace_id, sizeof(req->tp.trace_id)); - __builtin_memcpy( - req->tp.parent_id, server_tp->tp.span_id, sizeof(req->tp.parent_id)); - urand_bytes(req->tp.span_id, SPAN_ID_SIZE_BYTES); - } + bpf_dbg_printk("TCP request start, direction = %d, ssl = %d", direction, ssl); + + tcp_get_or_set_trace_info(req, pid_conn); bpf_map_update_elem(&ongoing_tcp_req, pid_conn, req, BPF_ANY); } @@ -90,6 +135,8 @@ static __always_inline void handle_unknown_tcp_connection(pid_connection_info_t bpf_clamp_umax(off, (K_TCP_MAX_LEN / 2)); bpf_probe_read(existing->buf + off, (K_TCP_MAX_LEN / 2), u_buf); existing->len += bytes_len; + } else { + existing->len += bytes_len; } } diff --git a/bpf/trace_common.h b/bpf/trace_common.h index 58eafd693..de8861929 100644 --- a/bpf/trace_common.h +++ b/bpf/trace_common.h @@ -172,7 +172,8 @@ static __always_inline void delete_client_trace_info(pid_connection_info_t *pid_ bpf_dbg_printk("Deleting client trace map for connection"); dbg_print_http_connection_info(&pid_conn->conn); - bpf_map_delete_elem(&trace_map, &pid_conn->conn); + delete_trace_info_for_connection(&pid_conn->conn, TRACE_TYPE_CLIENT); + egress_key_t e_key = { .d_port = pid_conn->conn.d_port, .s_port = pid_conn->conn.s_port, @@ -189,20 +190,20 @@ static __always_inline u8 valid_trace(const unsigned char *trace_id) { return *((u64 *)trace_id) != 0 || *((u64 *)(trace_id + 8)) != 0; } -static __always_inline void server_or_client_trace(http_connection_metadata_t *meta, - connection_info_t *conn, - tp_info_pid_t *tp_p) { - if (!meta) { - return; - } - if (meta->type == EVENT_HTTP_REQUEST) { +static __always_inline void +server_or_client_trace(u8 type, connection_info_t *conn, tp_info_pid_t *tp_p) { + if (type == EVENT_HTTP_REQUEST) { trace_key_t t_key = {0}; task_tid(&t_key.p_key); t_key.extra_id = extra_runtime_id(); tp_info_pid_t *existing = bpf_map_lookup_elem(&server_traces, &t_key); - // we have a conflict, mark this invalid and do nothing - if (existing) { + // We have a conflict, mark this invalid and do nothing + // We look for conflicts on HTTP requests only and only with other HTTP requests, + // since TCP requests can come one after another and with SSL we can have a mix + // of TCP and HTTP requests. + if (existing && (existing->req_type == tp_p->req_type) && + (tp_p->req_type == EVENT_HTTP_REQUEST)) { bpf_dbg_printk("Found conflicting server span, marking as invalid, id=%llx", bpf_get_current_pid_tgid()); existing->valid = 0; @@ -226,122 +227,46 @@ static __always_inline void server_or_client_trace(http_connection_metadata_t *m } } -static __always_inline void get_or_create_trace_info(http_connection_metadata_t *meta, - u32 pid, - connection_info_t *conn, - void *u_buf, - int bytes_len, - s32 capture_header_buffer) { - tp_info_pid_t *tp_p = tp_buf(); - - if (!tp_p) { - return; - } - - tp_p->tp.ts = bpf_ktime_get_ns(); - tp_p->tp.flags = 1; - tp_p->valid = 1; - tp_p->pid = pid; // used for avoiding finding stale server requests with client port reuse - - urand_bytes(tp_p->tp.span_id, SPAN_ID_SIZE_BYTES); - +static __always_inline u8 find_trace_for_server_request(connection_info_t *conn, tp_info_t *tp) { u8 found_tp = 0; - - if (meta) { - if (meta->type == EVENT_HTTP_CLIENT) { - pid_connection_info_t p_conn = {.pid = pid}; - __builtin_memcpy(&p_conn.conn, conn, sizeof(connection_info_t)); - tp_info_pid_t *server_tp = find_parent_trace(&p_conn); - - if (server_tp && server_tp->valid && valid_trace(server_tp->tp.trace_id)) { - found_tp = 1; - bpf_dbg_printk("Found existing server tp for client call"); - __builtin_memcpy( - tp_p->tp.trace_id, server_tp->tp.trace_id, sizeof(tp_p->tp.trace_id)); - __builtin_memcpy( - tp_p->tp.parent_id, server_tp->tp.span_id, sizeof(tp_p->tp.parent_id)); - } - } else { - //bpf_dbg_printk("Looking up existing trace for connection"); - //dbg_print_http_connection_info(conn); - - // For server requests, we first look for TCP info (setup by TC ingress) and then we fall back to black-box info. - tp_info_pid_t *existing_tp = bpf_map_lookup_elem(&incoming_trace_map, conn); - if (existing_tp) { - found_tp = 1; - bpf_dbg_printk("Found incoming (TCP) tp for server request"); - __builtin_memcpy( - tp_p->tp.trace_id, existing_tp->tp.trace_id, sizeof(tp_p->tp.trace_id)); - __builtin_memcpy( - tp_p->tp.parent_id, existing_tp->tp.span_id, sizeof(tp_p->tp.parent_id)); - bpf_map_delete_elem(&incoming_trace_map, conn); - } else { - existing_tp = trace_info_for_connection(conn); - - if (!disable_black_box_cp && correlated_requests(tp_p, existing_tp)) { - found_tp = 1; - bpf_dbg_printk("Found existing correlated tp for server request"); - __builtin_memcpy( - tp_p->tp.trace_id, existing_tp->tp.trace_id, sizeof(tp_p->tp.trace_id)); - __builtin_memcpy( - tp_p->tp.parent_id, existing_tp->tp.span_id, sizeof(tp_p->tp.parent_id)); - } - } - } - } - - if (!found_tp) { - bpf_dbg_printk("Generating new traceparent id"); - new_trace_id(&tp_p->tp); - __builtin_memset(tp_p->tp.parent_id, 0, sizeof(tp_p->tp.span_id)); + tp_info_pid_t *existing_tp = bpf_map_lookup_elem(&incoming_trace_map, conn); + if (existing_tp) { + found_tp = 1; + bpf_dbg_printk("Found incoming (TCP) tp for server request"); + __builtin_memcpy(tp->trace_id, existing_tp->tp.trace_id, sizeof(tp->trace_id)); + __builtin_memcpy(tp->parent_id, existing_tp->tp.span_id, sizeof(tp->parent_id)); + bpf_map_delete_elem(&incoming_trace_map, conn); } else { - bpf_dbg_printk("Using old traceparent id"); - } + bpf_dbg_printk("Looking up tracemap for"); + dbg_print_http_connection_info(conn); - //unsigned char tp_buf[TP_MAX_VAL_LENGTH]; - //make_tp_string(tp_buf, &tp_p->tp); - //bpf_dbg_printk("tp: %s", tp_buf); - -#ifdef BPF_TRACEPARENT - // The below buffer scan can be expensive on high volume of requests. We make it optional - // for customers to enable it. Off by default. - if (!capture_header_buffer) { - set_trace_info_for_connection(conn, tp_p); - server_or_client_trace(meta, conn, tp_p); - return; - } + existing_tp = trace_info_for_connection(conn, TRACE_TYPE_CLIENT); - unsigned char *buf = tp_char_buf(); - if (buf) { - int buf_len = bytes_len; - bpf_clamp_umax(buf_len, TRACE_BUF_SIZE - 1); + bpf_dbg_printk("existing_tp %llx", existing_tp); - bpf_probe_read(buf, buf_len, u_buf); - unsigned char *res = bpf_strstr_tp_loop(buf, buf_len); + if (!disable_black_box_cp && correlated_requests(tp, existing_tp)) { + found_tp = 1; + bpf_dbg_printk("Found existing correlated tp for server request"); + __builtin_memcpy(tp->trace_id, existing_tp->tp.trace_id, sizeof(tp->trace_id)); + __builtin_memcpy(tp->parent_id, existing_tp->tp.span_id, sizeof(tp->parent_id)); + } + } - if (res) { - bpf_dbg_printk("Found traceparent %s", res); - unsigned char *t_id = extract_trace_id(res); - unsigned char *s_id = extract_span_id(res); - unsigned char *f_id = extract_flags(res); + return found_tp; +} - decode_hex(tp_p->tp.trace_id, t_id, TRACE_ID_CHAR_LEN); - decode_hex((unsigned char *)&tp_p->tp.flags, f_id, FLAGS_CHAR_LEN); - if (meta && meta->type == EVENT_HTTP_CLIENT) { - decode_hex(tp_p->tp.span_id, s_id, SPAN_ID_CHAR_LEN); - } else { - decode_hex(tp_p->tp.parent_id, s_id, SPAN_ID_CHAR_LEN); - } - } else { - bpf_dbg_printk("No traceparent, making a new trace_id", res); - } - } else { - return; +static __always_inline u8 find_trace_for_client_request(pid_connection_info_t *p_conn, + tp_info_t *tp) { + u8 found_tp = 0; + tp_info_pid_t *server_tp = find_parent_trace(p_conn); + if (server_tp && server_tp->valid && valid_trace(server_tp->tp.trace_id)) { + found_tp = 1; + bpf_dbg_printk("Found existing server tp for client call"); + __builtin_memcpy(tp->trace_id, server_tp->tp.trace_id, sizeof(tp->trace_id)); + __builtin_memcpy(tp->parent_id, server_tp->tp.span_id, sizeof(tp->parent_id)); } -#endif - set_trace_info_for_connection(conn, tp_p); - server_or_client_trace(meta, conn, tp_p); + return found_tp; } #endif diff --git a/bpf/tracing.h b/bpf/tracing.h index ccbf26e11..44d0a776f 100644 --- a/bpf/tracing.h +++ b/bpf/tracing.h @@ -10,10 +10,18 @@ volatile const u32 disable_black_box_cp; +#define TRACE_TYPE_SERVER 1 +#define TRACE_TYPE_CLIENT 2 + +typedef struct trace_map_key { + connection_info_t conn; + u32 type; +} trace_map_key_t; + struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, connection_info_t); // key: the connection info - __type(value, tp_info_pid_t); // value: traceparent info + __type(key, trace_map_key_t); // key: the connection info + __type(value, tp_info_pid_t); // value: traceparent info __uint(max_entries, MAX_CONCURRENT_SHARED_REQUESTS); __uint(pinning, BEYLA_PIN_INTERNAL); } trace_map SEC(".maps"); @@ -55,13 +63,29 @@ static __always_inline void make_tp_string(unsigned char *buf, const tp_info_t * *buf = (tp->flags == 0) ? '0' : '1'; } -static __always_inline tp_info_pid_t *trace_info_for_connection(connection_info_t *conn) { - return (tp_info_pid_t *)bpf_map_lookup_elem(&trace_map, conn); +static __always_inline void +trace_key_from_conn(trace_map_key_t *key, connection_info_t *conn, u32 type) { + key->conn = *conn; + key->type = type; } -static __always_inline void set_trace_info_for_connection(connection_info_t *conn, - tp_info_pid_t *other_info) { - bpf_map_update_elem(&trace_map, conn, other_info, BPF_ANY); +static __always_inline tp_info_pid_t *trace_info_for_connection(connection_info_t *conn, u32 type) { + trace_map_key_t key = {}; + trace_key_from_conn(&key, conn, type); + return (tp_info_pid_t *)bpf_map_lookup_elem(&trace_map, &key); +} + +static __always_inline void +set_trace_info_for_connection(connection_info_t *conn, u32 type, tp_info_pid_t *info) { + trace_map_key_t key = {}; + trace_key_from_conn(&key, conn, type); + bpf_map_update_elem(&trace_map, &key, info, BPF_ANY); +} + +static __always_inline void delete_trace_info_for_connection(connection_info_t *conn, u32 type) { + trace_map_key_t key = {}; + trace_key_from_conn(&key, conn, type); + bpf_map_delete_elem(&trace_map, &key); } static __always_inline u64 current_epoch(u64 ts) { @@ -74,16 +98,17 @@ static __always_inline u64 current_immediate_epoch(u64 ts) { return temp * NANOSECONDS_PER_IMM_EPOCH; } -static __always_inline u8 correlated_requests(tp_info_pid_t *tp, tp_info_pid_t *existing_tp) { +static __always_inline u8 correlated_requests(tp_info_t *tp, tp_info_pid_t *existing_tp) { if (!existing_tp) { return 0; } // We check for correlated requests which are in order, but from different PIDs - // Same PID means that we had client port reuse, which might falsely match prior + // Same PID means that we had client port reuse (*unless one was client and the other + // was a server request, i.e. the type check), which might falsely match prior // transaction if it happened during the same epoch. - if ((tp->tp.ts >= existing_tp->tp.ts) && (tp->pid != existing_tp->pid)) { - return current_epoch(tp->tp.ts) == current_epoch(existing_tp->tp.ts); + if (tp->ts >= existing_tp->tp.ts) { + return current_epoch(tp->ts) == current_epoch(existing_tp->tp.ts); } return 0; @@ -94,15 +119,15 @@ static __always_inline u8 correlated_request_with_current(tp_info_pid_t *existin return 0; } - u64 pid_tid = bpf_get_current_pid_tgid(); + //u64 pid_tid = bpf_get_current_pid_tgid(); u64 ts = bpf_ktime_get_ns(); - u32 pid = pid_from_pid_tgid(pid_tid); + //u32 pid = pid_from_pid_tgid(pid_tid); // We check for correlated requests which are in order, but from different PIDs // Same PID means that we had client port reuse, which might falsely match prior // transaction if it happened during the same epoch. - if ((ts >= existing_tp->tp.ts) && (pid != existing_tp->pid)) { + if (ts >= existing_tp->tp.ts) { return current_epoch(ts) == current_epoch(existing_tp->tp.ts); } diff --git a/pkg/internal/ebpf/common/fast_cgi_detect_transform.go b/pkg/internal/ebpf/common/fast_cgi_detect_transform.go new file mode 100644 index 000000000..780bf64f7 --- /dev/null +++ b/pkg/internal/ebpf/common/fast_cgi_detect_transform.go @@ -0,0 +1,147 @@ +package ebpfcommon + +import ( + "bytes" + "strconv" + "unsafe" + + trace2 "go.opentelemetry.io/otel/trace" + + "github.com/grafana/beyla/pkg/internal/request" +) + +const fastCGIRequestHeaderLen = 24 +const requestMethodKey = "REQUEST_METHOD" +const requestURIKey = "REQUEST_URI" +const scriptNameKey = "SCRIPT_NAME" +const responseError = 7 // FCGI_STDERR +const responseStatusKey = "Status: " + +func parseCGITable(b []byte) map[string]string { + res := map[string]string{} + + for { + key := "" + val := "" + if len(b) <= 2 { // key len + val len + break + } + + keyLen := int(b[0]) + valLen := int(b[1]) + + if keyLen < 0 || valLen < 0 { + break + } + + b = b[2:] + + if keyLen > 0 && len(b) >= keyLen { + key = string(b[:keyLen]) + b = b[keyLen:] + } + + if valLen > 0 && len(b) >= valLen { + val = string(b[:valLen]) + b = b[valLen:] + } + + if key != "" { + res[key] = val + } + } + + return res +} + +func maybeFastCGI(b []byte) bool { + if len(b) <= fastCGIRequestHeaderLen { + return false + } + + methodPos := bytes.Index(b, []byte(requestMethodKey)) + + return methodPos >= 0 +} + +func detectFastCGI(b, rb []byte) (string, string, int) { + b = b[fastCGIRequestHeaderLen:] + + methodPos := bytes.Index(b, []byte(requestMethodKey)) + if methodPos >= 0 { + kv := parseCGITable(b) + + method, ok := kv[requestMethodKey] + if !ok { + return "", "", -1 + } + uri, ok := kv[requestURIKey] + if !ok { + uri = kv[scriptNameKey] + } + + // Translate the status code into HTTP, 200 OK, 500 ERR + status := 200 + + if len(rb) >= 2 { + if rb[1] == responseError { + status = 500 + } + + statusPos := bytes.Index(rb, []byte(responseStatusKey)) + if statusPos >= 0 { + rb = rb[statusPos+len(responseStatusKey):] + nextSpace := bytes.Index(rb, []byte(" ")) + if nextSpace > 0 { + statusStr := string(rb[:nextSpace]) + if parsed, err := strconv.ParseInt(statusStr, 10, 32); err == nil { + status = int(parsed) + } + } + } + } + + return method, uri, status + } + return "", "", -1 +} + +func TCPToFastCGIToSpan(trace *TCPRequestInfo, op, uri string, status int) request.Span { + peer := "" + hostname := "" + hostPort := 0 + + if trace.ConnInfo.S_port != 0 || trace.ConnInfo.D_port != 0 { + peer, hostname = (*BPFConnInfo)(unsafe.Pointer(&trace.ConnInfo)).reqHostInfo() + hostPort = int(trace.ConnInfo.D_port) + } + + reqType := request.EventTypeHTTPClient + if trace.Direction == 0 { + reqType = request.EventTypeHTTP + } + + return request.Span{ + Type: reqType, + Method: op, + Path: uri, + Peer: peer, + PeerPort: int(trace.ConnInfo.S_port), + Host: hostname, + HostPort: hostPort, + ContentLength: int64(trace.Len), + RequestStart: int64(trace.StartMonotimeNs), + Start: int64(trace.StartMonotimeNs), + End: int64(trace.EndMonotimeNs), + Status: status, + TraceID: trace2.TraceID(trace.Tp.TraceId), + SpanID: trace2.SpanID(trace.Tp.SpanId), + ParentSpanID: trace2.SpanID(trace.Tp.ParentId), + Flags: trace.Tp.Flags, + Pid: request.PidInfo{ + HostPID: trace.Pid.HostPid, + UserPID: trace.Pid.UserPid, + Namespace: trace.Pid.Ns, + }, + } +} diff --git a/pkg/internal/ebpf/common/fast_cgi_detect_transform_test.go b/pkg/internal/ebpf/common/fast_cgi_detect_transform_test.go new file mode 100644 index 000000000..618e2917a --- /dev/null +++ b/pkg/internal/ebpf/common/fast_cgi_detect_transform_test.go @@ -0,0 +1,193 @@ +package ebpfcommon + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMaybeFastCGI(t *testing.T) { + tests := []struct { + name string + input []byte + inputLen int + expected bool + }{ + { + name: "Correct values", + input: []byte{1, 1, 0, 1, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 1, 217, 7, 0, 12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + inputLen: 100, + expected: true, + }, + { + name: "Empty", + input: []byte{}, + inputLen: 100, + expected: false, + }, + { + name: "Short", + input: []byte{1, 1, 0, 1, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 1, 217, 7, 0, 12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + inputLen: 23, + expected: false, + }, + { + name: "REQUEST METHOD not in the text", + input: []byte{1, 1, 0, 1, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 1, 217, 7, 0, 12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 81, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + inputLen: 100, + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ilen := len(tt.input) + if ilen > tt.inputLen { + ilen = tt.inputLen + } + res := maybeFastCGI(tt.input[0:ilen]) + assert.Equal(t, tt.expected, res) + }) + } + +} + +func TestParseCGITable(t *testing.T) { + tests := []struct { + name string + input []byte + inputLen int + expected map[string]string + }{ + { + name: "Correct values", + input: []byte{12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + inputLen: 100, + expected: map[string]string{"CONTENT_LENGTH": "", "CONTENT_TYPE": "", "QUERY_STRING": "", "REQUEST_METHOD": "GET", "REQUEST_URI": "/ping", "SCRIPT_NAME": "/ping"}, + }, + { + name: "Empty", + input: []byte{}, + inputLen: 100, + expected: map[string]string{}, + }, + { + name: "Short", + input: []byte{12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + inputLen: 23, + expected: map[string]string{"QUERY_STRING": ""}, + }, + { + name: "Very Short", + input: []byte{12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + inputLen: 3, + expected: map[string]string{}, + }, + { + name: "Broken at key", + input: []byte{1, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + inputLen: 3, + expected: map[string]string{"Q": ""}, + }, + { + name: "Empty key for query string", + input: []byte{0, 12, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + inputLen: 100, + expected: map[string]string{"CONTENT_LENGTH": "", "CONTENT_TYPE": "", "REQUEST_METHOD": "GET", "REQUEST_URI": "/ping", "SCRIPT_NAME": "/ping"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ilen := len(tt.input) + if ilen > tt.inputLen { + ilen = tt.inputLen + } + res := parseCGITable(tt.input[0:ilen]) + assert.Equal(t, tt.expected, res) + }) + } + +} + +func TestDetectFastCGI(t *testing.T) { + tests := []struct { + name string + input []byte + output []byte + inputLen int + outputLen int + expectedMethod string + expectedPath string + expectedResult int + }{ + { + name: "Correct values", + input: []byte{1, 1, 0, 1, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 1, 217, 7, 0, 12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + output: []byte{1, 0, 1, 0, 0}, + inputLen: 200, + outputLen: 20, + expectedMethod: "GET", + expectedPath: "/ping", + expectedResult: 200, + }, + { + name: "Correct values, error", + input: []byte{1, 1, 0, 1, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 1, 217, 7, 0, 12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + output: []byte{1, 7, 1, 0, 0}, + inputLen: 200, + outputLen: 20, + expectedMethod: "GET", + expectedPath: "/ping", + expectedResult: 500, + }, + { + name: "Correct values, status 404", + input: []byte{1, 1, 0, 1, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 1, 217, 7, 0, 12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + output: []byte{1, 6, 0, 1, 0, 106, 6, 0, 83, 116, 97, 116, 117, 115, 58, 32, 52, 48, 52, 32, 78, 111, 116, 32, 70, 111, 117, 110, 100, 13, 10, 88, 45, 80, 111, 119, 101, 114, 101, 100, 45, 66, 121, 58, 32, 80, 72, 80, 47, 56, 46, 52, 46, 49, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 32, 116, 101, 120, 116, 47, 104, 116, 109, 108, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 85, 84, 70, 45, 56, 13, 10, 13, 10, 70, 105, 108, 101, 32, 110, 111, 116, 32, 102, 111, 117, 110, 100, 46, 10, 0, 0, 0, 0, 0, 0, 1, 3, 0, 1, 0, 8, 0, 0}, + inputLen: 200, + outputLen: 200, + expectedMethod: "GET", + expectedPath: "/ping", + expectedResult: 404, + }, + { + name: "Not enough data", + input: []byte{1, 1, 0, 1, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 1, 217, 7, 0, 12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + output: []byte{1, 7, 1, 0, 0}, + inputLen: 100, + outputLen: 1, + expectedMethod: "GET", + expectedPath: "", + expectedResult: 200, + }, + { + name: "Empty", + input: []byte{1, 1, 0, 1, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 1, 217, 7, 0, 12, 0, 81, 85, 69, 82, 89, 95, 83, 84, 82, 73, 78, 71, 14, 3, 82, 69, 81, 85, 69, 83, 84, 95, 77, 69, 84, 72, 79, 68, 71, 69, 84, 12, 0, 67, 79, 78, 84, 69, 78, 84, 95, 84, 89, 80, 69, 14, 0, 67, 79, 78, 84, 69, 78, 84, 95, 76, 69, 78, 71, 84, 72, 11, 5, 83, 67, 82, 73, 80, 84, 95, 78, 65, 77, 69, 47, 112, 105, 110, 103, 11, 5, 82, 69, 81, 85, 69, 83, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 12, 5, 68, 79, 67, 85, 77, 69, 78, 84, 95, 85, 82, 73, 47, 112, 105, 110, 103, 13, 13, 68, 79, 67, 85, 77, 69, 78, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + output: []byte{}, + inputLen: 24, + outputLen: 1, + expectedMethod: "", + expectedPath: "", + expectedResult: -1, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ilen := len(tt.input) + if ilen > tt.inputLen { + ilen = tt.inputLen + } + olen := len(tt.output) + if olen > tt.outputLen { + olen = tt.outputLen + } + method, path, status := detectFastCGI(tt.input[0:ilen], tt.output[0:olen]) + assert.Equal(t, tt.expectedMethod, method) + assert.Equal(t, tt.expectedPath, path) + assert.Equal(t, tt.expectedResult, status) + }) + } + +} diff --git a/pkg/internal/ebpf/common/tcp_detect_transform.go b/pkg/internal/ebpf/common/tcp_detect_transform.go index 7f6ddc5ae..efada79e8 100644 --- a/pkg/internal/ebpf/common/tcp_detect_transform.go +++ b/pkg/internal/ebpf/common/tcp_detect_transform.go @@ -36,9 +36,18 @@ func ReadTCPRequestIntoSpan(record *ringbuf.Record, filter ServiceFilter) (reque // Check if we have a SQL statement op, table, sql := detectSQLBytes(b) - switch { - case validSQL(op, table): + if validSQL(op, table) { return TCPToSQLToSpan(&event, op, table, sql), false, nil + } + + if maybeFastCGI(b) { + op, uri, status := detectFastCGI(b, event.Rbuf[:rl]) + if status >= 0 { + return TCPToFastCGIToSpan(&event, op, uri, status), false, nil + } + } + + switch { case isRedis(b) && isRedis(event.Rbuf[:rl]): op, text, ok := parseRedisRequest(string(b)) diff --git a/pkg/internal/ebpf/generictracer/bpf_arm64_bpfel.go b/pkg/internal/ebpf/generictracer/bpf_arm64_bpfel.go index 18f32a95f..7ed36fe64 100644 --- a/pkg/internal/ebpf/generictracer/bpf_arm64_bpfel.go +++ b/pkg/internal/ebpf/generictracer/bpf_arm64_bpfel.go @@ -194,9 +194,10 @@ type bpfTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpfTraceKeyT struct { @@ -204,6 +205,11 @@ type bpfTraceKeyT struct { ExtraId uint64 } +type bpfTraceMapKeyT struct { + Conn bpfConnectionInfoT + Type uint32 +} + // loadBpf returns the embedded CollectionSpec for bpf. func loadBpf() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_BpfBytes) diff --git a/pkg/internal/ebpf/generictracer/bpf_arm64_bpfel.o b/pkg/internal/ebpf/generictracer/bpf_arm64_bpfel.o index 2463e8696..53fc43261 100644 --- a/pkg/internal/ebpf/generictracer/bpf_arm64_bpfel.o +++ b/pkg/internal/ebpf/generictracer/bpf_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:901c1861fadb70c62cbde8ed18facefbe429874c0ddc65e7d5b8a733ff5c1b75 -size 522312 +oid sha256:2abff0827a0fa68c39db2dab7e06f526320eed0b830e8d12c711291b1f3504a1 +size 535592 diff --git a/pkg/internal/ebpf/generictracer/bpf_debug_arm64_bpfel.go b/pkg/internal/ebpf/generictracer/bpf_debug_arm64_bpfel.go index 9bba3be31..08b762067 100644 --- a/pkg/internal/ebpf/generictracer/bpf_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/generictracer/bpf_debug_arm64_bpfel.go @@ -194,9 +194,10 @@ type bpf_debugTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_debugTraceKeyT struct { @@ -204,6 +205,11 @@ type bpf_debugTraceKeyT struct { ExtraId uint64 } +type bpf_debugTraceMapKeyT struct { + Conn bpf_debugConnectionInfoT + Type uint32 +} + // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. func loadBpf_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_debugBytes) diff --git a/pkg/internal/ebpf/generictracer/bpf_debug_arm64_bpfel.o b/pkg/internal/ebpf/generictracer/bpf_debug_arm64_bpfel.o index 9ffbe61da..0261cedd1 100644 --- a/pkg/internal/ebpf/generictracer/bpf_debug_arm64_bpfel.o +++ b/pkg/internal/ebpf/generictracer/bpf_debug_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1de3096504b0c70a83b572d58307ca29f2d80cc67f488771cc7eb7bdd47af46f -size 852968 +oid sha256:ba13d5b910fe88ef0583ae978d0e80b0325014c8dcb61cfb9578c84fb9589d00 +size 898240 diff --git a/pkg/internal/ebpf/generictracer/bpf_debug_x86_bpfel.go b/pkg/internal/ebpf/generictracer/bpf_debug_x86_bpfel.go index d4dd3e499..47f86ee59 100644 --- a/pkg/internal/ebpf/generictracer/bpf_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/generictracer/bpf_debug_x86_bpfel.go @@ -194,9 +194,10 @@ type bpf_debugTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_debugTraceKeyT struct { @@ -204,6 +205,11 @@ type bpf_debugTraceKeyT struct { ExtraId uint64 } +type bpf_debugTraceMapKeyT struct { + Conn bpf_debugConnectionInfoT + Type uint32 +} + // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. func loadBpf_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_debugBytes) diff --git a/pkg/internal/ebpf/generictracer/bpf_debug_x86_bpfel.o b/pkg/internal/ebpf/generictracer/bpf_debug_x86_bpfel.o index 6a7c5a368..d55397614 100644 --- a/pkg/internal/ebpf/generictracer/bpf_debug_x86_bpfel.o +++ b/pkg/internal/ebpf/generictracer/bpf_debug_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:36282e7065f566fa2ee5959b1c7d833366a58fcec31852f35b46caabb3163f58 -size 852480 +oid sha256:d624cf08b2b1a73cb5c4807a6b9f72c23650b0d2eca98ab19da674718014f6bf +size 897752 diff --git a/pkg/internal/ebpf/generictracer/bpf_tp_arm64_bpfel.go b/pkg/internal/ebpf/generictracer/bpf_tp_arm64_bpfel.go index 21a6aa111..a77bc856b 100644 --- a/pkg/internal/ebpf/generictracer/bpf_tp_arm64_bpfel.go +++ b/pkg/internal/ebpf/generictracer/bpf_tp_arm64_bpfel.go @@ -194,9 +194,10 @@ type bpf_tpTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_tpTraceKeyT struct { @@ -204,6 +205,11 @@ type bpf_tpTraceKeyT struct { ExtraId uint64 } +type bpf_tpTraceMapKeyT struct { + Conn bpf_tpConnectionInfoT + Type uint32 +} + // loadBpf_tp returns the embedded CollectionSpec for bpf_tp. func loadBpf_tp() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_tpBytes) diff --git a/pkg/internal/ebpf/generictracer/bpf_tp_arm64_bpfel.o b/pkg/internal/ebpf/generictracer/bpf_tp_arm64_bpfel.o index 2133b568d..0380461ec 100644 --- a/pkg/internal/ebpf/generictracer/bpf_tp_arm64_bpfel.o +++ b/pkg/internal/ebpf/generictracer/bpf_tp_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b864fd2d3608c18ebb35b1fba0ee54acbb79693ab1d1a0055101232646bcf9b1 -size 536088 +oid sha256:f41c44d5d523bbc37374ab62e91aaa0958d2faf1d44bec8635d0c7d8b625f3d7 +size 549888 diff --git a/pkg/internal/ebpf/generictracer/bpf_tp_debug_arm64_bpfel.go b/pkg/internal/ebpf/generictracer/bpf_tp_debug_arm64_bpfel.go index c6fabfe1f..76ae2fd6e 100644 --- a/pkg/internal/ebpf/generictracer/bpf_tp_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/generictracer/bpf_tp_debug_arm64_bpfel.go @@ -194,9 +194,10 @@ type bpf_tp_debugTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_tp_debugTraceKeyT struct { @@ -204,6 +205,11 @@ type bpf_tp_debugTraceKeyT struct { ExtraId uint64 } +type bpf_tp_debugTraceMapKeyT struct { + Conn bpf_tp_debugConnectionInfoT + Type uint32 +} + // loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. func loadBpf_tp_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_tp_debugBytes) diff --git a/pkg/internal/ebpf/generictracer/bpf_tp_debug_arm64_bpfel.o b/pkg/internal/ebpf/generictracer/bpf_tp_debug_arm64_bpfel.o index 1f67802ef..f2d6358b8 100644 --- a/pkg/internal/ebpf/generictracer/bpf_tp_debug_arm64_bpfel.o +++ b/pkg/internal/ebpf/generictracer/bpf_tp_debug_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d38274bbcbc20147a6c9f8c7e32dcc75c3b6e881427095268d1f3118558b74af -size 870528 +oid sha256:38bcf808af9dd1fff7d0670425e2e155b391f908101e86931883b17fd94b27f4 +size 916064 diff --git a/pkg/internal/ebpf/generictracer/bpf_tp_debug_x86_bpfel.go b/pkg/internal/ebpf/generictracer/bpf_tp_debug_x86_bpfel.go index 1344bb046..cda7748ec 100644 --- a/pkg/internal/ebpf/generictracer/bpf_tp_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/generictracer/bpf_tp_debug_x86_bpfel.go @@ -194,9 +194,10 @@ type bpf_tp_debugTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_tp_debugTraceKeyT struct { @@ -204,6 +205,11 @@ type bpf_tp_debugTraceKeyT struct { ExtraId uint64 } +type bpf_tp_debugTraceMapKeyT struct { + Conn bpf_tp_debugConnectionInfoT + Type uint32 +} + // loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. func loadBpf_tp_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_tp_debugBytes) diff --git a/pkg/internal/ebpf/generictracer/bpf_tp_debug_x86_bpfel.o b/pkg/internal/ebpf/generictracer/bpf_tp_debug_x86_bpfel.o index 4727100d9..2e6100264 100644 --- a/pkg/internal/ebpf/generictracer/bpf_tp_debug_x86_bpfel.o +++ b/pkg/internal/ebpf/generictracer/bpf_tp_debug_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dde1fef8a69c1c1fca551d3a3d34033877b34960e886c46418576484b95b1970 -size 870048 +oid sha256:af61a5c8ff1e1a7e119ebdf8089f40b19d7186b9d796049b2c61f5bbb3853b97 +size 915576 diff --git a/pkg/internal/ebpf/generictracer/bpf_tp_x86_bpfel.go b/pkg/internal/ebpf/generictracer/bpf_tp_x86_bpfel.go index 7a40e7dd2..5bd49d7cf 100644 --- a/pkg/internal/ebpf/generictracer/bpf_tp_x86_bpfel.go +++ b/pkg/internal/ebpf/generictracer/bpf_tp_x86_bpfel.go @@ -194,9 +194,10 @@ type bpf_tpTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_tpTraceKeyT struct { @@ -204,6 +205,11 @@ type bpf_tpTraceKeyT struct { ExtraId uint64 } +type bpf_tpTraceMapKeyT struct { + Conn bpf_tpConnectionInfoT + Type uint32 +} + // loadBpf_tp returns the embedded CollectionSpec for bpf_tp. func loadBpf_tp() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_tpBytes) diff --git a/pkg/internal/ebpf/generictracer/bpf_tp_x86_bpfel.o b/pkg/internal/ebpf/generictracer/bpf_tp_x86_bpfel.o index 7e6efca47..ace917dc1 100644 --- a/pkg/internal/ebpf/generictracer/bpf_tp_x86_bpfel.o +++ b/pkg/internal/ebpf/generictracer/bpf_tp_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94e556cf09dbb675fccf4f1dec815d19d7f2e74d5674d472d710c92e13dfe5f6 -size 535488 +oid sha256:367c24125e88846560f792e060ac1e6b9ee28069b63e53af4f94533cf4580f35 +size 549296 diff --git a/pkg/internal/ebpf/generictracer/bpf_x86_bpfel.go b/pkg/internal/ebpf/generictracer/bpf_x86_bpfel.go index 4dd6e40aa..1dc380608 100644 --- a/pkg/internal/ebpf/generictracer/bpf_x86_bpfel.go +++ b/pkg/internal/ebpf/generictracer/bpf_x86_bpfel.go @@ -194,9 +194,10 @@ type bpfTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpfTraceKeyT struct { @@ -204,6 +205,11 @@ type bpfTraceKeyT struct { ExtraId uint64 } +type bpfTraceMapKeyT struct { + Conn bpfConnectionInfoT + Type uint32 +} + // loadBpf returns the embedded CollectionSpec for bpf. func loadBpf() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_BpfBytes) diff --git a/pkg/internal/ebpf/generictracer/bpf_x86_bpfel.o b/pkg/internal/ebpf/generictracer/bpf_x86_bpfel.o index f0f41ee74..464dfcd2a 100644 --- a/pkg/internal/ebpf/generictracer/bpf_x86_bpfel.o +++ b/pkg/internal/ebpf/generictracer/bpf_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:939822a2a053d06fdeccdf6b435831753b432e7716afaff20f9d930d7b9bddf3 -size 521712 +oid sha256:7876d41ff32500f24006d0af1713900d1a77f8c021b39af986aec87074bca8e1 +size 534992 diff --git a/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.go index ef639571d..3148e6091 100644 --- a/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.go @@ -159,10 +159,11 @@ type bpfTopicT struct { } type bpfTpInfoPidT struct { - Tp bpfTpInfoT - Pid uint32 - Valid uint8 - _ [3]byte + Tp bpfTpInfoT + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpfTpInfoT struct { @@ -174,6 +175,11 @@ type bpfTpInfoT struct { _ [7]byte } +type bpfTraceMapKeyT struct { + Conn bpfConnectionInfoT + Type uint32 +} + // loadBpf returns the embedded CollectionSpec for bpf. func loadBpf() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_BpfBytes) diff --git a/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.o index f0c083061..da0486c66 100644 --- a/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2eddb3da6240b3f38e59d8e50bc2af0e5394a67e2e06c747ba3a525e90afe81d -size 380752 +oid sha256:2705a4b8715a347b64b04dc633e5fea4c2ba70c890db9055fbf6927a6715698a +size 381008 diff --git a/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.go index 4ddc9f8b5..d4e27361c 100644 --- a/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.go @@ -159,10 +159,11 @@ type bpf_debugTopicT struct { } type bpf_debugTpInfoPidT struct { - Tp bpf_debugTpInfoT - Pid uint32 - Valid uint8 - _ [3]byte + Tp bpf_debugTpInfoT + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_debugTpInfoT struct { @@ -174,6 +175,11 @@ type bpf_debugTpInfoT struct { _ [7]byte } +type bpf_debugTraceMapKeyT struct { + Conn bpf_debugConnectionInfoT + Type uint32 +} + // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. func loadBpf_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_debugBytes) diff --git a/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.o index d5ecebd8f..fef714d74 100644 --- a/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:617e4272e192efe8fd4bd83f6ac1bab47a26a426238c16054d04a62173fa777d -size 883880 +oid sha256:32f9fd6f88f5c616e8312c3a1454e0656f25a53a71c5331b86b3c888132dedfd +size 884144 diff --git a/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.go index 8f46eaa98..9df6941a4 100644 --- a/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.go @@ -159,10 +159,11 @@ type bpf_debugTopicT struct { } type bpf_debugTpInfoPidT struct { - Tp bpf_debugTpInfoT - Pid uint32 - Valid uint8 - _ [3]byte + Tp bpf_debugTpInfoT + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_debugTpInfoT struct { @@ -174,6 +175,11 @@ type bpf_debugTpInfoT struct { _ [7]byte } +type bpf_debugTraceMapKeyT struct { + Conn bpf_debugConnectionInfoT + Type uint32 +} + // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. func loadBpf_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_debugBytes) diff --git a/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.o index d93bdaf4e..440d589be 100644 --- a/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:30f75b36b2ec2bfea2b668f286a87885789f6f9fd9e2af43c02c7813ab23f449 -size 885680 +oid sha256:88faa153e5c574df247e46030e698f795afdcc8933cd39e6c7be1e38f9734408 +size 885944 diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.go index 0ca8e55ad..95466e64d 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.go @@ -171,10 +171,11 @@ type bpf_tpTopicT struct { } type bpf_tpTpInfoPidT struct { - Tp bpf_tpTpInfoT - Pid uint32 - Valid uint8 - _ [3]byte + Tp bpf_tpTpInfoT + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_tpTpInfoT struct { @@ -186,6 +187,11 @@ type bpf_tpTpInfoT struct { _ [7]byte } +type bpf_tpTraceMapKeyT struct { + Conn bpf_tpConnectionInfoT + Type uint32 +} + // loadBpf_tp returns the embedded CollectionSpec for bpf_tp. func loadBpf_tp() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_tpBytes) diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.o index 93e2b2d79..557b8a77d 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2767655e494656042bb6a0f5b335d82ebd1fb08c62d61e53c002f4fcece2867b -size 427872 +oid sha256:24f2a99087364cd54eff3b596050e44e11483b1e56e053656b3bbf8c6b8127a0 +size 428128 diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.go index f477747aa..307648cae 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.go @@ -171,10 +171,11 @@ type bpf_tp_debugTopicT struct { } type bpf_tp_debugTpInfoPidT struct { - Tp bpf_tp_debugTpInfoT - Pid uint32 - Valid uint8 - _ [3]byte + Tp bpf_tp_debugTpInfoT + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_tp_debugTpInfoT struct { @@ -186,6 +187,11 @@ type bpf_tp_debugTpInfoT struct { _ [7]byte } +type bpf_tp_debugTraceMapKeyT struct { + Conn bpf_tp_debugConnectionInfoT + Type uint32 +} + // loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. func loadBpf_tp_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_tp_debugBytes) diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.o index bba6c6e1f..fdae2dc88 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a8fdee2799b08cdb3def4d811cd3281efb963a64a97efab45c783bba6b3116c -size 984248 +oid sha256:f9e06265710208a910cbe72c2f401379b4aa7254b2b95270ea90f3b5f09c06c6 +size 984512 diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.go index 9d2d99cec..d763497a5 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.go @@ -171,10 +171,11 @@ type bpf_tp_debugTopicT struct { } type bpf_tp_debugTpInfoPidT struct { - Tp bpf_tp_debugTpInfoT - Pid uint32 - Valid uint8 - _ [3]byte + Tp bpf_tp_debugTpInfoT + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_tp_debugTpInfoT struct { @@ -186,6 +187,11 @@ type bpf_tp_debugTpInfoT struct { _ [7]byte } +type bpf_tp_debugTraceMapKeyT struct { + Conn bpf_tp_debugConnectionInfoT + Type uint32 +} + // loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. func loadBpf_tp_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_tp_debugBytes) diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.o index ded2ff625..5a232b4fd 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e985ed6c99acf230309893e8c5b7970c48d28acee6cfe30687393a1dd83fa43 -size 986040 +oid sha256:87ea917661b0d145823382b64c14305c31e26edcad83919c09f0dea4fd81e665 +size 986304 diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.go index e4e1443cd..25997bc3b 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.go @@ -171,10 +171,11 @@ type bpf_tpTopicT struct { } type bpf_tpTpInfoPidT struct { - Tp bpf_tpTpInfoT - Pid uint32 - Valid uint8 - _ [3]byte + Tp bpf_tpTpInfoT + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_tpTpInfoT struct { @@ -186,6 +187,11 @@ type bpf_tpTpInfoT struct { _ [7]byte } +type bpf_tpTraceMapKeyT struct { + Conn bpf_tpConnectionInfoT + Type uint32 +} + // loadBpf_tp returns the embedded CollectionSpec for bpf_tp. func loadBpf_tp() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_tpBytes) diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.o index 98cde2370..e61be0470 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:02e3ef0adbe8a489ad236fb8e3d4b103cadd67f97ec52cd547691413aa487adc -size 429632 +oid sha256:2bf6c526ed0ac2a05318014ea6b8d667467bedc2d2618618560bf13ce375e4bc +size 429888 diff --git a/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.go index c26c864d4..0d20255a3 100644 --- a/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.go @@ -159,10 +159,11 @@ type bpfTopicT struct { } type bpfTpInfoPidT struct { - Tp bpfTpInfoT - Pid uint32 - Valid uint8 - _ [3]byte + Tp bpfTpInfoT + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpfTpInfoT struct { @@ -174,6 +175,11 @@ type bpfTpInfoT struct { _ [7]byte } +type bpfTraceMapKeyT struct { + Conn bpfConnectionInfoT + Type uint32 +} + // loadBpf returns the embedded CollectionSpec for bpf. func loadBpf() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_BpfBytes) diff --git a/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.o index 74915f551..762176151 100644 --- a/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cad7a4ba19d684c65b254551d770eaaa115a465f35c5c5413cec4d011baf4291 -size 382584 +oid sha256:4ff91fb4ed1b14ab8b6fd56335d45e3662316024dccb26f7d3d601be908b87d6 +size 382832 diff --git a/pkg/internal/ebpf/httptracer/bpf_arm64_bpfel.go b/pkg/internal/ebpf/httptracer/bpf_arm64_bpfel.go index d05b4a32b..798a7108d 100644 --- a/pkg/internal/ebpf/httptracer/bpf_arm64_bpfel.go +++ b/pkg/internal/ebpf/httptracer/bpf_arm64_bpfel.go @@ -51,9 +51,15 @@ type bpfTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte +} + +type bpfTraceMapKeyT struct { + Conn bpfConnectionInfoT + Type uint32 } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/httptracer/bpf_arm64_bpfel.o b/pkg/internal/ebpf/httptracer/bpf_arm64_bpfel.o index fcad8487b..e4d7f1783 100644 --- a/pkg/internal/ebpf/httptracer/bpf_arm64_bpfel.o +++ b/pkg/internal/ebpf/httptracer/bpf_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0aed50f8a73c6152bc9a00d4d5108de3d9de07dde2cdba6bee4449cd6675b6cd -size 42872 +oid sha256:531109a911d19d42d1466d7b77f03898480fbcf7c90c9ca406fa11d9551c09b7 +size 42984 diff --git a/pkg/internal/ebpf/httptracer/bpf_debug_arm64_bpfel.go b/pkg/internal/ebpf/httptracer/bpf_debug_arm64_bpfel.go index 089b95fe7..586554922 100644 --- a/pkg/internal/ebpf/httptracer/bpf_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/httptracer/bpf_debug_arm64_bpfel.go @@ -51,9 +51,15 @@ type bpf_debugTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte +} + +type bpf_debugTraceMapKeyT struct { + Conn bpf_debugConnectionInfoT + Type uint32 } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/httptracer/bpf_debug_arm64_bpfel.o b/pkg/internal/ebpf/httptracer/bpf_debug_arm64_bpfel.o index 5673378f2..b581585c0 100644 --- a/pkg/internal/ebpf/httptracer/bpf_debug_arm64_bpfel.o +++ b/pkg/internal/ebpf/httptracer/bpf_debug_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:facde3bae441088f2dfd58147595392624d9c65cb619bf84fb83d5c28e533ca5 -size 43112 +oid sha256:2f349266f8b0a5877954d37b97849a20c04c92ed6147389765b4ab04c24150eb +size 43232 diff --git a/pkg/internal/ebpf/httptracer/bpf_debug_x86_bpfel.go b/pkg/internal/ebpf/httptracer/bpf_debug_x86_bpfel.go index 538fc50ca..af1f2ee53 100644 --- a/pkg/internal/ebpf/httptracer/bpf_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/httptracer/bpf_debug_x86_bpfel.go @@ -51,9 +51,15 @@ type bpf_debugTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte +} + +type bpf_debugTraceMapKeyT struct { + Conn bpf_debugConnectionInfoT + Type uint32 } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/httptracer/bpf_debug_x86_bpfel.o b/pkg/internal/ebpf/httptracer/bpf_debug_x86_bpfel.o index f4eb69b82..b05fee8fa 100644 --- a/pkg/internal/ebpf/httptracer/bpf_debug_x86_bpfel.o +++ b/pkg/internal/ebpf/httptracer/bpf_debug_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc461947e3b312b962beb4aa8d92ea325a2f313d1268484866e8752e3b6def0b -size 43000 +oid sha256:dca31fa9a85115331b30b1587d9a1ffd20da5fef126f378ec33beb79d0b06d9b +size 43112 diff --git a/pkg/internal/ebpf/httptracer/bpf_x86_bpfel.go b/pkg/internal/ebpf/httptracer/bpf_x86_bpfel.go index 0461f36c3..e1189f47a 100644 --- a/pkg/internal/ebpf/httptracer/bpf_x86_bpfel.go +++ b/pkg/internal/ebpf/httptracer/bpf_x86_bpfel.go @@ -51,9 +51,15 @@ type bpfTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte +} + +type bpfTraceMapKeyT struct { + Conn bpfConnectionInfoT + Type uint32 } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/httptracer/bpf_x86_bpfel.o b/pkg/internal/ebpf/httptracer/bpf_x86_bpfel.o index e19c67211..0e54455b2 100644 --- a/pkg/internal/ebpf/httptracer/bpf_x86_bpfel.o +++ b/pkg/internal/ebpf/httptracer/bpf_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbc5f7d559cda9471e514afd89a22555bfa453bc6981ae393364df38ee349a1d -size 42760 +oid sha256:244013c7a102f7bab54bed3203fa517b44464b043d41450d6e36e590cd78442d +size 42872 diff --git a/pkg/internal/ebpf/tctracer/bpf_arm64_bpfel.go b/pkg/internal/ebpf/tctracer/bpf_arm64_bpfel.go index b98794077..26e63738e 100644 --- a/pkg/internal/ebpf/tctracer/bpf_arm64_bpfel.go +++ b/pkg/internal/ebpf/tctracer/bpf_arm64_bpfel.go @@ -199,9 +199,10 @@ type bpfTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpfTraceKeyT struct { @@ -209,6 +210,11 @@ type bpfTraceKeyT struct { ExtraId uint64 } +type bpfTraceMapKeyT struct { + Conn bpfConnectionInfoT + Type uint32 +} + // loadBpf returns the embedded CollectionSpec for bpf. func loadBpf() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_BpfBytes) diff --git a/pkg/internal/ebpf/tctracer/bpf_arm64_bpfel.o b/pkg/internal/ebpf/tctracer/bpf_arm64_bpfel.o index c018e90f6..aa50b8f8a 100644 --- a/pkg/internal/ebpf/tctracer/bpf_arm64_bpfel.o +++ b/pkg/internal/ebpf/tctracer/bpf_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3a10a0d94a52394c8f87c66d531d1d2066b67d459ce14e611f00851d0fdaf719 -size 196272 +oid sha256:aabc72d22ca308a83838d368077ca0e16b2d87305bb5927b5caa8fdb204b1dd7 +size 206576 diff --git a/pkg/internal/ebpf/tctracer/bpf_debug_arm64_bpfel.go b/pkg/internal/ebpf/tctracer/bpf_debug_arm64_bpfel.go index a2900ffca..d1ea90789 100644 --- a/pkg/internal/ebpf/tctracer/bpf_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/tctracer/bpf_debug_arm64_bpfel.go @@ -199,9 +199,10 @@ type bpf_debugTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_debugTraceKeyT struct { @@ -209,6 +210,11 @@ type bpf_debugTraceKeyT struct { ExtraId uint64 } +type bpf_debugTraceMapKeyT struct { + Conn bpf_debugConnectionInfoT + Type uint32 +} + // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. func loadBpf_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_debugBytes) diff --git a/pkg/internal/ebpf/tctracer/bpf_debug_arm64_bpfel.o b/pkg/internal/ebpf/tctracer/bpf_debug_arm64_bpfel.o index c97170210..b336ba7fc 100644 --- a/pkg/internal/ebpf/tctracer/bpf_debug_arm64_bpfel.o +++ b/pkg/internal/ebpf/tctracer/bpf_debug_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71f4c902cdfbff09b16230c7d727590462c20b056533176b4bfd54d87bbbe63f -size 339464 +oid sha256:cf95ae239cf48cc25890ca6962aeb60dd3f4f159a967e2a0ba719079d6188638 +size 380088 diff --git a/pkg/internal/ebpf/tctracer/bpf_debug_x86_bpfel.go b/pkg/internal/ebpf/tctracer/bpf_debug_x86_bpfel.go index 9ebc167f3..e3325a12b 100644 --- a/pkg/internal/ebpf/tctracer/bpf_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/tctracer/bpf_debug_x86_bpfel.go @@ -199,9 +199,10 @@ type bpf_debugTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpf_debugTraceKeyT struct { @@ -209,6 +210,11 @@ type bpf_debugTraceKeyT struct { ExtraId uint64 } +type bpf_debugTraceMapKeyT struct { + Conn bpf_debugConnectionInfoT + Type uint32 +} + // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. func loadBpf_debug() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_Bpf_debugBytes) diff --git a/pkg/internal/ebpf/tctracer/bpf_debug_x86_bpfel.o b/pkg/internal/ebpf/tctracer/bpf_debug_x86_bpfel.o index 31ff269c4..4ee60de35 100644 --- a/pkg/internal/ebpf/tctracer/bpf_debug_x86_bpfel.o +++ b/pkg/internal/ebpf/tctracer/bpf_debug_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08f2a65445f7f5323e54dc62e05d9f253c326b833c2fa23fa8daa5204847dca2 -size 340768 +oid sha256:0bcaf86afec020451e83116937754d4e71c6f9c3d018375744f257fa112b5fec +size 381400 diff --git a/pkg/internal/ebpf/tctracer/bpf_x86_bpfel.go b/pkg/internal/ebpf/tctracer/bpf_x86_bpfel.go index 83cccce57..f5681ed8b 100644 --- a/pkg/internal/ebpf/tctracer/bpf_x86_bpfel.go +++ b/pkg/internal/ebpf/tctracer/bpf_x86_bpfel.go @@ -199,9 +199,10 @@ type bpfTpInfoPidT struct { Flags uint8 _ [7]byte } - Pid uint32 - Valid uint8 - _ [3]byte + Pid uint32 + Valid uint8 + ReqType uint8 + _ [2]byte } type bpfTraceKeyT struct { @@ -209,6 +210,11 @@ type bpfTraceKeyT struct { ExtraId uint64 } +type bpfTraceMapKeyT struct { + Conn bpfConnectionInfoT + Type uint32 +} + // loadBpf returns the embedded CollectionSpec for bpf. func loadBpf() (*ebpf.CollectionSpec, error) { reader := bytes.NewReader(_BpfBytes) diff --git a/pkg/internal/ebpf/tctracer/bpf_x86_bpfel.o b/pkg/internal/ebpf/tctracer/bpf_x86_bpfel.o index e23033b77..a52311403 100644 --- a/pkg/internal/ebpf/tctracer/bpf_x86_bpfel.o +++ b/pkg/internal/ebpf/tctracer/bpf_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:54e45d8d38195633a89be7cd688f2f8b547c0586ec345b998cb95cf8304d31da -size 197576 +oid sha256:930ca57b724e22d85cafe1f7df0e6aaa649a44dd9f5f6bdd291cd85f90e98b64 +size 207888 diff --git a/test/integration/components/javakafka/src/main/java/Kafka.java b/test/integration/components/javakafka/src/main/java/Kafka.java index 47d74d1d6..5ebcf741d 100644 --- a/test/integration/components/javakafka/src/main/java/Kafka.java +++ b/test/integration/components/javakafka/src/main/java/Kafka.java @@ -30,11 +30,13 @@ public static void main(String[] args) { Thread producerThread = new Thread(() -> { KafkaProducer producer = new KafkaProducer<>(producerProps); - for (int i = 0; i < 100; i++) { - producer.send(new ProducerRecord<>("my-topic", "key", "value" + i)); - System.out.println("Produced message: " + "value" + i); + for (;;) { + producer.send(new ProducerRecord<>("my-topic", "key", "value")); + System.out.println("Produced message"); + try { + Thread.sleep(500); + } catch (Exception ignore) {} } - producer.close(); }); // Consumer diff --git a/test/integration/components/php/index.php b/test/integration/components/php/index.php new file mode 100644 index 000000000..d6884632b --- /dev/null +++ b/test/integration/components/php/index.php @@ -0,0 +1,9 @@ + diff --git a/test/integration/components/php/nginx.conf b/test/integration/components/php/nginx.conf new file mode 100644 index 000000000..efd12203c --- /dev/null +++ b/test/integration/components/php/nginx.conf @@ -0,0 +1,35 @@ +worker_processes 1; +events { worker_connections 1024; } #total number of connections nginx can handle concurrently + +http { + sendfile on; +# fastcgi_read_timeout 4s; #kills the connection (http request) if php-fpm takes more than 1s to handle it (return a response) + + server { + listen 80 default_server; + root /var/www/html; + server_name _; + + location / { + fastcgi_pass php-fpm:9000; + # fastcgi_pass unix:/run/php-fpm/www.sock + include fastcgi_params; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + } + + location /status { + access_log off; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + fastcgi_pass php-fpm:9000; + } + + location /stub_status { + stub_status on; + access_log off; + } + } +} + diff --git a/test/integration/components/php/php-fpm.conf b/test/integration/components/php/php-fpm.conf new file mode 100644 index 000000000..bc2275012 --- /dev/null +++ b/test/integration/components/php/php-fpm.conf @@ -0,0 +1,15 @@ +[www] +listen = /var/run/php-fpm.sock +user = www-data +group = www-data +pm = ${PM_STRATEGY} +pm.max_children = ${PM_MAX_CHILDREN} +pm.max_requests = ${PM_MAX_REQUESTS} +request_terminate_timeout = ${PM_REQUEST_TERMINATE_TIMEOUT} +php_value[memory_limit] = ${PM_CHILDREN_MEMORY_LIMIT} +pm.start_servers = ${PM_START_SERVERS} +pm.min_spare_servers = ${PM_MIN_SPARE_SERVERS} +pm.max_spare_servers = ${PM_MAX_SPARE_SERVERS} +pm.process_idle_timeout = ${PM_PROCESS_IDLE_TIMEOUT} +pm.status_path = /status +ping.path = /ping diff --git a/test/integration/components/php/php.ini b/test/integration/components/php/php.ini new file mode 100644 index 000000000..11bb070a8 --- /dev/null +++ b/test/integration/components/php/php.ini @@ -0,0 +1,18 @@ +; Maximum execution time of each script, in seconds +max_execution_time = 30 + +; Maximum amount of memory a script may consume, in megabytes +memory_limit = 256M + +; Path to a temporary directory for storing uploaded files +upload_tmp_dir = /tmp + +; Whether or not to display errors on the screen +display_errors = On + +; Error reporting level +error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT + +; Default timezone +date.timezone = "America/New_York" + diff --git a/test/integration/configs/instrumenter-config-php.yml b/test/integration/configs/instrumenter-config-php.yml new file mode 100644 index 000000000..e1d443179 --- /dev/null +++ b/test/integration/configs/instrumenter-config-php.yml @@ -0,0 +1,4 @@ +otel_metrics_export: + endpoint: http://127.0.0.1:4018 +otel_traces_export: + endpoint: http://127.0.0.1:4318 \ No newline at end of file diff --git a/test/integration/docker-compose-php-fpm.yml b/test/integration/docker-compose-php-fpm.yml new file mode 100644 index 000000000..ff11290df --- /dev/null +++ b/test/integration/docker-compose-php-fpm.yml @@ -0,0 +1,118 @@ +version: '3.8' + +services: + nginx: + image: nginx:latest + mem_limit: 128m + container_name: hatest-nginx + ports: + - "8080:80" + volumes: + - ./components/php/nginx.conf:/etc/nginx/nginx.conf + - nginx_socket:/var/run/ + depends_on: + - php-fpm + + php-fpm: + image: php:fpm + mem_limit: 512m + container_name: hatest-php-fpm + volumes: + - ./components/php/php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf + - ./components/php/php.ini:/usr/local/etc/php/php.ini + - ./components/php/:/var/www/html + - php_socket:/var/run/ + environment: + PM_STRATEGY: static + PM_MAX_CHILDREN: 100 + PM_MAX_REQUESTS: 500 + PM_REQUEST_TERMINATE_TIMEOUT: 5s + PHP_MEM_USED_IN_MB: 1 + PHP_EXECUTION_TIME_IN_SECONDS: 1 + PM_CHILDREN_MEMORY_LIMIT: 50M + PM_START_SERVERS: 10 + PM_MIN_SPARE_SERVERS: 5 + PM_MAX_SPARE_SERVERS: 20 + PM_PROCESS_IDLE_TIMEOUT: 10s + + autoinstrumenter: + build: + context: ../.. + dockerfile: ./test/integration/components/beyla/Dockerfile + command: + - --config=/configs/instrumenter-config-php.yml + volumes: + - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security + - ../../testoutput:/coverage + - ../../testoutput/run-php:/var/run/beyla + image: hatest-javaautoinstrumenter + privileged: true # in some environments (not GH Pull Requests) you can set it to false and then cap_add: [ SYS_ADMIN ] + network_mode: "host" + pid: "host" + environment: + GOCOVERDIR: "/coverage" + BEYLA_TRACE_PRINTER: "text" + BEYLA_EXECUTABLE_NAME: "nginx|php-fpm" + BEYLA_SERVICE_NAMESPACE: "integration-test" + BEYLA_METRICS_INTERVAL: "10ms" + BEYLA_BPF_BATCH_TIMEOUT: "10ms" + BEYLA_LOG_LEVEL: "DEBUG" + BEYLA_BPF_DEBUG: "TRUE" + BEYLA_METRICS_REPORT_TARGET: "true" + BEYLA_METRICS_REPORT_PEER: "true" + BEYLA_HOSTNAME: "beyla" + depends_on: + nginx: + condition: service_started + + # OpenTelemetry Collector + otelcol: + image: otel/opentelemetry-collector-contrib:0.104.0 + container_name: otel-col + deploy: + resources: + limits: + memory: 125M + restart: unless-stopped + command: [ "--config=/etc/otelcol-config/otelcol-config-4017.yml" ] + volumes: + - ./configs/:/etc/otelcol-config + ports: + - "4017" # OTLP over gRPC receiver + - "4018:4018" # OTLP over HTTP receiver + - "9464" # Prometheus exporter + - "8888" # metrics endpoint + depends_on: + prometheus: + condition: service_started + + # Prometheus + prometheus: + image: quay.io/prometheus/prometheus:v2.53.0 + container_name: prometheus + command: + - --storage.tsdb.retention.time=1m + - --config.file=/etc/prometheus/prometheus-config.yml + - --storage.tsdb.path=/prometheus + - --web.enable-lifecycle + - --web.route-prefix=/ + - --log.level=debug + volumes: + - ./configs/:/etc/prometheus + ports: + - "9090:9090" + + jaeger: + image: jaegertracing/all-in-one:1.57 + ports: + - "16686:16686" # Query frontend + - "4317:4317" # OTEL GRPC traces collector + - "4318:4318" # OTEL HTTP traces collector + environment: + - COLLECTOR_OTLP_ENABLED=true + - LOG_LEVEL=debug + +volumes: + nginx_socket: + php_socket: diff --git a/test/integration/php_fm_test.go b/test/integration/php_fm_test.go new file mode 100644 index 000000000..e1c89c5b9 --- /dev/null +++ b/test/integration/php_fm_test.go @@ -0,0 +1,115 @@ +//go:build integration + +package integration + +import ( + "fmt" + "path" + "testing" + + "github.com/mariomac/guara/pkg/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/grafana/beyla/test/integration/components/docker" + "github.com/grafana/beyla/test/integration/components/prom" +) + +// does a smoke test to verify that all the components that started +// asynchronously for the Elixir test are up and communicating properly +func waitForPHPTestComponents(t *testing.T, url string) { + waitForTestComponentsSub(t, url, "/status") +} + +func testREDMetricsForPHPHTTPLibrary(t *testing.T, url string, nginx, php string) { + path := "/ping" + + pq := prom.Client{HostPort: prometheusHostPort} + var results []prom.Result + + // Call 4 times the instrumented service, forcing it to: + // - process multiple calls in a row with, one more than we might need + // - returning a 200 code + for i := 0; i < 4; i++ { + doHTTPGet(t, fmt.Sprintf("%s%s", url, path), 200) + } + + // Eventually, Prometheus would make this query visible + test.Eventually(t, testTimeout, func(t require.TestingT) { + var err error + results, err = pq.Query(`http_server_request_duration_seconds_count{` + + `http_request_method="GET",` + + `http_response_status_code="200",` + + `service_namespace="integration-test",` + + `service_name="` + nginx + `",` + + `http_route="/ping"}`) + require.NoError(t, err) + enoughPromResults(t, results) + val := totalPromCount(t, results) + assert.LessOrEqual(t, 3, val) + if len(results) > 0 { + res := results[0] + addr := res.Metric["client_address"] + assert.NotNil(t, addr) + } + }) + test.Eventually(t, testTimeout, func(t require.TestingT) { + var err error + results, err = pq.Query(`http_server_request_duration_seconds_count{` + + `http_request_method="GET",` + + `http_response_status_code="200",` + + `service_namespace="integration-test",` + + `service_name="` + php + `",` + + `http_route="/ping"}`) + require.NoError(t, err) + enoughPromResults(t, results) + val := totalPromCount(t, results) + assert.LessOrEqual(t, 3, val) + if len(results) > 0 { + res := results[0] + addr := res.Metric["client_address"] + assert.NotNil(t, addr) + } + }) + test.Eventually(t, testTimeout, func(t require.TestingT) { + var err error + results, err = pq.Query(`http_client_request_duration_seconds_count{` + + `http_request_method="GET",` + + `http_response_status_code="200",` + + `service_namespace="integration-test",` + + `service_name="` + nginx + `",` + + `http_route="/ping"}`) + require.NoError(t, err) + enoughPromResults(t, results) + val := totalPromCount(t, results) + assert.LessOrEqual(t, 3, val) + if len(results) > 0 { + res := results[0] + addr := res.Metric["client_address"] + assert.NotNil(t, addr) + } + }) +} + +func testREDMetricsPHPFPM(t *testing.T) { + for _, testCaseURL := range []string{ + "http://localhost:8080", + } { + t.Run(testCaseURL, func(t *testing.T) { + waitForPHPTestComponents(t, testCaseURL) + testREDMetricsForPHPHTTPLibrary(t, testCaseURL, "nginx", "php-fpm") + }) + } +} + +func TestPHPFM(t *testing.T) { + compose, err := docker.ComposeSuite("docker-compose-php-fpm.yml", path.Join(pathOutput, "test-suite-php-fpm.log")) + // we are going to setup discovery directly in the configuration file + compose.Env = append(compose.Env, `BEYLA_EXECUTABLE_NAME=`, `BEYLA_OPEN_PORT=`) + require.NoError(t, err) + require.NoError(t, compose.Up()) + + t.Run("PHP-FM RED metrics", testREDMetricsPHPFPM) + + require.NoError(t, compose.Close()) +}