拦截点的选取 · didi/rdebug Wiki

流量录制必然要在某个点上对流量进行拦截并镜像。这里有几个选择。

point

在进入到 tcp/ip 协议栈的时候线程id已经丢失了。所以只有两个选项

  • libc 拦截。因为 send/recv 的拦截是在业务进程内执行的,所以调用的call stack是在同一个线程上。可以直接调用获取‘当前线程id“。
  • syscall 拦截

    • ptrace,走的是中断,太慢
    • syscall jmp table 补丁,需要改内核
    • syscall eBPF 需要新版本的内核

所以对于使用了 libc 的语言来说,LD_PRELOAD 拦截 libc 是最合适的拦截点。对于 Go 语言来说,没有使用 libc,所以拦截是通过修改语言标准库来实现的。需要用定制版的 Go 编译器对源代码进行编译,但是也不需要修改业务源代码。

本质上,这个问题就是一个书同文,车同轨的问题。理论上如果所有的代码都用同一种语言实现,那么我们修改这个语言就行。如果所有的代码是用同一种框架实现,我们修改这个框架就行。因为我们现在只能保证所有的代码用一套类似的 syscall(无论是linux还是mac),所以只能在 syscall 层面做公共的拦截。否则就需要给每一种语言,每一种框架写一套拦截代码。什么时候能够实现书同文,车同轨?我们先需要有一个能够焚书坑儒的秦始皇。


Original url: Access
Created at: 2019-06-11 16:34:50
Category: default
Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论