TCP如何在多路分解中读取IP地址?

How can the TCP read the IP address in demultiplexing?

大多数计算机网络书籍在解释 TCP/IP 堆栈时都提到:当一个层收到其 PDU(无论是帧还是段...)时,执行以下操作:

如果这是真的,那么问题来了:TCP 如何知道源 IP 地址(网络层 header 中的地址),它将用于将段移动到它们适当的套接字。

提前致谢!

他们在(介绍性)教科书中所说的关于网络堆栈中数据包遍历的内容只是教学。如果我们看一下它是如何实现的,就会复杂得多。让我们考虑一下 Linux。

我引用文章的相关部分来回答你的问题。

  1. IP 数据包处理程序通过从 net/ipv4/ip_output.c:ip_init() 调用的 net/core/dev.c:dev_add_pack() 进行注册。

  2. IPv4包处理函数是net/ipv4/ip_input.c:ip_rcv()。经过一些初始检查(如果数据包是针对该主机的,...)计算 ip 校验和。对长度和 IP 协议版本 4 进行了额外检查。此时将丢弃未通过其中一项健全性检查的每个数据包。

  3. 遍历成功后,调用net/ipv4/ipv_input.c:ip_rcv_finish()。在 ip_rcv_finish() 内部,数据包的目的地是通过调用路由函数 net/ipv4/route.c:ip_route_input() 来确定的。此外,如果我们的 IP 数据包有 IP 选项,它们现在会被处理。根据 net/ipv4/route.c:ip_route_input_slow() 做出的路由决定,我们的数据包的旅程在以下功能之一中继续:

    • net/ipv4/ip_input.c:ip_local_deliver() :数据包的目的地是本地的,我们必须处理第 4 层协议并将其传递给用户空间进程。

    • net/ipv4/ip_forward.c:ip_forward() : 数据包的目的地不是本地的,我们必须将它转发到另一个网络

    • net/ipv4/route.c:ip_error() :发生错误,我们无法为该数据包找到合适的路由 table 条目。

    • net/ipv4/ipmr.c:ip_mr_input() :这是一个多播数据包,我们必须做一些多播路由。

注意: 跳过了一些与 Netfilter 挂钩相关的遍历阶段。所有阶段请参考原文

net/ipv4/in_input.c:ip_local_deliver() 是我们感兴趣的函数。如上所述,它处理第 4 层协议并将其传递给用户空间。从 Linux 内核代码中可以看出它是如何实现的,简而言之,假设 ip_local_deliver() 了解第 3 层细节并没有什么坏处。