tracee源码初探(二)TCP处理流程
handleEvents(ctx), processNetCaptureEvents(若开启Capture.Net)协程一直常驻,并等待netCapChannel消息通知. 当有事件传过来时, 程序先看该事件是否需要处理,也就是说tracee是上报所有事件的,然后过滤来处理事件。在tracee.go中的initBPF函数里t.bpfModule.InitPerfBuf( "net_cap_events", ...)函数,初始化了网络事件的PerfBuf, 然后tracee.bpf.c是挂载到内核的函数SEC("cgroup_skb/ingress")和SEC("cgroup_skb/egress"),当有网络事件时,把事件放到net_cap_events map中并提交到用户空间。具体过程是:
挂载事件触发函数cgroup_skb_generic-->CGROUP_SKB_HANDLE(proto)->函数定义展开为cgroup_skb_handle_proto(ctx, neteventctx, nethdrs)-->CGROUP_SKB_HANDLE_FUNCTION(proto)【这一步映射是猜的】 如果是IP报文则解析IP报文属性,当解析出事TCP报文时调用CGROUP_SKB_HANDLE_FUNCTION(proto_tcp)-->cgroup_skb_capture-->cgroup_skb_capture_event(ctx, neteventctx, NET_PACKET_CAP_BASE)-->cgroup_skb_submit(&net_cap_events,ctx,neteventctx,event_type,nc->capture_length);
这里需要注意的一点是cgroup_skb_generic函数中用到的ingress和egress方向的已存储map:cgrpctxmap_in和cgrpctxmap_eg是由SEC("kprobe/__cgroup_bpf_run_filter_skb")挂载的函数实现存储起来的,cgroup_skb_generic只通过bpf_map_lookup_elem查找处理完之后再用bpf_map_delete_elem把对应的map数据删除。
当输入传送到用户空间的handleEvents函数来处理,会调用processEvents触发processor来处理(例如processWriteEvent等)然后是deriveEvents来处理派生函数NetPacketTCP对应的派生函数是derive.NetPacketTCP()解析TCP的各个字段,最后handleEvents调用sinkEvents把事件放入到t.config.ChanEvents中,然后tracee一直运行的Run()函数取出ChanEvents中的事件进行事件输出给用户可视端。
而如果config.Capture.Net配置开启还有processNetCapEvent来处理,刚好事件的ID是NET_PACKET_CAP_BASE, 最后写入pcap文件。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现