在之前的文章中介绍了网络的「分层」概念1,那么这一篇继续科普一下网络的基础,即「转发」这个概念。
所有的转发都是二层转发。
为什么这么说呢?从前面网络的分层中我们已经知道,四层的网络协议是基于一种三层协议的,三层协议的数据包需要二层协议来承载(毕竟,我们不可能直接把三层数据包不经过二层直接传给别人),然后二层协议的数据包通过物理层发出去。物理层就是通信技术的知识了,可以说,到网络工程师这里第一层数字信号就是二层。在我们平时使用抓包工具抓包的时候,看的最外层数据包一般都是二层的包。
从网络设备的工作原理上讲也是这样,一个 IP 包从 src 传到 dst,中间经过了各种各样的网络设备,那么从 src 发出到 dst 收到,中间的网络设备修改了这个包的什么内容,才能一环接一环把它送到目的地呢?
交换机:不会修改任何内容,只查找自己的 mac 地址表转发走;
路由器:会根据 dst IP 查询下一跳应该发给哪一个 IP,但是下一跳的 IP 不会添加到数据包中。路由器会获取到下一跳对应的 MAC 地址,把数据包的 dst MAC 修改成下一跳的 MAC 然后转发出去。可以认为,此路由器出口 IP 和下一跳路由器入口的 IP 是在同一个子网中,所以每跳三层转发都是在同一个子网内的转发,即「所有的转发都是二层转发」。一般来说,路由器会有很多个物理接口,每一个物理接口都有 IP,互相连接的两个路由器的接口是在同一个子网(也有某些特殊的 P2P 网络可以不在同子网,甚至不需要配置 IP就能完成三层路由)。
可以看出来,如果不考虑 NAT 这种会改变 IP 的设备,三层及以上的内容(除了 TTL 会被路由器修改)的内容是基本不会改变的。而二层内容几乎每一次都在改变。
Traceroute 的原理
一个包从源发送到目的地,要经过的网络设备太多,遇到问题怎么排查呢?traceroute 是网络的世界中最常用的一个工具了。
它的原理是:发送 TTL=1 的 ping 包,故意让第 1 跳路由器无法完成转发,第 1 跳路由器只能丢弃这个包,并发送 ICMP time exceed 错误信息回来,这个 ICMP 是告诉我转发的时候出错了,源 IP 是发生因为 TTL 丢包的设备的 IP,目的 IP 就是我,因为错误是要告诉我的。于是我就知道了第 1 跳的 IP(即丢包的 IP)是什么了。如此炮制,继续发送 TTL=2 的包出去,拿到第二跳的地址。知道目的地收到了我的包并且回复 ICMP reply 回来。这样,我就知道了整条链路上所有的设备的 IP,就可以用来定位问题了。当然了,肯定有些设备因为「安全因素」的考虑,配置了不对丢包发回去 ICMP time exceed,这样,这一跳就是空的,我们拿不到它的 IP。
说起来,还有过一次挺有意思的讨论。一次面试的时候,我和人家讨论 traceroute 的原理,对方讲的很好—— 「发送 TTL=1 的包,再发送 TTL=2 的包,到那一跳的时候会因为 TTL 丢包,然后直接发送一个 ICMP 回来」。但是这里的「直接」很有意思,有多直接呢?我问:「直接的意思是,比如第 3 跳会直接发给 src IP 一个 ICMP,还是第三跳转发 ICMP 给第 2 跳,第 2 跳转发给第 1 跳,最后转发到 src IP ?」对方说:「是前者,会直接发给 src IP,因为是要立即告诉 sender 出错了。」
但是…… 候选人忽略了一个实际的问题——我们的 sender 和 R3 有物理连接吗?如果有物理连接,那么从发出的时候就不需要经过 R1 和 R2 了!说完之后他也恍然大悟,包是不可能隔空传递的!
什么是流?
谈到四层的时候,我认为流 (flow) 这个概念在四层上强调地不够。四层的数据流,就像小溪一样,源源不断从一个地方流到另一个地方,但是经过的路线总是一样的。
虽然在 IP 层每一跳都可能有多个下一跳设备可以选择,甚至多个设备的 cost 一样。那么在选路的时候,这一跳会根据 hash 算法来选择一个作为下一跳。hash 算法对于属于同一个流的数据包总会得到相同的结果,这样,就可以保证一个流的所有数据包经过的路线是一样的。比如,TCP 用来计算 hash 的 header 有 (src ip, src port, dst ip, dst port)
,UDP 和 TCP 一样,ICMP 一般是 (src ip, dst ip)
。这也取决于设备的配置和实现,不一定非要使用这些字段。比如,使用 (src MAC, dst MAC)
也可以,TCP 的 hash 也可以只使用 (src ip, dst ip)
。只要保证一点:同一个流经过的路线是一样的,就可以了。
为什么要这样做呢?为了尽最大努力保证数据包的顺序,让接收到的顺序和发送的顺序是一致的。
但是 TCP 协议不是会保证包的顺序的一致性吗?是的。TCP 尽管可以帮我们纠正顺序,但是这不是免费的,TCP 需要在实现上利用 buffer 将乱序的包临时保存并且重新排列,然后再交给应用层。而且 TCP 协议可能认为收到的包乱序是网络堵塞了,然后会降低发送的速度。所以 IP 层会尽量保证包的到达顺序和发送顺序一致,但是不会完全保证。TCP 则会作为最后的兜底,完全保证顺序的一致性。
==计算机网络实用技术 目录==
这篇文章是计算机网络实用技术系列文章中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网路分析。
如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!
没有链接的目录还没有写完,敬请期待……
- 序章
- 抓包技术以及技巧
- 理解网络的分层模型
- 数据是如何路由的
- 网络问题排查的思路和技巧
- 不可以用路由器?
- 网工闯了什么祸?
- 网络中的环路和防环技术
- 延迟增加了多少?
- TCP 延迟分析
- 压测的时候 QPS 为什么上不去?
- 压测的时候 QPS 为什么上不去?答案和解析
- 重新认识 TCP 的握手和挥手
- 重新认识 TCP 的握手和挥手:答案和解析
- TCP 下载速度为什么这么慢?
- TCP 长肥管道性能分析
- 后记:学习网络的一点经验分享
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。