socket_trace_common.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #ifndef DF_BPF_SOCKET_TRACE_COMMON_H
  2. #define DF_BPF_SOCKET_TRACE_COMMON_H
  3. #define CAP_DATA_SIZE 1024 // For no-brust send buffer
  4. #define BURST_DATA_BUF_SIZE 8192 // For brust send buffer
  5. enum endpoint_role {
  6. ROLE_UNKNOWN,
  7. ROLE_CLIENT,
  8. ROLE_SERVER
  9. };
  10. struct __tuple_t {
  11. __u8 daddr[16];
  12. __u8 rcv_saddr[16];
  13. __u8 addr_len;
  14. __u8 l4_protocol;
  15. __u16 dport;
  16. __u16 num;
  17. };
  18. struct __socket_data {
  19. /* 进程/线程信息 */
  20. __u32 pid; // 表示线程号 如果'pid == tgid'表示一个进程, 否则是线程
  21. __u32 tgid; // 进程号
  22. __u64 coroutine_id; // CoroutineID, i.e., golang goroutine id
  23. __u8 source; // SYSCALL,GO_TLS_UPROBE,GO_HTTP2_UPROBE
  24. __u8 comm[TASK_COMM_LEN]; // 进程或线程名
  25. /* 连接(socket)信息 */
  26. __u64 socket_id; /* 通信socket唯一ID, 从启动时的时钟开始自增1 */
  27. struct __tuple_t tuple;
  28. /*
  29. * 携带数据, 比如:MySQL第一次读取的数据,被第二次读取的数据携带一并发给用户
  30. * 注意携带数据只有4字节大小。
  31. */
  32. __u32 extra_data;
  33. __u32 extra_data_count;
  34. /* 追踪信息 */
  35. __u32 tcp_seq;
  36. __u64 thread_trace_id;
  37. /* 追踪数据信息 */
  38. __u64 timestamp; // 数据捕获时间戳
  39. __u8 direction: 1; // bits[0]: 方向,值为T_EGRESS(0), T_INGRESS(1)
  40. __u8 msg_type: 7; // bits[1-7]: 信息类型,值为MSG_UNKNOWN(0), MSG_REQUEST(1), MSG_RESPONSE(2)
  41. __u64 syscall_len; // 本次系统调用读、写数据的总长度
  42. __u64 data_seq; // cap_data在Socket中的相对顺序号
  43. __u16 data_type; // HTTP, DNS, MySQL
  44. __u16 data_len; // 数据长度
  45. char data[BURST_DATA_BUF_SIZE];
  46. } __attribute__((packed));
  47. /*
  48. * 整个结构大小为2^15(强制为2的次幂),目的是用(2^n - 1)与数据
  49. * 长度作位与操作使eBPF程序进行安全的bpf_perf_event_output()操作。
  50. */
  51. struct __socket_data_buffer {
  52. __u32 events_num;
  53. __u32 len; // data部分长度
  54. char data[32760]; // 32760 + len(4bytes) + events_num(4bytes) = 2^15 = 32768
  55. };
  56. struct trace_conf_t {
  57. __u64 socket_id; // 会话标识
  58. __u64 coroutine_trace_id; // 同一协程的数据转发关联
  59. __u64 thread_trace_id; // 同一进程/线程的数据转发关联,用于多事务流转场景
  60. __u64 data_limit_max; // Maximum number of data transfers
  61. __u64 go_tracing_timeout;
  62. __u64 io_event_collect_mode;
  63. __u64 io_event_minimal_duration;
  64. unsigned char host_id[APM_HOST_ID_SIZE];
  65. unsigned char app_id[APM_APP_ID_SIZE];
  66. };
  67. struct trace_stats {
  68. __u64 socket_map_count; // 对socket 链接表进行统计
  69. __u64 trace_map_count; // 对同一进程/线程的多次转发表进行统计
  70. };
  71. struct socket_info_t {
  72. __u64 l7_proto;
  73. /*
  74. * The serial number of the socket read and write data, used to
  75. * correct out-of-sequence.
  76. *
  77. * socket读写数据的序列号,用于纠正数据乱序。
  78. */
  79. volatile __u64 seq;
  80. /*
  81. * mysql, kafka这种类型在读取数据时,先读取4字节
  82. * 然后再读取剩下的数据,这里用于对预先读取的数据存储
  83. * 用于后续的协议分析。
  84. */
  85. __u8 prev_data[4];
  86. __u8 direction: 1;
  87. __u8 msg_type: 2; // 保存数据类型,值为MSG_UNKNOWN(0), MSG_REQUEST(1), MSG_RESPONSE(2)
  88. __u8 role: 5; // 标识socket角色:ROLE_CLIENT, ROLE_SERVER, ROLE_UNKNOWN
  89. bool need_reconfirm; // l7协议推断是否需要再次确认。
  90. __s32 correlation_id; // 目前用于kafka协议推断。
  91. __u32 peer_fd; // 用于记录socket间数据转移的对端fd。
  92. /*
  93. * 一旦有数据读/写就会更新这个时间,这个时间是从系统开机开始
  94. * 到更新时的间隔时间单位是秒。
  95. */
  96. __u32 update_time;
  97. __u32 prev_data_len;
  98. __u64 trace_id;
  99. __u64 uid; // socket唯一标识ID
  100. } __attribute__((packed));
  101. struct trace_key_t {
  102. __u32 tgid;
  103. __u32 pid;
  104. __u64 goid;
  105. } __attribute__((packed));
  106. struct trace_info_t {
  107. /*
  108. * Whether traceID is zero ?
  109. * For the client to actively send request, set traceID to zero.
  110. */
  111. bool is_trace_id_zero;
  112. __u32 update_time; // 从系统开机开始到创建/更新时的间隔时间单位是秒
  113. __u32 peer_fd; // 用于socket之间的关联
  114. __u64 thread_trace_id; // 线程追踪ID
  115. __u64 socket_id; // Records the socket associated when tracing was created (记录创建追踪时关联的socket)
  116. } __attribute__((packed));
  117. struct allow_port_bitmap {
  118. __u8 bitmap[65536 / 8];
  119. } __attribute__((packed));
  120. struct __io_event_buffer {
  121. __u32 bytes_count;
  122. // 0: write
  123. // 1: read
  124. __u32 operation;
  125. // nanosecond
  126. __u64 latency;
  127. // strings terminated with \0
  128. char filename[64];
  129. } __attribute__((packed));
  130. #define is_set_bitmap(bitmap, idx) (bitmap[(idx) / 8] & (1 << ((idx) % 8)))
  131. // struct ebpf_proc_info -> offsets[] arrays index.
  132. enum offsets_index {
  133. OFFSET_IDX_GOID_RUNTIME_G,
  134. OFFSET_IDX_CONN_TLS_CONN,
  135. OFFSET_IDX_SYSFD_POLL_FD,
  136. OFFSET_IDX_CONN_HTTP2_SERVER_CONN,
  137. OFFSET_IDX_TCONN_HTTP2_CLIENT_CONN,
  138. OFFSET_IDX_CC_HTTP2_CLIENT_CONN_READ_LOOP,
  139. OFFSET_IDX_CONN_GRPC_HTTP2_CLIENT,
  140. OFFSET_IDX_CONN_GRPC_HTTP2_SERVER,
  141. OFFSET_IDX_FRAMER_GRPC_TRANSPORT_LOOPY_WRITER,
  142. OFFSET_IDX_WRITER_GRPC_TRANSPORT_FRAMER,
  143. OFFSET_IDX_CONN_GRPC_TRANSPORT_BUFWRITER,
  144. OFFSET_IDX_SIDE_GRPC_TRANSPORT_LOOPY_WRITER,
  145. OFFSET_IDX_FIELDS_HTTP2_META_HEADERS_FRAME,
  146. OFFSET_IDX_STREAM_HTTP2_CLIENT_CONN,
  147. OFFSET_IDX_STREAM_ID_HTTP2_FRAME_HEADER,
  148. OFFSET_IDX_MAX,
  149. };
  150. // Store the ebpf_proc_info to eBPF Map.
  151. struct ebpf_proc_info {
  152. __u32 version;
  153. __u16 offsets[OFFSET_IDX_MAX];
  154. // In golang, itab represents type, and in interface, struct is represented
  155. // by the address of itab. We use itab to judge the structure type, and
  156. // find the fd representing the connection after multiple jumps. These
  157. // types are not available in Go ELF files without a symbol table.
  158. // Go 用 itab 表示类型, 在 interface 中通过 itab 确定具体的 struct, 并根据
  159. // struct 找到表示连接的 fd.
  160. __u64 net_TCPConn_itab;
  161. __u64 crypto_tls_Conn_itab; // TLS_HTTP1,TLS_HTTP2
  162. __u64 credentials_syscallConn_itab; // gRPC
  163. // __u64 start_addr;
  164. // __u64 end_addr;
  165. unsigned char instance_id[APM_INSTANCE_ID_SIZE];
  166. } __attribute__((packed));
  167. enum {
  168. /*
  169. * 0 ~ 16 for L7 socket event (struct socket_data_buffer),
  170. * indicates the number of socket data in socket_data_buffer.
  171. */
  172. /*
  173. * For event registrion
  174. */
  175. EVENT_TYPE_MIN = 1 << 5,
  176. EVENT_TYPE_PROC_EXEC = 1 << 5,
  177. EVENT_TYPE_PROC_EXIT = 1 << 6
  178. // Add new event type here.
  179. };
  180. // Description Provides basic information about an event
  181. struct event_meta {
  182. __u32 event_type;
  183. };
  184. // Process execution or exit event data
  185. struct process_event_t {
  186. struct event_meta meta;
  187. __u32 pid; // process ID
  188. __u8 name[TASK_COMM_LEN]; // process name
  189. };
  190. #define GO_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
  191. #endif /* BPF_SOCKET_TRACE_COMMON */