《Computer Networking - A Top-Down Approach》第四章4.1-4.3复习知识点总结
第四章主要是讲网络层,也就是IP协议。
4.1 网络层概览
4.1.1 转发和路由
转发和路由很相近,但是是两个不同的服务,都由网络层进行支持。
- 转发。转发是指,一个IP包到达路由器,路由器决定要将这个包从哪一个接口再度发出去,以便该接口到达目的IP地址。这是一个路由器本地的操作。
- 路由。路由是指,在整个网络范围内,决定好从一个源地址到目的地址的路线。这是一个全网的操作,通常耗时更长。
对于路由器来说,转发表是最重要的数据结构。
转发就是靠从IP包中找出几个域,而后从转发表中索引出目的IP地址对应的发出接口。
路由则是用来决定转发表中的值的。
4.1.2 网络层服务模型
网络层服务模型为:最大努力模型,也就是没有任何保证的模型。
4.2 路由器里有什么
路由器里有四个重要的组成部分:
- 输入端口。输入端口有如下作用:
- 终止物理连接,使得物理链路上传输的bit流进入路由器
- 进行链路层包解析,提取出网络层包
- 根据网络层的包结构进行转发,如果是控制消息包,比如路由协议的包,就转发给路由处理器,如果是数据包,就查询转发表并发到对应的输出端口上
- 输出端口,向外传输数据
- Switching Fabric 连接输入端口和输出端口/路由处理器
- 路由处理器,使用相应的路由协议,路由算法,维护转发表,接受路由协议消息或向外发送路由协议消息。
其中,前三个部分一般以硬件实现(因为软件处理速度跟不上链路上包到达的速度,纳秒级的到达速度),路由处理器一般由软件实现,对处理速度要求不高,因为路由协议的处理一般是毫秒或秒级的。
由于需要转发,转发之前就一定要根据到达的IP包中的信息进行处理,决定输出端口,而一般情况下有这两种决定方式:
- 基于目的地的转发。通过检查IP包的目的IP地址,决定对应的输出端口。
- 一般化转发。一般化转发的思想是检查IP包的任意的信息,而后决定对应的输出端口。当然,对于每个IP包检查的信息是一致的,只不过不局限于目的IP地址而已。
4.2.1 输入端口处理和基于目的地的转发
输入端口有如下作用:
- 终止物理连接,使得物理链路上传输的bit流进入路由器
- 进行链路层包解析,提取出网络层包
- 根据网络层的包结构进行转发,如果是控制消息包,比如路由协议的包,就转发给路由处理器,如果是数据包,就查询转发表并发到对应的输出端口上
而对于基于目的地的转发,查询转发表的方式就是最长前缀匹配:
对于一个目的IP地址A,转发表中有许多<字符串,端口号>对,将A与这些字符串进行匹配,匹配时仅仅使用A的前缀进行匹配,在所有匹配的字符串中,寻找最长的字符串,其对应的端口号就是输出端口号。
4.2.2 交换(Switching)
交换是指Switching Fabric将来自输入端口的IP包转交给输出端口的过程。
常见的交换方式有如下几种:
- 基于主存的交换
- 输入端口将到达的IP包写入主存,而后再从主存中读到输出端口上完成转发
- 基于总线的交换
- 输入端口给到达的IP包打上标签,发送到总线上,只有对应标签的输出端口会接受这个IP包
- 基于交叉网络的交换
- 多个端口对应多个总线的交叉网络
4.2.3 输出端口处理
输出端口需要取出从输入端口转发来的IP包,进行链路层封装后,转发出去。
4.2.4 排队情境会在哪里出现
输入排队:如果Switching Fabric转发的速度比所有输入端口的IP包到达的速度要慢的话,就会在输入端口出现排队现象。
同时,排队时会出现行首阻塞(head of line blocking)的现象,也就是说对于一个输入端口上的队列,如果队首的包被阻塞,那么根据先进先出原则,即便后面的包所对应的输出端口没有被占用,也必须等待队首先被取出才行。这会极大降低转发效率。
输出排队:如果Switching Fabric转发的速度比输出端口的处理速度还要快的话,就会在输出端口出现排队现象。
4.2.5 Packet Scheduling 包调度
包调度是指在一个输出端口的缓冲区上决定下面转发哪一个包。
先进先出调度:简单,就是先到达的包先调度处理
优先级调度排队:在包到达时,会先将包分类,不同的类有不同的优先级,也有自己的队列,取包时先从高优先级的队列中取。相同队列中的包一般以先进先出的方式处理。
优先级调度通常用在比如:
- 网络控制包(比如路由协议包) 优先于 用户数据包
- 实时性数据包(比如实时视频会议数据) 优先于 普通数据(比如电子邮件)
轮询和权值轮询:在包到达时,先将包分类,不同的类有自己的队列,每次取包时,轮流从不同的队列中取。我们也可以为每个队列加上权值,权值高的每次多取几个包再转移到下一个队列中去取包。
4.3 IP协议,IP地址,IPv4,IPv6
4.3.1 IPv4包格式
IPv4包头有如下的域:
- 版本号。IPv4或者IPv6
- 包头长度。由于IPv4包头有可选的域,于是需要说明一下包头长度
- 服务类型(Type of Service)。可以将比如实时性数据包和非实时性数据包区分开来。如何设置由路由器管理者决定。
- 包长度。
- Identifier, flags, fragmentation offset.这三者用来处理IP包的分段
- Time-to-live. 这个域用于确保IP包不会在网络中永久循环传播,每次经过一跳,就会减一,直到成为0,路由器就会直接丢弃该IP包。
- 上层协议。一般IP包到达目的地,才会通过这个域决定IP包中的数据交给哪个上层协议。类似于传输层的端口号决定传给哪个应用进程。
- 包头校验和。用于错误检查。注意,每一跳上,由于Time-to-live会改变,所以校验和也必须重新计算。
- 源IP地址,目的IP地址
- 可选项
4.3.2 IPv4包分段
由于链路层对于最大可传送的链路层包大小有限制,所以一个IP包未必能完整的组成一个整包进行发送,就需要用到IPv4包分段。
包分段主要涉及到包头Identifier, flags, fragmentation offset三个域:
- identifier 用于标示所在的原始包,也就是说,拥有相同identifier的片段是属于相同的原始IP包的
- flags 包括两个flag
- 一个用于标示是否允许IP协议进行分段
- 另一个用于标示该分段是否是最后一段,0表示最后一段,1表示不是最后一段
- fragmentation offset用于表示该分段的数据在原数据中的偏移,以八字节为单位
- 比如fragmentation offset是20,就说明这个片段里的第一个字节的数据已经是原数据里第161字节的数据了,前面有160个字节的数据在别的分段里
4.3.3 IPv4地址
IPv4地址为32位的二进制数。
一般情况下,IPv4被表示为a.b.c.d的形式,其中,a,b,c,d是IPv4地址中第1,2,3,4个字节的十进制表示。
由于因特网被分成了各个不同的子网,所以对于每一个IPv4地址,都可以将它分为两部分,第一部分是网络地址部分,代表了该IP地址所在的网络,第二部分是主机地址部分,代表了IP地址在网络中的标识符。
现在的网络-主机地址划分方法为CIDR(Classless Interdomain Routing),也就是以32位地址的前x位作为网络地址,剩下的32-x位是主机地址,记作a.b.c.d/x。
特殊的IP地址:255.255.255.255,该地址为特定的广播地址,只要向该地址发送IP包,路由器会自动将包发送到当前子网下的所有主机上,甚至有可能发送到子网外的主机上。
获取子网IP地址
想要获取子网的IP地址,必须向上一级的IP地址管理者发出申请并由上一级进行分配。
获取主机IP地址
主机的IP地址可以手动分配,也可以使用DHCP(Dynamic Host Configuration Protocol)进行分配。
DHCP
想要DHCP正常工作,子网内必须有一个DHCP服务器,当一个新到来的主机想要获得IP地址时,过程如下:
- 主机尝试发现DHCP服务器。
- 由于新来的主机既不清楚自己的IP地址,也不清楚DHCP服务器的IP地址,所以主机以0.0.0.0的源IP地址向广播端口255.255.255.255发送一条探测消息,固定端口号为67
- 在这条消息里会包含一个事务ID
- DHCP服务器给出IP地址。
- 同样,由于DHCP服务器暂时无法确定主机的IP地址,它需要向255.255.255.255发送消息。
- 这条消息里包含了提供的IP地址,该地址的有效时间,自身DHCP服务器的IP地址,主机传来的事务ID。
- DHCP Request。
- 新来的主机可能会从多个DHCP服务器中获得提供的IP地址,它需要选择一个,然后发送DHCP Request Message,此时还不确定能不能真的拿到该IP,所以仍然需要0.0.0.0到255.255.255.255发送Request
- 这个Request消息里会包含被选中的IP地址,那么对应的服务器就知道新来的主机选择了自己提供的IP
- DHCP ACK。
- DHCP服务器接收到新来主机的Request Message之后,发出DHCP ACK,确认已经配置好了。此时仍然需要向255.255.255.255发送ACK。
4.3.4 Network Address Translation(NAT)
在IP地址中,有一类地址被保留下来作为私有地址,10.0.0.0/8就是其中一类。
所谓私有地址就是指该地址只在当前所在的子网中有意义,一旦考虑外部网络,该地址就没有意义。
那么当私有地址的主机尝试和外界通讯时,需要将私有地址转化为公开地址,这就是NAT的作用。
NAT通过如下几点来进行私有地址到公开地址的转化:
- NAT由一个路由器来进行操作
- NAT路由器拥有一个公开的IP地址,假设为X
- NAT路由器中维护了一张<端口号, <私有IP,端口号>>的表,也就是说子网中的<私有IP地址, 端口号>对应到了<统一的公开IP地址, 端口号>上
- 当子网内的主机尝试向外发送包,源地址就从<私有IP地址, 端口号>被NAT转化为<统一的公开IP地址, 端口号>,同样,当外部网络发送包到NAT时,NAT将目的地址转化为<私有IP地址, 端口号>而后发给对应主机。
NAT的使用备受争议:
- NAT打破了因特网中的分层原则,同时使用传输层和网络层来修改地址和端口号。
- NAT将许多主机隐藏在了一个路由器后面,将原本用于定位应用进程的端口号用于定位主机,那么有一些专用的端口号比如服务器的80端口就会受到影响(事实上很少将服务器放置在NAT后面)
4.3.5 IPv6
由于32位IPv4地址会被用尽,所以新的IPv6进入了开发阶段,虽然距离IPv4地址真正用尽还有一定的时间,但是想要部署IPv6,也同样需要大量的时间。
相比于IPv4,IPv6有如下特性:
- 扩展的地址空间。
- IPv6地址为128位地址
- IPv6地址除了支持IPv4中的单播,广播,还支持组播(即向固定的一组IP地址进行发包)
- 定长的40字节包头
- 除去了IPv4包头里的可选项
- 定长包头更加易于处理,路由更快
- 流标签
- 类似于IPv4中的Type of Service,IPv6使用流来区别不同的包
- 流标签用来区别不同的流
IPv6 包头格式
IPv6包头中包含了:
- 版本(IPv4 or IPv6)
- 等级(Traffic Class),用于给包赋予优先级,可以是根据流来赋予,也可以根据源应用来赋予
- 流标签(Flow Label),用于标示一个流
- 负载长度(Payload Length),由于包头定长,所以只记录了携带数据的长度
- 下一包头(Next Header),也就是类似于IPv4中的协议,用于标示上一层使用的协议(TCP,UDP, etc.),或者指向可选项
- 跳限制(Hop Limit),类似于IPv4中的Time-to-live,减小到零,直接丢弃
- 源地址和目的地址
可以从IPv6的包头中看到,有一部分功能被删除了:
- 分片/重组
- IPv6的IP包如果由于过大不能在链路层上传输,路由器会返回一个Packet too big的ICMP消息,而不是像IPv4一样进行分片
- 如果要分片,就是在收到ICMP消息后在终端主机上进行分片
- 加快了路由的速度
- 校验和
- 由于传输层和链路层都有校验机制,所以在网络层就不再设置校验机制
- 加快了路由速度
- 可选项
- 使用Next Header进行指向而不是放在包头内
- 定长的包头,更易处理
IPv4到IPv6
如果想要从IPv4转变到IPv6,我们新建的IPv6路由器可以兼容IPv4的IP包路由,但是以往的IPv4路由器想要兼容IPv6就会比较困难。
我们可以使用隧道(tunneling)的方式解决这个问题。
也就是说,将两个IPv6的路由/主机之间的IPv4路由视作链路层协议而不是同等的网络层协议,当需要发送IPv6包时,将其包裹在一个IPv4包中发出,到达终点后解开IPv4包,提取出IPv6包。