【问题标题】:How can the TCP read the IP address in demultiplexing?TCP如何在解复用中读取IP地址?
【发布时间】:2020-09-25 05:37:30
【问题描述】:

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

  • 检查字段,做一些事情并决定是否将消息传递到它上面的层。
  • 如果该层决定将消息传递给它上面的层,则上面的层将在之后再次执行相同的上一步(删除上一层标头)。

如果这是真的,那么问题就来了:TCP 如何知道源 IP 地址(在网络层标头中),该地址将用于将段移动到相应的套接字。

提前致谢!

【问题讨论】:

  • 在 TCP 套接字的情况下,它已经与套接字关联;在 UDP 的情况下,它是要传递给应用程序的数据的一部分,因此它被提供给 UDP 层。但分层并不像某些文本暗示或陈述的那样干净利落。引擎盖下有很多偷窥。

标签: sockets networking tcp network-programming ip


【解决方案1】:

他们在(介绍性)教科书中关于网络堆栈中数据包遍历的内容只是教学性的。如果我们看看它是如何实现的,它会复杂得多。让我们考虑一下 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() : 发生错误,我们无法为此数据包找到合适的路由表条目。

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

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

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

【讨论】:

  • @IbrahimAlnefisi 由于您是社区新手,请刷新此链接someone-answers
猜你喜欢
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
  • 2019-06-26
  • 2016-06-30
  • 2021-12-05
  • 2016-07-27
  • 1970-01-01
相关资源
最近更新 更多