sockets - 为什么 skb_buffer 需要跳过 20 个字节才能在数据包输入时读取传输缓冲区?

标签 sockets networking tcp linux-kernel linux-device-driver

我正在 Linux 中编写一个网络模块,我看到只有从 skb 缓冲区跳过 20 个字节后才能提取 tcp header ,即使 API 是“skb_transport_header”。 其背后的原因是什么?有人可以详细解释一下吗?传出数据包不需要同样的。我知道在接收数据包时,当数据包从 L1 流向 L5 时, header 会被删除。但是,当数据包传出时,会添加 header 。这在这里有何不同?

/**对于输入包**/

  struct tcphdr *tcp; 
  tcp = (struct tcphdr *)(skb_transport_header(skb)+20);

/** 对于传出数据包 **/

struct tcphdr *tcp; 
tcp = (struct tcphdr *)(skb_transport_header(skb));

最佳答案

这取决于您在堆栈中处理数据包的位置。就在收到数据包之后,传输 header 偏移量尚未设置。一旦你确定这个数据包实际上是发往本地盒子的,就不再需要了。这发生在 ip_local_deliver_finish() 中的 IPv4 中。 (请注意,例如,tcp_hdr() 假定 transport_header 位置已经设​​置。)

这是完全有道理的(尽管很难确定在正常流程中发生这种事情的位置):随着每一层被识别和处理,下一层的起始偏移量被记录在 sk_buff 中。 header 实际上并没有被删除,skb“数据”位置只是被调整为指向它们之外。层特定的位置也进行了类似的调整。

在输出时,它更直接一些,并且以相反的顺序完成:首先创建传输 header 。然后,网络 header 被添加到它前面,等等。

关于sockets - 为什么 skb_buffer 需要跳过 20 个字节才能在数据包输入时读取传输缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23693335/

相关文章:

如果客户端停止(SIGSTOP),Python TCP 服务器将永远阻止发送给客户端

c# - StreamSocket下DataWriter的StoreAsync是如何工作的?

java - 两个独立 LAN 网络上的计算机之间未发生套接字连接

php - 想要手动发送 SYN ACK 数据包来建立 TCP 连接(如果可能的话在 PHP 中)

windows - 套接字异步操作是否会同步完成?

Python 套接字接受 block - 防止应用程序退出

c - C 语言的 Windows 套接字编程

html - 资源在 Google Chrome 网络选项卡中显示待处理和来自缓存

java 网络,写入调用平均比读取调用长 4 倍,这正常吗?

linux - 在 Linux 上使用 VB.net 的 Windows TCP 套接字连接