diff --git a/agent/plugin/common.bpf.h b/agent/plugin/common.bpf.h index d516c776465524a205507d362dbdcd5776ee1f15..73558ea231e0731751939cbbecfd19d25f6df97a 100644 --- a/agent/plugin/common.bpf.h +++ b/agent/plugin/common.bpf.h @@ -47,6 +47,12 @@ struct __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } flags_rb SEC(".maps"); + +struct +{ + __uint(type, BPF_MAP_TYPE_RINGBUF); + __uint(max_entries, 256 * 1024); +} rate_rb SEC(".maps"); /*map helper*/ struct @@ -125,6 +131,15 @@ struct __type(value, u64); } fin_count_map SEC(".maps"); +struct +{ + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 65536); + __type(key, struct sock *); + __type(value, u64); +} tcp_rate_map SEC(".maps"); + +static int kprobe_select = 1, tcp_status_info = 1, fentry_select = 1, udp_info = 1, packet_count = 1, protocol_info = 1, tcp_output_info = 1; /*funcation hepler*/ static __always_inline int get_current_tgid() { @@ -164,10 +179,10 @@ static void get_tcp_pkt_tuple(void *pkt_tuple, struct iphdr *ip, struct tcphdr * if (type == 1) { // struct tuple_key struct tuple_key *key = (struct tuple_key *)pkt_tuple; - key->saddr = _R(ip, saddr); - key->daddr = _R(ip, daddr); - key->sport = __bpf_ntohs(_R(tcp, source)); - key->dport = __bpf_ntohs(_R(tcp, dest)); + key->skbap.saddr = _R(ip, saddr); + key->skbap.daddr = _R(ip, daddr); + key->skbap.sport = __bpf_ntohs(_R(tcp, source)); + key->skbap.dport = __bpf_ntohs(_R(tcp, dest)); } else if (type == 2) { // struct event @@ -180,21 +195,24 @@ static void get_tcp_pkt_tuple(void *pkt_tuple, struct iphdr *ip, struct tcphdr * event->ack = __bpf_ntohl(_R(tcp, ack_seq)); } } - static __always_inline void *bmloti(void *map, const void *key, const void *init) { void *val; long err; + val = bpf_map_lookup_elem(map, key); if (val) return val; - err = bpf_map_update_elem(map, key, init, - BPF_NOEXIST); - if (!err) - return 0; + + err = bpf_map_update_elem(map, key, init, BPF_NOEXIST); + if (err == 0) + { + return bpf_map_lookup_elem(map, key); + } return bpf_map_lookup_elem(map, key); } + static __always_inline char is_period_txrx(struct sock *sk) { struct sock_stats_s *sock_stats = bpf_map_lookup_elem(&tcp_link_map, &sk); @@ -207,9 +225,7 @@ static __always_inline char is_period_txrx(struct sock *sk) u64 current_time = NS_TIME(); u64 last_time = sock_stats->txrx_ts; u64 elapsed_time = current_time - last_time; - // bpf_printk("Current time: %llu, Last time: %llu, Elapsed time: %llu", current_time, last_time, elapsed_time); - if ((current_time > last_time) && (elapsed_time >= TIMEOUT_NS)) { sock_stats->txrx_ts = current_time; @@ -218,45 +234,28 @@ static __always_inline char is_period_txrx(struct sock *sk) return 0; } -static __always_inline void report_tx_rx(void *ctx, struct tcp_metrics_s *metrics, struct sock *sk) +static void get_tcp_tx_rx_segs(struct sock *sk, struct tcp_tx_rx *segs) { + struct tcp_sock *tcp_sk = (struct tcp_sock *)sk; + segs->segs_in = _R(tcp_sk, segs_in); + segs->segs_out = _R(tcp_sk, segs_out); +} - if (!is_period_txrx(sk)) - { - return; - } - - u32 last_time_segs_out = metrics->tx_rx_stats.segs_out; // save the number of last sent segments - u32 last_time_segs_in = metrics->tx_rx_stats.segs_in; // recieve segments - metrics->report_flags |= TCP_PROBE_TXRX; +static __always_inline void report_tx_rx(struct sock_stats_s *sock_stats, struct sock *sk) +{ + sock_stats->metrics.report_flags |= TCP_PROBE_TXRX; void *buf = bpf_ringbuf_reserve(&tcp_output_rb, sizeof(struct tcp_metrics_s), 0); if (!buf) { return; } - - __builtin_memcpy(buf, metrics, sizeof(struct tcp_metrics_s)); - metrics->report_flags &= ~TCP_PROBE_TXRX; - __builtin_memset(&(metrics->tx_rx_stats), 0x0, sizeof(metrics->tx_rx_stats)); - - metrics->tx_rx_stats.last_time_segs_in = last_time_segs_in; - metrics->tx_rx_stats.last_time_segs_out = last_time_segs_out; - // bpf_printk("=========Reporting TX/RX. Last segs_out: %u, Last segs_in: %u", metrics->tx_rx_stats.last_time_segs_out, metrics->tx_rx_stats.last_time_segs_in); - + __builtin_memcpy(buf, &sock_stats->metrics, sizeof(struct tcp_metrics_s)); bpf_ringbuf_submit(buf, 0); } -static void get_tcp_tx_rx_segs(struct sock *sk, struct tcp_tx_rx *segs) -{ - struct tcp_sock *tcp_sk = (struct tcp_sock *)sk; - segs->segs_in = _R(tcp_sk, segs_in); - segs->segs_out = _R(tcp_sk, segs_out); - // bpf_printk("Got TCP TX/RX segs. segs_in: %u, segs_out: %u", segs->segs_in, segs->segs_out); -} - static __always_inline struct tcp_metrics_s *get_tcp_metrics(struct sock *sk) { - struct sock_stats_s init_sock_stats = {}; + struct sock_stats_s init_sock_stats = {0}; struct sock_stats_s *sock_stats; sock_stats = (struct sock_stats_s *)bmloti(&tcp_link_map, &sk, &init_sock_stats); @@ -265,7 +264,6 @@ static __always_inline struct tcp_metrics_s *get_tcp_metrics(struct sock *sk) { return NULL; } - return &(sock_stats->metrics); } @@ -281,7 +279,6 @@ static __always_inline struct packet_count *count_packet(__u32 proto, bool is_tx { struct packet_count *count; struct packet_count initial_count = {0}; - count = bpf_map_lookup_elem(&proto_stats, &proto); if (!count) { @@ -335,7 +332,7 @@ static __always_inline int fill_sk_skb(struct drop_event *event, struct sock *sk bpf_probe_read(&event->sk_state, sizeof(event->sk_state), (const void *)&sk->__sk_common.skc_state); // bpf_printk(" IP:%U Dip:%u", event->skbap.saddr, event->skbap.daddr); } - // 从 sk_buff 中提取头部和网络层偏移信息 + bpf_probe_read(&head, sizeof(head), &skb->head); bpf_probe_read(&network_header, sizeof(network_header), &skb->network_header); if (network_header != 0) @@ -376,9 +373,9 @@ static __always_inline int fill_sk_skb(struct drop_event *event, struct sock *sk } static __always_inline void fill_tcp_packet_type(struct tuple_key *devent, struct sock *sk) { - devent->saddr = _R(sk, __sk_common.skc_rcv_saddr); - devent->daddr = _R(sk, __sk_common.skc_daddr); - devent->sport = _R(sk, __sk_common.skc_num); - devent->dport = __bpf_ntohs(_R(sk, __sk_common.skc_dport)); + devent->skbap.saddr = _R(sk, __sk_common.skc_rcv_saddr); + devent->skbap.daddr = _R(sk, __sk_common.skc_daddr); + devent->skbap.sport = _R(sk, __sk_common.skc_num); + devent->skbap.dport = __bpf_ntohs(_R(sk, __sk_common.skc_dport)); } #endif // __COMMON_BPF_H \ No newline at end of file diff --git a/agent/plugin/probe.bpf.c b/agent/plugin/probe.bpf.c index 04e31c93b38d338e7baf12cbbbb0c6d3d7358819..3bc6067f2bbcccb14cf1c54a5a29404ad6586d39 100644 --- a/agent/plugin/probe.bpf.c +++ b/agent/plugin/probe.bpf.c @@ -1,30 +1,136 @@ #include "common.bpf.h" #include "traffic.bpf.h" -// udp recieve -SEC("kprobe/udp_rcv") -int BPF_KPROBE(udp_rcv, struct sk_buff *skb) +/*helper*/ +static inline int udp_rcv_common(struct sk_buff *skb, bool is_fentry) { + if ((is_fentry ? !fentry_select : !kprobe_select) || !udp_info) + { + return 0; + } return __udp_rcv(skb); } - -SEC("kprobe/__udp_enqueue_schedule_skb") -int BPF_KPROBE(__udp_enqueue_schedule_skb, struct sock *sk, - struct sk_buff *skb) +static inline int udp_enqueue_common(struct sock *sk, struct sk_buff *skb, bool is_fentry) { + if ((is_fentry ? !fentry_select : !kprobe_select) || !udp_info) + { + return 0; + } return udp_enqueue_schedule_skb(sk, skb); } - -// send -SEC("kprobe/udp_send_skb") -int BPF_KPROBE(udp_send_skb, struct sk_buff *skb) +static inline int udp_send_common(struct sk_buff *skb, bool is_fentry) { + if ((is_fentry ? !fentry_select : !kprobe_select) || !udp_info) + { + return 0; + } return __udp_send_skb(skb); } +static inline int dev_hard_start_xmit_common(struct sk_buff *skb, bool is_fentry) +{ + if ((is_fentry ? !fentry_select : !kprobe_select) || !protocol_info) + { + return 0; + } + return __dev_hard_start_xmit(skb); +} + +static inline int tcp_cleanup_common(struct sock *sk, int copied, bool is_fentry) +{ + if ((is_fentry ? !fentry_select : !kprobe_select) || !tcp_output_info) + { + return 0; + } + return __tcp_cleanup_rbuf(sk, copied); +} +static inline int tcp_send_common(struct sock *sk, struct msghdr *msg, size_t size, bool is_fentry) +{ + if ((is_fentry ? !fentry_select : !kprobe_select) || !tcp_output_info) + { + return 0; + } + return __tcp_sendmsg(sk, msg, size); +} +static inline int tcp_close_common(struct sock *sk, bool is_fentry) +{ + if ((is_fentry ? !fentry_select : !kprobe_select) || !tcp_output_info) + { + return 0; + } + return trace_tcp_close(sk); +} + +static inline int eth_type_trans_common(struct sk_buff *skb, bool is_fentry) +{ + if ((is_fentry ? !fentry_select : !kprobe_select) || !protocol_info) + { + return 0; + } + return __eth_type_trans(skb); +} +static inline int tcp_connect_common(struct sock *sk, bool is_fentry) +{ + if ((is_fentry ? !fentry_select : !kprobe_select) || !packet_count) + { + return 0; + } + return __tcp_connect(sk); +} +static inline int tcp_rcv_state_process_common(struct sock *sk, struct sk_buff *skb, bool is_fentry) +{ + if ((is_fentry ? !fentry_select : !kprobe_select) || !packet_count) + { + return 0; + } + return __tcp_rcv_state_process(sk, skb); +} +static inline int tcp_send_fin_common(struct sock *sk, bool is_fentry) +{ + if ((is_fentry ? !fentry_select : !kprobe_select) || !packet_count) + { + return 0; + } + return __tcp_send_fin(sk); +} +// udp +SEC("kprobe/udp_rcv") +int BPF_KPROBE(kp_udp_rcv, struct sk_buff *skb) +{ + return udp_rcv_common(skb, false); +} +SEC("fentry/udp_rcv") +int BPF_PROG(ft_udp_rcv, struct sk_buff *skb) +{ + return udp_rcv_common(skb, true); +} +SEC("kprobe/__udp_enqueue_schedule_skb") +int BPF_KPROBE(kp__udp_enqueue_schedule_skb, struct sock *sk, struct sk_buff *skb) +{ + return udp_enqueue_common(sk, skb, false); +} +SEC("fentry/__udp_enqueue_schedule_skb") +int BPF_PROG(ft__udp_enqueue_schedule_skb, struct sock *sk, struct sk_buff *skb) +{ + return udp_enqueue_common(sk, skb, true); +} +SEC("kprobe/udp_send_skb") +int BPF_KPROBE(kp_udp_send_skb, struct sk_buff *skb) +{ + return udp_send_common(skb, false); +} +SEC("fentry/udp_send_skb") +int BPF_PROG(ft_udp_send_skb, struct sk_buff *skb) +{ + return udp_send_common(skb, true); +} SEC("kprobe/ip_send_skb") -int BPF_KPROBE(ip_send_skb, struct net *net, struct sk_buff *skb) +int BPF_KPROBE(kp_ip_send_skb, struct net *net, struct sk_buff *skb) { + if (!kprobe_select || !udp_info) + { + return 0; + } return __ip_send_skb(skb); } @@ -37,79 +143,124 @@ int handle_tcp_state(struct trace_event_raw_inet_sock_set_state *ctx) // protocol recieve SEC("kprobe/tcp_sendmsg") -int __handle_tcp_sendmsg(struct pt_regs *ctx) +int BPF_KPROBE(kp_tcp_sendmsg, struct sock *sk, struct msghdr *msg, size_t size) { - return __tcp_sendmsg(ctx); + return tcp_send_common(sk, msg, size, false); } +SEC("fentry/tcp_sendmsg") +int BPF_PROG(ft_tcp_sendmsg, struct sock *sk, struct msghdr *msg, size_t size) +{ + return tcp_send_common(sk, msg, size, true); +} SEC("kprobe/tcp_cleanup_rbuf") -int __handle_tcp_cleanup_rbuf(struct pt_regs *ctx) +int BPF_KPROBE(kp_tcp_cleanup_rbuf, struct sock *sk, int copied) +{ + return tcp_cleanup_common(sk, copied, false); +} + +SEC("fentry/tcp_cleanup_rbuf") +int BPF_PROG(ft_tcp_cleanup_rbuf, struct sock *sk, int copied) { - return __tcp_cleanup_rbuf(ctx); + return tcp_cleanup_common(sk, copied, true); +} + +SEC("kprobe/tcp_close") +int BPF_KPROBE(kp_tcp_close, struct sock *sk) +{ + return tcp_close_common(sk,false); +} + +SEC("fentry/tcp_close") +int BPF_PROG(ft_tcp_close, struct sock *sk) +{ + return tcp_close_common(sk,true); } // count the usage of protocol ports // receive SEC("kprobe/eth_type_trans") -int BPF_KPROBE(eth_type_trans, struct sk_buff *skb) +int BPF_KPROBE(kp_eth_type_trans, struct sk_buff *skb) { - return __eth_type_trans(skb); + return eth_type_trans_common(skb, false); +} +SEC("fentry/eth_type_trans") +int BPF_PROG(ft_eth_type_trans, struct sk_buff *skb) +{ + return eth_type_trans_common(skb, true); } -// send SEC("kprobe/dev_hard_start_xmit") -int BPF_KPROBE(dev_hard_start_xmit, struct sk_buff *skb) +int BPF_KPROBE(kp_dev_hard_start_xmit, struct sk_buff *skb) { - return __dev_hard_start_xmit(skb); + return dev_hard_start_xmit_common(skb, false); +} +SEC("fentry/dev_hard_start_xmit") +int BPF_PROG(ft_dev_hard_start_xmit, struct sk_buff *skb) +{ + return dev_hard_start_xmit_common(skb, true); } // iptables drop SEC("kprobe/ipt_do_table") -int BPF_KPROBE(ipt_do_table, struct sk_buff *skb, u32 hook, struct nf_hook_state *state) +int kp_ipt_do_table(struct pt_regs *ctx) { - struct xt_table *table = (struct xt_table *)PT_REGS_PARM4(ctx); return __ipt_do_table_start(ctx); } + SEC("kretprobe/ipt_do_table") -int BPF_KRETPROBE(ipt_do_table_ret) +int BPF_KRETPROBE(kp_ipt_do_table_ret) { int ret = PT_REGS_RC(ctx); - return __ipt_do_table_ret(ctx, ret); + __ipt_do_table_ret(ctx, ret); + return 0; } +//skb drop SEC("tracepoint/skb/kfree_skb") int handle_kfree_skb(struct trace_event_raw_kfree_skb *ctx) { return __kfree_skb(ctx); } -// SYN-ACK total -// SEC("kprobe/tcp_rcv_state_process ") -// int BPF_KPROBE(tcp_rcv_state_process ,struct sock *sk,struct sk_buff *skb) -// { -// return __tcp_rcv_state_process(sk,skb); -// } - +//SYN、SYN-ACK、FIN SEC("kprobe/tcp_connect") -int BPF_KPROBE(tcp_connect, struct sock *sk) +int BPF_KPROBE(kp_tcp_connect, struct sock *sk) { - bpf_printk("tcp_connect"); - return __tcp_connect(sk); + return tcp_connect_common(sk, false); } +SEC("fentry/tcp_connect") +int BPF_PROG(ft_tcp_connect, struct sock *sk) +{ + return tcp_connect_common(sk, true); +} SEC("kprobe/tcp_rcv_state_process") -int BPF_KPROBE(tcp_rcv_state_process, struct sock *sk, struct sk_buff *skb) +int BPF_KPROBE(kp_tcp_rcv_state_process, struct sock *sk, struct sk_buff *skb) { - bpf_printk("tcp_rcv_state_process"); - return __tcp_rcv_state_process(sk, skb); + return tcp_rcv_state_process_common(sk, skb, false); +} +SEC("fentry/tcp_rcv_state_process") +int BPF_PROG(ft_tcp_rcv_state_process, struct sock *sk, struct sk_buff *skb) +{ + return tcp_rcv_state_process_common(sk, skb, true); } - SEC("kprobe/tcp_send_fin") -int BPF_KPROBE(tcp_send_fin, struct sock *sk) +int BPF_KPROBE(kp_tcp_send_fin, struct sock *sk) { - bpf_printk("tcp_send_fin"); - return __tcp_send_fin(sk); + return tcp_send_fin_common(sk, false); +} +SEC("fentry/tcp_send_fin") +int BPF_PROG(ft_tcp_send_fin, struct sock *sk) +{ + return tcp_send_fin_common(sk, true); +} +//TCP CONN +SEC("tracepoint/tcp/tcp_rcv_space_adjust") +int handle_tcp_rcv_space_adjust(struct trace_event_raw_tcp_event_sk *ctx) +{ + return __tcp_rcv_space_adjust(ctx); } -// SEC("kprobe/tcp_send_reset") -// int handle_send_reset(struct pt_regs *ctx) +// SEC("tracepoint/tcp/tcp_send_reset") +// int handle_send_reset(struct trace_event_raw_tcp_event_sk_skb *ctx) // { -// return __tcp_send_reset(ctx); +// bpf_printk("ceshi11"); +// return 0; // } - diff --git a/agent/plugin/probe.c b/agent/plugin/probe.c index f00e5b640e2c5281893ce1357f557c1fe2d61d70..66bb25c81e12d365559ef69cfd3c117698bec70b 100755 --- a/agent/plugin/probe.c +++ b/agent/plugin/probe.c @@ -16,7 +16,7 @@ #include "probe.h" static volatile bool exiting = false; -static int udp_info = 0, tcp_status_info = 0, tcp_output_info = 0, protocol_info = 0, port_distribution = 0, drop_info = 0, drop_skb = 0, num_symbols = 0, cache_size = 0; +static int udp_info = 0, tcp_status_info = 0, tcp_output_info = 0, protocol_info = 0, port_distribution = 0, drop_info = 0, drop_skb = 0, num_symbols = 0, cache_size = 0, kprobe_select = 0, fentry_select = 0, tcp_conn = 0; static int packet_count = 0; struct protocol_stats proto_stats[MAX] = {0}; static int interval = 20, entry_count = 0; @@ -28,14 +28,17 @@ static struct packet_stats hash_map[HASH_MAP_SIZE] = {0}; const char argp_program_doc[] = "Trace time delay in network subsystem \n"; static const struct argp_option opts[] = { + {"kprobe", 'K', 0, 0, "Specify the mount type"}, + {"fentry", 'F', 0, 0, "Specify the mount type"}, {"udp", 'u', 0, 0, "trace the udp message"}, {"tcp_status_info", 't', 0, 0, "trace the tcp states"}, {"tcp_output_info", 'o', 0, 0, "trace the tcp flow"}, {"protocol_info", 'p', 0, 0, "statistics on the use of different protocols"}, - {"port_distribution_info", 'P', 0, 0, "statistical use of top10 destination ports"}, + {"port_distribution", 'P', 0, 0, "statistical use of top10 destination ports"}, {"drop_info", 'i', 0, 0, "trace the iptables drop"}, {"drop_skb", 'd', 0, 0, "trace the all skb drop"}, {"packet_count", 'c', 0, 0, "trace the packet include SYN、SYN-ACK、FIN"}, + {"tcpconn", 'T', 0, 0, "trace the tcp connect"}, {}, }; @@ -43,6 +46,13 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) { switch (key) { + case 'K': + kprobe_select = 1; // 设置 kprobe 标志 + break; + case 'F': + fentry_select = 1; // 设置 fentry 标志 + break; + case 'u': udp_info = 1; break; @@ -67,8 +77,12 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) case 'c': packet_count = 1; break; + case 'T': + tcp_conn = 1; + break; default: return ARGP_ERR_UNKNOWN; + break; } return 0; } @@ -96,7 +110,7 @@ static void format_ip_address(__be32 ip, char *buffer, size_t buffer_size) static int print_udp_event_info(void *ctx, void *packet_info, size_t data_sz) { - if (!udp_info) + if (!udp_info || (!fentry_select && !kprobe_select)) { return 0; } @@ -130,6 +144,11 @@ static int print_tcp_state_info(void *ctx, void *packet_info, size_t data_sz) { return 0; } + if (fentry_select || kprobe_select) + { + printf("Kprobe/fentry mount is not supported,Please select -t run\n"); + return 0; + } const struct event *pack_info = (const struct event *)packet_info; char s_str[INET_ADDRSTRLEN]; char d_str[INET_ADDRSTRLEN]; @@ -154,22 +173,30 @@ static int print_tcp_state_info(void *ctx, void *packet_info, size_t data_sz) static int print_tcp_flow_info(void *ctx, void *packet_info, size_t data_sz) { - if (!tcp_output_info) + if (!tcp_output_info || (!fentry_select && !kprobe_select)) { return 0; } const struct tcp_metrics_s *pack_info = (const struct tcp_metrics_s *)packet_info; + if ((pack_info->client_ip & 0x0000FFFF) == 0x0000007F || + (pack_info->server_ip & 0x0000FFFF) == 0x0000007F) + return 0; char s_str[INET_ADDRSTRLEN]; char d_str[INET_ADDRSTRLEN]; - if (pack_info->client_ip > 0xFFFFFFFF || pack_info->server_ip > 0xFFFFFFFF || pack_info->pid <= 0) + // if (pack_info->client_ip > 0xFFFFFFFF || pack_info->server_ip > 0xFFFFFFFF || pack_info->pid <= 0) + // { + // return 0; + // } + if (pack_info->pid <= 0) { return 0; } + format_ip_address(pack_info->client_ip, s_str, sizeof(s_str)); format_ip_address(pack_info->server_ip, d_str, sizeof(d_str)); - printf("%-20d %-20s %-20s %-20d %-20d %-20llu %-20llu %-20u %-20u %-20d\n", + printf("%-20d %-20s %-20s %-20d %-20d %-20zu %-20zu %-20u %-20u %-20d\n", pack_info->pid, s_str, d_str, @@ -259,7 +286,7 @@ static int find_port_entry(int dst_port, int proto) { for (int i = 0; i < entry_count; i++) { - if (entries[i].dst_port == dst_port && entries[i].proto == proto) + if (entries[i].skbap.dport == dst_port && entries[i].proto == proto) { return i; } @@ -269,7 +296,7 @@ static int find_port_entry(int dst_port, int proto) static int print_drop(void *ctx, void *packet_info, size_t data_sz) { - if (!drop_info) + if (!drop_info || (!fentry_select && !kprobe_select)) { return 0; } @@ -278,11 +305,6 @@ static int print_drop(void *ctx, void *packet_info, size_t data_sz) char s_str[INET_ADDRSTRLEN]; char d_str[INET_ADDRSTRLEN]; - if (!drop_info) - { - return 0; - } - format_ip_address(event->skbap.saddr, s_str, sizeof(s_str)); format_ip_address(event->skbap.daddr, d_str, sizeof(d_str)); const char *type_str = event->type >= 0 && event->type < 4 ? drop_type_str[event->type] : "UNKNOWN"; @@ -393,7 +415,7 @@ struct SymbolEntry findfunc(unsigned long int addr) static int print_drop_skb(void *ctx, void *packet_info, size_t data_sz) { - if (!drop_skb) + if (!drop_skb || (!fentry_select && !kprobe_select)) { return 0; } @@ -403,12 +425,12 @@ static int print_drop_skb(void *ctx, void *packet_info, size_t data_sz) char protol[6], result[40]; struct SymbolEntry data = findfunc(event->location); sprintf(result, "%s+0x%lx", data.name, event->location - data.addr); - if (event->client_ip == 0 && event->server_ip == 0) + if (event->skbap.saddr == 0 && event->skbap.daddr == 0) { return 0; } - format_ip_address(event->client_ip, s_str, sizeof(s_str)); - format_ip_address(event->server_ip, d_str, sizeof(d_str)); + format_ip_address(event->skbap.saddr, s_str, sizeof(s_str)); + format_ip_address(event->skbap.daddr, d_str, sizeof(d_str)); if (event->protocol == IPV4) { strcpy(protol, "ipv4"); @@ -421,7 +443,7 @@ static int print_drop_skb(void *ctx, void *packet_info, size_t data_sz) { strcpy(protol, "other"); } - printf("%-20d %-20s %-20s %-20d %-20d %-20s %-34lx %-34s \n", event->pid, s_str, d_str, event->client_port, event->server_port, protol, event->location, result); + printf("%-20d %-20s %-20s %-20d %-20d %-20s %-34lx %-34s \n", event->pid, s_str, d_str, event->skbap.sport, event->skbap.dport, protol, event->location, result); return 0; } static int print_count_protocol_use(void *ctx, void *packet_info, size_t data_sz) @@ -436,7 +458,7 @@ static int print_count_protocol_use(void *ctx, void *packet_info, size_t data_sz if (port_distribution) { // 查找当前端口号和协议号是否已经存在于 entries 数组中 - int index = find_port_entry(pack_protocol_info->dst_port, pack_protocol_info->proto); + int index = find_port_entry(pack_protocol_info->skbap.dport, pack_protocol_info->proto); if (index != -1) { entries[index].packet_count++; @@ -448,7 +470,7 @@ static int print_count_protocol_use(void *ctx, void *packet_info, size_t data_sz printf("entry_count big"); return 0; } - entries[entry_count].dst_port = pack_protocol_info->dst_port; + entries[entry_count].skbap.dport = pack_protocol_info->skbap.dport; entries[entry_count].proto = pack_protocol_info->proto; entries[entry_count].packet_count = 1; entry_count++; @@ -467,28 +489,31 @@ static int print_top_5_keys() for (int i = 0; i < TOP_N && i < entry_count; i++) { const char *proto_str = (entries[i].proto >= 0 && entries[i].proto <= 3) ? protocol[entries[i].proto] : "UNKNOWN"; - printf("Port: %d, PPS: %d, Protocol: %s\n", entries[i].dst_port, entries[i].packet_count, proto_str); + printf("Port: %d, PPS: %d, Protocol: %s\n", entries[i].skbap.dport, entries[i].packet_count, proto_str); } memset(entries, 0, entry_count * sizeof(struct packet_info)); entry_count = 0; return 0; } -static int tuple_key_hash(const struct tuple_key *key, u8 packet_type) { - return (key->saddr ^ key->daddr ^ key->sport ^ key->dport ^ packet_type) % HASH_MAP_SIZE; +static int tuple_key_hash(const struct tuple_key *key, u8 packet_type) +{ + return (key->skbap.saddr ^ key->skbap.daddr ^ key->skbap.sport ^ key->skbap.dport ^ packet_type) % HASH_MAP_SIZE; } - -static void output_statistics() { - for (int i = 0; i < HASH_MAP_SIZE; i++) { +static void output_statistics() +{ + for (int i = 0; i < HASH_MAP_SIZE; i++) + { struct packet_stats *stats = &hash_map[i]; - if (stats->syn_count != 0 || stats->synack_count != 0 || stats->fin_count != 0) { + if (stats->syn_count != 0 || stats->synack_count != 0 || stats->fin_count != 0) + { char s_str[INET_ADDRSTRLEN]; char d_str[INET_ADDRSTRLEN]; - format_ip_address(stats->key.saddr, s_str, sizeof(s_str)); - format_ip_address(stats->key.daddr, d_str, sizeof(d_str)); + format_ip_address(stats->key.skbap.saddr, s_str, sizeof(s_str)); + format_ip_address(stats->key.skbap.daddr, d_str, sizeof(d_str)); printf("Tuple (Source: %s:%d, Destination: %s:%d): SYN Count: %lld, SYN-ACK Count: %lld, FIN Count: %lld\n", - s_str, stats->key.sport, d_str, stats->key.dport, + s_str, stats->key.skbap.sport, d_str, stats->key.skbap.dport, stats->syn_count, stats->synack_count, stats->fin_count); stats->syn_count = 0; stats->synack_count = 0; @@ -496,8 +521,9 @@ static void output_statistics() { } } } -static int print_packet_count(void *ctx, void *packet_info, size_t data_sz) { - if (!packet_info) +static int print_packet_count(void *ctx, void *packet_info, size_t data_sz) +{ + if (!packet_info || (!fentry_select && !kprobe_select)) { return 0; } @@ -505,27 +531,53 @@ static int print_packet_count(void *ctx, void *packet_info, size_t data_sz) { // 创建 4-tuple 作为 key struct tuple_key key = { - .saddr = event->saddr, - .daddr = event->daddr, - .sport = event->sport, - .dport = event->dport - }; + .skbap.saddr = event->skbap.saddr, + .skbap.daddr = event->skbap.daddr, + .skbap.sport = event->skbap.sport, + .skbap.dport = event->skbap.dport}; // 包含 packet_type 以生成唯一的哈希索引 - int hash_index = tuple_key_hash(&key, event->sum.key.packet_type ); + int hash_index = tuple_key_hash(&key, event->sum.key.packet_type); struct packet_stats *stats = &hash_map[hash_index]; // 存储 4-tuple 信息 stats->key = key; // 根据包类型更新对应计数 - if ( event->sum.key.packet_type == 1) { // SYN - stats->syn_count = event->sum.syn_count; - } else if ( event->sum.key.packet_type == 2) { // SYN-ACK - stats->synack_count = event->sum.synack_count; - } else if ( event->sum.key.packet_type == 3) { // FIN - stats->fin_count = event->sum.fin_count; + if (event->sum.key.packet_type == 1) + { // SYN + stats->syn_count = event->sum.syn_count; + } + else if (event->sum.key.packet_type == 2) + { // SYN-ACK + stats->synack_count = event->sum.synack_count; + } + else if (event->sum.key.packet_type == 3) + { // FIN + stats->fin_count = event->sum.fin_count; + } + return 0; +} +static int print_tcp_conn(void *ctx, void *data, size_t data_sz) +{ + if (!tcp_conn) + { + return 0; } + if (fentry_select || kprobe_select) + { + printf("Kprobe/fentry mount is not supported,Please select -T run\n"); + return 0; + } + const struct tcp_rate *event = (const struct tcp_rate *)data; + char s_str[INET_ADDRSTRLEN]; + char d_str[INET_ADDRSTRLEN]; + + format_ip_address(event->skbap.saddr, s_str, sizeof(s_str)); + format_ip_address(event->skbap.daddr, d_str, sizeof(d_str)); + + printf("%-20d %-20s %-20s %-20d %-20d %-20lld %-20lld %-20lld\n", + event->pid, s_str, d_str, event->skbap.sport, event->skbap.dport, event->tcp_rto, event->tcp_ato, event->tcp_delack_max); return 0; } @@ -541,6 +593,7 @@ int main(int argc, char **argv) struct ring_buffer *perf_map = NULL; struct ring_buffer *trace_all_drop = NULL; struct ring_buffer *flags_rb = NULL; + struct ring_buffer *rate_rb = NULL; /* Parse command line arguments */ err = argp_parse(&argp, argc, argv, 0, NULL, NULL); @@ -549,7 +602,7 @@ int main(int argc, char **argv) libbpf_set_strict_mode(LIBBPF_STRICT_ALL); /* Set up libbpf errors and debug info callback */ - // libbpf_set_print(libbpf_print_fn); + // libbpf_set_print(libbpf_print_fn); /* Cleaner handling of Ctrl-C */ signal(SIGINT, sig_handler); @@ -631,9 +684,15 @@ int main(int argc, char **argv) fprintf(stderr, "Failed to create ring buffer\n"); goto cleanup; } - + rate_rb = ring_buffer__new(bpf_map__fd(skel->maps.rate_rb), print_tcp_conn, NULL, NULL); + if (!rate_rb) + { + err = -1; + fprintf(stderr, "Failed to create ring buffer\n"); + goto cleanup; + } /* Process events */ - if (udp_info) + if (udp_info && (fentry_select || kprobe_select)) { printf("%-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s\n", "Pid", "Client_ip", "Server_ip", "Client_port", "Server_port", "Comm", "Tran_time/μs", "Direction", "len/byte"); } @@ -641,26 +700,30 @@ int main(int argc, char **argv) { printf("%-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s \n", "Pid", "Client_ip", "Server_ip", "Client_port", "Server_port", "oldstate", "newstate", "time/μs"); } - if (tcp_output_info) + if (tcp_output_info && (fentry_select || kprobe_select)) { - printf("%-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s\n", "Pid", "Client_ip", "Server_ip", "Client_port", "Server_port", "Send/bytes", "receive/bytes", "segs_in", "segs_out", "Direction"); + printf("%-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s\n", "Pid", "Client_ip", "Server_ip", "Client_port", "Server_port", "Send/bytes", "receive/bytes", "segs_in", "segs_out","Direction"); } - if (drop_info) + if (drop_info && (fentry_select || kprobe_select)) { printf("%-20s %-20s %-20s %-20s %-20s %-20s %-20s \n", "Pid", "Client_ip", "Server_ip", "Client_port", "Server_port", "Protocol", "Drop_type"); } - if (drop_skb) + if (drop_skb && (fentry_select || kprobe_select)) { printf("%-20s %-20s %-20s %-20s %-20s %-20s %-20s \n", "Pid", "Client_ip", "Server_ip", "Client_port", "Server_port", "Protocol", "DROP_addr"); } - if (protocol_info) + if (protocol_info && (fentry_select || kprobe_select)) { printf("==========Proportion of each agreement==========\n"); } - if (port_distribution) + if (port_distribution && (fentry_select || kprobe_select)) { printf("==========port_distribution==========\n"); } + if (tcp_conn) + { + printf("%-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s \n", "Pid", "Client_ip", "Server_ip", "Client_port", "Server_port", "RTO/ms", "ATO/ms", "Delack_max/ms"); + } struct timeval start, end; gettimeofday(&start, NULL); while (!exiting) @@ -672,6 +735,7 @@ int main(int argc, char **argv) err = ring_buffer__poll(perf_map, 100 /* timeout, ms */); err = ring_buffer__poll(trace_all_drop, 100 /* timeout, ms */); err = ring_buffer__poll(flags_rb, 100 /* timeout, ms */); + err = ring_buffer__poll(rate_rb, 100 /* timeout, ms */); /* Ctrl-C will cause -EINTR */ // Regularly calculate and print the proportion of agreements if (err == -EINTR) @@ -707,6 +771,7 @@ cleanup: ring_buffer__free(perf_map); ring_buffer__free(trace_all_drop); ring_buffer__free(flags_rb); + ring_buffer__free(rate_rb); probe_bpf__destroy(skel); return err < 0 ? -err : 0; diff --git a/agent/plugin/probe.h b/agent/plugin/probe.h index 48c75566482c1b054287697dce3c5482ff4bb203..3e40a1d99ffccb719492c9ab2b593ca73de5dfff 100644 --- a/agent/plugin/probe.h +++ b/agent/plugin/probe.h @@ -5,8 +5,8 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; - -#define ETH_HLEN 14 // 以太网头部的长度 +#define MTU_SIZE 1500 +#define ETH_HLEN 14 // 以太网头部的长度 #define MAXSYMBOLS 300000 #define CACHEMAXSIZE 5 #define SK(sk) ((const struct sock *)(sk)) @@ -36,8 +36,18 @@ typedef unsigned long long u64; #define TCP_PROBE_TXRX (u32)(1 << 3) #define RCV_SHUTDOWN 2 #define HASH_MAP_SIZE 1024 +#define TIME_THRESHOLD_NS 200000000 // 200ms +typedef u64 stack_trace_t[MAX_STACK_DEPTH]; /* bpf.h struct helper */ +struct addr_pair +{ + u32 saddr; + u32 daddr; + u16 sport; + u16 dport; +}; + struct ktime_info { u64 qdisc_time; @@ -71,21 +81,18 @@ struct event struct reasonissue { - u32 client_ip; - u32 server_ip; - u16 client_port; - u16 server_port; + struct addr_pair skbap; long location; u16 protocol; int pid; }; struct tcp_tx_rx { - u64 rx; // FROM tcp_cleanup_rbuf - u64 tx; // FROM tcp_sendmsg - u32 last_time_segs_out; + size_t rx; // FROM tcp_cleanup_rbuf + size_t tx; // FROM tcp_sendmsg + u32 last_segs_out; u32 segs_out; // total number of segments sent - u32 last_time_segs_in; + u32 last_segs_in; u32 segs_in; // total number of segments in }; @@ -105,6 +112,7 @@ struct sock_stats_s { u64 txrx_ts; struct tcp_metrics_s metrics; + bool is_reported; }; enum @@ -124,10 +132,7 @@ struct packet_count struct packet_info { - u32 src_ip; - u32 dst_ip; - u16 src_port; - u16 dst_port; + struct addr_pair skbap; u32 proto; int packet_count; struct packet_count count; @@ -139,13 +144,6 @@ struct protocol_stats uint64_t tx_count; }; -struct addr_pair { - u32 saddr; - u32 daddr; - u16 sport; - u16 dport; -}; - static const char *tcp_states[] = { [1] = "ESTABLISHED", [2] = "SYN_SENT", @@ -177,8 +175,6 @@ struct tid_map_value u32 hook; void *ctx; }; - -typedef u64 stack_trace_t[MAX_STACK_DEPTH]; struct drop_event { u8 type; @@ -223,30 +219,30 @@ struct SymbolEntry char name[30]; }; // 4-tuple 结构体定义 -struct tuple_key { - uint32_t saddr; - uint32_t daddr; - uint16_t sport; - uint16_t dport; +struct tuple_key +{ + struct addr_pair skbap; u8 packet_type; }; - -struct packet_stats { +struct packet_stats +{ u64 syn_count; u64 synack_count; u64 fin_count; - struct tuple_key key; + struct tuple_key key; }; - -struct tcp_event { - u32 saddr; - u32 daddr; - u16 sport; - u16 dport; +struct tcp_event +{ + struct addr_pair skbap; struct packet_stats sum; }; - - - +struct tcp_rate +{ + struct addr_pair skbap; + u64 tcp_ato; + u64 tcp_rto; + u64 tcp_delack_max; + u32 pid; +}; #endif diff --git a/agent/plugin/traffic.bpf.h b/agent/plugin/traffic.bpf.h index d750f432d4494f08cf91187fe7498ff88493a942..3c248c9a00bb1a363a5604f2cbda9adbc4641c24 100644 --- a/agent/plugin/traffic.bpf.h +++ b/agent/plugin/traffic.bpf.h @@ -157,17 +157,21 @@ static __always_inline int __handle_tcp_state(struct trace_event_raw_inet_sock_s return 0; } // tcp -static __always_inline void handle_tcp_metrics(struct pt_regs *ctx, struct sock *sk, size_t size, bool is_tx, int pid) +static __always_inline void handle_tcp_metrics(struct sock *sk, size_t size, bool is_tx, int pid) { struct tcp_metrics_s *metrics = get_tcp_metrics(sk); if (!metrics) { return; } + struct tcp_metrics_s tuple = {}; get_tcp_tuple(sk, &tuple); metrics->pid = pid; + struct tcp_tx_rx current_stats = {}; + get_tcp_tx_rx_segs(sk, ¤t_stats); + if (is_tx) { metrics->client_ip = tuple.client_ip; @@ -175,7 +179,15 @@ static __always_inline void handle_tcp_metrics(struct pt_regs *ctx, struct sock metrics->client_port = tuple.client_port; metrics->server_port = tuple.server_port; metrics->tran_flag = 1; - TCP_TX_DATA(metrics->tx_rx_stats, (int)size); + + TCP_TX_DATA(metrics->tx_rx_stats, size); + + if (current_stats.segs_out > metrics->tx_rx_stats.last_segs_out) + { + u32 segs_out_delta = current_stats.segs_out - metrics->tx_rx_stats.last_segs_out; + metrics->tx_rx_stats.segs_out += segs_out_delta; + metrics->tx_rx_stats.last_segs_out = current_stats.segs_out; + } } else { @@ -184,40 +196,50 @@ static __always_inline void handle_tcp_metrics(struct pt_regs *ctx, struct sock metrics->client_port = tuple.server_port; metrics->server_port = tuple.client_port; metrics->tran_flag = 0; - get_tcp_tx_rx_segs(sk, &metrics->tx_rx_stats); + TCP_RX_DATA(metrics->tx_rx_stats, size); - } - report_tx_rx(ctx, metrics, sk); + if (current_stats.segs_in > metrics->tx_rx_stats.last_segs_in) + { + u32 segs_in_delta = current_stats.segs_in - metrics->tx_rx_stats.last_segs_in; + metrics->tx_rx_stats.segs_in += segs_in_delta; + metrics->tx_rx_stats.last_segs_in = current_stats.segs_in; + } + } } -// send -static __always_inline int __tcp_sendmsg(struct pt_regs *ctx) + +static __always_inline int __tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) { - struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx); int pid = get_current_tgid(); - struct tcp_metrics_s tuple = {}; - - get_tcp_tuple(sk, &tuple); - size_t send_size = (size_t)PT_REGS_PARM3(ctx); - // bpf_printk("Sending size: %zu\n", send_size); - handle_tcp_metrics(ctx, sk, send_size, true, pid); + handle_tcp_metrics(sk, size, true, pid); return 0; } // recieve -static __always_inline int __tcp_cleanup_rbuf(struct pt_regs *ctx) +static __always_inline int __tcp_cleanup_rbuf(struct sock *sk, int copied) { - struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx); int pid = get_current_tgid(); - struct tcp_metrics_s tuple = {}; - get_tcp_tuple(sk, &tuple); - int recieve_size = (int)PT_REGS_PARM2(ctx); - if (recieve_size <= 0) + if (copied <= 0) + { + return 0; + } + handle_tcp_metrics(sk, copied, false, pid); + return 0; +} + +static __always_inline int trace_tcp_close(struct sock *sk) +{ + struct sock_stats_s *sock_stats = bpf_map_lookup_elem(&tcp_link_map, &sk); + if (!sock_stats || sock_stats->is_reported) { return 0; } - // bpf_printk("recieve_size: %zu\n", recieve_size); - handle_tcp_metrics(ctx, sk, (size_t)recieve_size, false, pid); + + report_tx_rx(sock_stats, sk); + + sock_stats->is_reported = true; + bpf_map_delete_elem(&tcp_link_map, &sk); + __builtin_memset(sock_stats, 0, sizeof(struct sock_stats_s)); return 0; } @@ -245,23 +267,23 @@ static __always_inline int process_packet(struct sk_buff *skb, bool is_tx) return 0; } - pkt->src_ip = _R(ip, saddr); - pkt->dst_ip = _R(ip, daddr); + pkt->skbap.saddr = _R(ip, saddr); + pkt->skbap.daddr = _R(ip, daddr); pkt->proto = _R(ip, protocol); if (pkt->proto == IPPROTO_TCP) { struct tcphdr *tcp = (struct tcphdr *)(_R(skb, data) + sizeof(struct ethhdr) + sizeof(struct iphdr)); - pkt->src_port = _R(tcp, source); - pkt->dst_port = _R(tcp, dest); + pkt->skbap.sport = _R(tcp, source); + pkt->skbap.dport = _R(tcp, dest); pkt->proto = PROTO_TCP; // bpf_printk("TCP packet: src_port=%d, dst_port=%d\n", pkt->src_port, pkt->dst_port); } else if (pkt->proto == IPPROTO_UDP) { struct udphdr *udp = (struct udphdr *)(_R(skb, data) + sizeof(struct ethhdr) + sizeof(struct iphdr)); - pkt->src_port = _R(udp, source); - pkt->dst_port = _R(udp, dest); + pkt->skbap.sport = _R(udp, source); + pkt->skbap.dport = _R(udp, dest); pkt->proto = PROTO_UDP; // bpf_printk("UDP packet: src_port=%d, dst_port=%d\n", pkt->src_port, pkt->dst_port); } @@ -310,13 +332,13 @@ static __always_inline int __ipt_do_table_start(struct pt_regs *ctx) struct tid_map_value value = {}; struct sk_buff *skb = (struct sk_buff *)PT_REGS_PARM1(ctx); - struct nf_hook_state *state = (struct nf_hook_state *)PT_REGS_PARM3(ctx); - struct xt_table *table = (struct xt_table *)PT_REGS_PARM4(ctx); - u32 hook = (u32)PT_REGS_PARM2(ctx); + struct nf_hook_state *state = (struct nf_hook_state *)PT_REGS_PARM2(ctx); + struct xt_table *table = (struct xt_table *)PT_REGS_PARM3(ctx); + // u32 hook = (u32)PT_REGS_PARM2(ctx); value.skb = skb; value.state = state; - value.hook = hook; + // value.hook = hook; value.table = table; bpf_map_update_elem(&inner_tid_map, &tid, &value, BPF_ANY); @@ -355,7 +377,7 @@ static __always_inline int submit_event(struct pt_regs *ctx, struct tid_map_valu bpf_probe_read(event->name, sizeof(event->name), (void *)addr); } - event->hook = value->hook; + // event->hook = value->hook; } bpf_ringbuf_submit(event, 0); return 1; @@ -381,7 +403,6 @@ static __always_inline int __ipt_do_table_ret(struct pt_regs *ctx, int ret) } return 0; } - static __always_inline int __kfree_skb(struct trace_event_raw_kfree_skb *ctx) { struct sk_buff *skb = ctx->skbaddr; @@ -390,17 +411,17 @@ static __always_inline int __kfree_skb(struct trace_event_raw_kfree_skb *ctx) struct iphdr *ip = extract_iphdr(skb); struct tcphdr *tcp = extract_tcphdr(skb); struct event devent = {0}; - get_tcp_pkt_tuple(&devent, ip, tcp,2); + get_tcp_pkt_tuple(&devent, ip, tcp, 2); struct reasonissue *event; event = bpf_ringbuf_reserve(&trace_all_drop, sizeof(*event), 0); if (!event) { return 0; } - event->client_ip = devent.client_ip; - event->server_ip = devent.server_ip; - event->client_port = devent.client_port; - event->server_port = devent.server_port; + event->skbap.saddr = devent.client_ip; + event->skbap.daddr = devent.server_ip; + event->skbap.sport = devent.client_port; + event->skbap.dport = devent.server_port; event->pid = get_current_tgid(); event->location = (long)ctx->location; event->protocol = ctx->protocol; @@ -432,10 +453,10 @@ static __always_inline void update_packet_count(void *map, struct tuple_key *dev return; } __builtin_memset(event, 0, sizeof(*event)); - event->saddr = devent->saddr; - event->daddr = devent->daddr; - event->sport = devent->sport; - event->dport = devent->dport; + event->skbap.saddr = devent->skbap.saddr; + event->skbap.daddr = devent->skbap.daddr; + event->skbap.sport = devent->skbap.sport; + event->skbap.dport = devent->skbap.dport; event->sum.key.packet_type = packet_type; switch (event->sum.key.packet_type) { @@ -456,7 +477,7 @@ static __always_inline void update_packet_count(void *map, struct tuple_key *dev static __always_inline int __tcp_connect(struct sock *sk) { - if (!sk ) + if (!sk) return 0; struct tuple_key devent = {0}; fill_tcp_packet_type(&devent, sk); // SYN packet type @@ -472,7 +493,7 @@ static __always_inline int __tcp_rcv_state_process(struct sock *sk, struct sk_bu struct iphdr *ip = extract_iphdr(skb); struct tcphdr *tcp = extract_tcphdr(skb); struct tuple_key devent = {0}; - get_tcp_pkt_tuple(&devent, ip, tcp,1); + get_tcp_pkt_tuple(&devent, ip, tcp, 1); // update SYN-ACK update_packet_count(&synack_count_map, &devent, 2); @@ -490,6 +511,43 @@ static __always_inline int __tcp_send_fin(struct sock *sk) return 0; } +static __always_inline int __tcp_rcv_space_adjust(struct trace_event_raw_tcp_event_sk *ctx) +{ + struct sock *sk = (struct sock *)ctx->skaddr; + if (!sk) + return 0; + + u64 current_time = bpf_ktime_get_ns() / 1000; + u64 *last_time = bpf_map_lookup_elem(&tcp_rate_map, &sk); + + if (last_time) + { + if ((current_time - *last_time) < TIME_THRESHOLD_NS) + { + return 0; + } + } + + bpf_map_update_elem(&tcp_rate_map, &sk, ¤t_time, BPF_ANY); + struct inet_connection_sock *icsk = (struct inet_connection_sock *)sk; + if (!icsk) + return 0; + struct tcp_rate *message = bpf_ringbuf_reserve(&rate_rb, sizeof(*message), 0); + if (!message) + { + return 0; + } + message->tcp_ato = BPF_CORE_READ(icsk, icsk_ack.ato); + message->skbap.saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); + message->skbap.daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr); + message->skbap.sport = __bpf_ntohs(BPF_CORE_READ(sk, __sk_common.skc_num)); + message->skbap.dport = __bpf_ntohs(BPF_CORE_READ(sk, __sk_common.skc_dport)); + message->tcp_rto = BPF_CORE_READ(icsk, icsk_rto); + message->tcp_delack_max = BPF_CORE_READ(icsk, icsk_delack_max); + message->pid = get_current_tgid(); + bpf_ringbuf_submit(message, 0); + return 0; +} // 捕获 RST 包 // static __always_inline int __tcp_send_reset(struct pt_regs *ctx) { // // 增加 RST 包计数