2

我正在as close to real-time尽可能在 linux 上开发一个系统,一旦我收到一个特定的数据包,就需要在 TCP 数据包中发送大约 600-800 个字节。

为了获得尽可能好的延迟,我希望这个数据包直接从内核发送,而不是接收到的数据包一直到达用户空间和应用程序,然后返回。

如果我在 Windows 上,我会编写一个 NDIS 过滤器,我将缓存要发送的数据包和匹配的参数,以便它检查接收到的数据包并在匹配时将预缓存的数据包触发到网络上而不通过接收到的数据包向上层。

所以我的问题是 linux 上最接近 NDIS 过滤器的类似物是什么?

我已经阅读了有关 netfilter 的内容,也许这就是我会使用的,但我不知道这是否是最好的方法。

我还能做些什么来实现尽可能低的延迟?

我当前的纯用户空间代码在 Intel Xeon 3.7 GHz 处理器上运行 2.6.3x 内核上的 Ubuntu 10.04 给了我大约 80-100 微秒。

4

2 回答 2

2

您可以使用iptables目标NFLOG将数据包复制到用户空间或NFQUEUE允许用户空间破坏它们。这种交互发生在netlink上,但您可以使用诸如libnetfilter_loglibnetfilter_queue 之类的库来环绕它。

于 2012-10-12T04:29:53.863 回答
1

Linux内核中有类似的机制称为BPF(伯克利包过滤器)。从您的应用程序中将 BPF 过滤器注册到内核中。匹配过滤器的数据包将被捕获并转发到注册的钩子函数。

以下是我在互联网上找到的示例代码。( https://gist.github.com/939154 ) 基本上你必须创建一个打开,将它与 BPF 过滤器绑定,然后选择这个 FD 来接收数据包:set_filter(int fd) { struct bpf_program fcode = {0};

/* dump ssh packets only */
struct bpf_insn insns[] = {
    BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 10),
    BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 8),
    BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
    BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
    BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
    BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 22, 2, 0),
    BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 22, 0, 1),
    BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
    BPF_STMT(BPF_RET+BPF_K, 0),
};


/* Set the filter */
fcode.bf_len = sizeof(insns) / sizeof(struct bpf_insn);
fcode.bf_insns = &insns[0];

if(ioctl(fd, BIOCSETF, &fcode) < 0)
    return -1;

return 0;

}

bpf_inst 看起来很糟糕。但是,不需要手动编写它。您可以使用 tcp-dump 自动生成这些脚本。

例如:

sudo tcpdump 'tcp[13]=18'  -i eth0 -dd
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 0, 8, 0x00000800 },
{ 0x30, 0, 0, 0x00000017 },
{ 0x15, 0, 6, 0x00000006 },
{ 0x28, 0, 0, 0x00000014 },
{ 0x45, 4, 0, 0x00001fff },
{ 0xb1, 0, 0, 0x0000000e },
{ 0x50, 0, 0, 0x0000001b },
{ 0x15, 0, 1, 0x00000012 },
{ 0x6, 0, 0, 0x00000060 },
{ 0x6, 0, 0, 0x00000000 },
于 2012-10-12T03:22:56.853 回答