| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- #ifndef DF_BPF_SOCKET_TRACE_COMMON_H
- #define DF_BPF_SOCKET_TRACE_COMMON_H
- #define CAP_DATA_SIZE 1024 // For no-brust send buffer
- #define BURST_DATA_BUF_SIZE 8192 // For brust send buffer
- enum endpoint_role {
- ROLE_UNKNOWN,
- ROLE_CLIENT,
- ROLE_SERVER
- };
- struct __tuple_t {
- __u8 daddr[16];
- __u8 rcv_saddr[16];
- __u8 addr_len;
- __u8 l4_protocol;
- __u16 dport;
- __u16 num;
- };
- struct __socket_data {
- /* 进程/线程信息 */
- __u32 pid; // 表示线程号 如果'pid == tgid'表示一个进程, 否则是线程
- __u32 tgid; // 进程号
- __u64 coroutine_id; // CoroutineID, i.e., golang goroutine id
- __u8 source; // SYSCALL,GO_TLS_UPROBE,GO_HTTP2_UPROBE
- __u8 comm[TASK_COMM_LEN]; // 进程或线程名
- /* 连接(socket)信息 */
- __u64 socket_id; /* 通信socket唯一ID, 从启动时的时钟开始自增1 */
- struct __tuple_t tuple;
- /*
- * 携带数据, 比如:MySQL第一次读取的数据,被第二次读取的数据携带一并发给用户
- * 注意携带数据只有4字节大小。
- */
- __u32 extra_data;
- __u32 extra_data_count;
- /* 追踪信息 */
- __u32 tcp_seq;
- __u64 thread_trace_id;
- /* 追踪数据信息 */
- __u64 timestamp; // 数据捕获时间戳
- __u8 direction: 1; // bits[0]: 方向,值为T_EGRESS(0), T_INGRESS(1)
- __u8 msg_type: 7; // bits[1-7]: 信息类型,值为MSG_UNKNOWN(0), MSG_REQUEST(1), MSG_RESPONSE(2)
- __u64 syscall_len; // 本次系统调用读、写数据的总长度
- __u64 data_seq; // cap_data在Socket中的相对顺序号
- __u16 data_type; // HTTP, DNS, MySQL
- __u16 data_len; // 数据长度
- char data[BURST_DATA_BUF_SIZE];
- } __attribute__((packed));
- /*
- * 整个结构大小为2^15(强制为2的次幂),目的是用(2^n - 1)与数据
- * 长度作位与操作使eBPF程序进行安全的bpf_perf_event_output()操作。
- */
- struct __socket_data_buffer {
- __u32 events_num;
- __u32 len; // data部分长度
- char data[32760]; // 32760 + len(4bytes) + events_num(4bytes) = 2^15 = 32768
- };
- struct trace_conf_t {
- __u64 socket_id; // 会话标识
- __u64 coroutine_trace_id; // 同一协程的数据转发关联
- __u64 thread_trace_id; // 同一进程/线程的数据转发关联,用于多事务流转场景
- __u64 data_limit_max; // Maximum number of data transfers
- __u64 go_tracing_timeout;
- __u64 io_event_collect_mode;
- __u64 io_event_minimal_duration;
- unsigned char host_id[APM_HOST_ID_SIZE];
- unsigned char app_id[APM_APP_ID_SIZE];
- };
- struct trace_stats {
- __u64 socket_map_count; // 对socket 链接表进行统计
- __u64 trace_map_count; // 对同一进程/线程的多次转发表进行统计
- };
- struct socket_info_t {
- __u64 l7_proto;
- /*
- * The serial number of the socket read and write data, used to
- * correct out-of-sequence.
- *
- * socket读写数据的序列号,用于纠正数据乱序。
- */
- volatile __u64 seq;
- /*
- * mysql, kafka这种类型在读取数据时,先读取4字节
- * 然后再读取剩下的数据,这里用于对预先读取的数据存储
- * 用于后续的协议分析。
- */
- __u8 prev_data[4];
- __u8 direction: 1;
- __u8 msg_type: 2; // 保存数据类型,值为MSG_UNKNOWN(0), MSG_REQUEST(1), MSG_RESPONSE(2)
- __u8 role: 5; // 标识socket角色:ROLE_CLIENT, ROLE_SERVER, ROLE_UNKNOWN
- bool need_reconfirm; // l7协议推断是否需要再次确认。
- __s32 correlation_id; // 目前用于kafka协议推断。
- __u32 peer_fd; // 用于记录socket间数据转移的对端fd。
- /*
- * 一旦有数据读/写就会更新这个时间,这个时间是从系统开机开始
- * 到更新时的间隔时间单位是秒。
- */
- __u32 update_time;
- __u32 prev_data_len;
- __u64 trace_id;
- __u64 uid; // socket唯一标识ID
- } __attribute__((packed));
- struct trace_key_t {
- __u32 tgid;
- __u32 pid;
- __u64 goid;
- } __attribute__((packed));
- struct trace_info_t {
- /*
- * Whether traceID is zero ?
- * For the client to actively send request, set traceID to zero.
- */
- bool is_trace_id_zero;
- __u32 update_time; // 从系统开机开始到创建/更新时的间隔时间单位是秒
- __u32 peer_fd; // 用于socket之间的关联
- __u64 thread_trace_id; // 线程追踪ID
- __u64 socket_id; // Records the socket associated when tracing was created (记录创建追踪时关联的socket)
- } __attribute__((packed));
- struct allow_port_bitmap {
- __u8 bitmap[65536 / 8];
- } __attribute__((packed));
- struct __io_event_buffer {
- __u32 bytes_count;
- // 0: write
- // 1: read
- __u32 operation;
- // nanosecond
- __u64 latency;
- // strings terminated with \0
- char filename[64];
- } __attribute__((packed));
- #define is_set_bitmap(bitmap, idx) (bitmap[(idx) / 8] & (1 << ((idx) % 8)))
- // struct ebpf_proc_info -> offsets[] arrays index.
- enum offsets_index {
- OFFSET_IDX_GOID_RUNTIME_G,
- OFFSET_IDX_CONN_TLS_CONN,
- OFFSET_IDX_SYSFD_POLL_FD,
- OFFSET_IDX_CONN_HTTP2_SERVER_CONN,
- OFFSET_IDX_TCONN_HTTP2_CLIENT_CONN,
- OFFSET_IDX_CC_HTTP2_CLIENT_CONN_READ_LOOP,
- OFFSET_IDX_CONN_GRPC_HTTP2_CLIENT,
- OFFSET_IDX_CONN_GRPC_HTTP2_SERVER,
- OFFSET_IDX_FRAMER_GRPC_TRANSPORT_LOOPY_WRITER,
- OFFSET_IDX_WRITER_GRPC_TRANSPORT_FRAMER,
- OFFSET_IDX_CONN_GRPC_TRANSPORT_BUFWRITER,
- OFFSET_IDX_SIDE_GRPC_TRANSPORT_LOOPY_WRITER,
- OFFSET_IDX_FIELDS_HTTP2_META_HEADERS_FRAME,
- OFFSET_IDX_STREAM_HTTP2_CLIENT_CONN,
- OFFSET_IDX_STREAM_ID_HTTP2_FRAME_HEADER,
- OFFSET_IDX_MAX,
- };
- // Store the ebpf_proc_info to eBPF Map.
- struct ebpf_proc_info {
- __u32 version;
- __u16 offsets[OFFSET_IDX_MAX];
- // In golang, itab represents type, and in interface, struct is represented
- // by the address of itab. We use itab to judge the structure type, and
- // find the fd representing the connection after multiple jumps. These
- // types are not available in Go ELF files without a symbol table.
- // Go 用 itab 表示类型, 在 interface 中通过 itab 确定具体的 struct, 并根据
- // struct 找到表示连接的 fd.
- __u64 net_TCPConn_itab;
- __u64 crypto_tls_Conn_itab; // TLS_HTTP1,TLS_HTTP2
- __u64 credentials_syscallConn_itab; // gRPC
- // __u64 start_addr;
- // __u64 end_addr;
- unsigned char instance_id[APM_INSTANCE_ID_SIZE];
- } __attribute__((packed));
- enum {
- /*
- * 0 ~ 16 for L7 socket event (struct socket_data_buffer),
- * indicates the number of socket data in socket_data_buffer.
- */
- /*
- * For event registrion
- */
- EVENT_TYPE_MIN = 1 << 5,
- EVENT_TYPE_PROC_EXEC = 1 << 5,
- EVENT_TYPE_PROC_EXIT = 1 << 6
- // Add new event type here.
- };
- // Description Provides basic information about an event
- struct event_meta {
- __u32 event_type;
- };
- // Process execution or exit event data
- struct process_event_t {
- struct event_meta meta;
- __u32 pid; // process ID
- __u8 name[TASK_COMM_LEN]; // process name
- };
- #define GO_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
- #endif /* BPF_SOCKET_TRACE_COMMON */
|