当前位置:科技动态 > IP:互联网上的

IP:互联网上的

  • 发布:2023-10-05 13:48

链接,而不是直接链接到

在前面的《听说你很懂 DNS?》中,我们分析了用户在浏览器中输入www.sychzs.cn后,浏览器如何通过DNS解析获取IP地址,然后请求该IP地址来获取网站内容。

本文接下来会讲浏览器向目标主机(IP地址)发送的数据是如何经过网络上的种种磨难到达目的地的。

我们现在所说的网络一般指的是Internet(互联网)。互联网是一种网络架构模型。除了互联网之外,世界上还有其他网络架构,例如ATM、帧中继等,地球上目前使用的互联网就是基于互联网架构的。

在互联网中,每个联网设备在整个网络中都有一个唯一的标识,称为IP地址(简称IP)。有了IP地址,两台主机(电脑、手机等联网设备)就可以通过网络进行通信。 :

上图中,我们直接在两台电脑之间拉一根网线,两端直接相连。如果土豆还想和白菜通信,他就得再和白菜拉一根电缆——也就是说,你的主机要和百度、新浪、腾讯、阿里巴巴……各自拉一根电缆才能通信。这显然是不可能的。现实。

所以现实中主机之间的通信并不是直接相连的,而是通过很多中转站进行转发。这就像在淘宝上买一袋饼干一样。快递公司不能从商家直接飞到你楼下。相反,它通过各个中转站转发。例如,首先从商户所在的街道网点发送。城市中转站再从市区发往华北配送中心,再发往华中配送中心,再配送至各区域网点。最后,快递员会骑着摩托车送到你家。

所以,我们的网络如下所示:

主机之间不直接相连,而是通过中转设备交换数据。我们称这种传输设备为router(路由器)。

(路由:指路径,表示从从某个地方到某个地方,路线是指通过某条路径到达某个地方,路径经过的公交站称为 路由器)

如果主机A要向主机B发送数据,需要通过路由器A进行中继;如果发送到主机D,则需要经过路由器A和路由器B中继两次——这里需要多次中继。计算机中有一个术语叫Hop(hop,英文意思是用一只脚跳跃,从路由器的一侧“跳”到另一侧)。从主机 A 到主机 B 需要 1 跳,到主机 D 需要 2 跳。

我们看从主机A到主机D的路径,这条路径通过路由器A和路由器B相连,整个路径就像一条链条,所以在这条路径上称为pair。节点之间的线称为 链接 。上述路径由三条链路组成:主机A-路由器A、路由器A-路由器B、路由器B-主机D。

在继续深入研究细节之前,我们需要先了解一下网络的分层架构设计。

网络分层架构

现实生活中的例子:

一般第一次坐飞机的人都会有点困惑(别问我怎么知道的!)。比如,他们拉着小车,拖着一百公斤的行李四处走动,随便找一个看起来像门的地方(比如国内到达口?)就潜入了,仿佛进入了一个荒无人烟的地方——然后自然而然地就被推到了那里。安全地面。

路线这样的高端复杂系统,其流程比公共交通要多得多。你的飞行过程大致是这样的:

你不会在一个地方完成所有事情(售票、行李、登机等),而是在不同的值机点完成部分工作,并且按照上图中箭头的顺序进行,在传入和传出方向上。服务点是对应的(入口先做的,出口最后做的,入口最后做的,对应出口先做的)。各个部分串在一起形成您的旅程。

互联网也是一个如此复杂的系统。应用程序需要交换各种格式的数据,并确保数据能够正确、及时、安全地传输到目的地。这个过程涉及非常复杂和异构的过程。技术问题也必须通过这种分工来落实。具体做法是,从逻辑上把它们分成几个层次,每一层只处理特定的事情。

我们把每一层做事的规则称为协议(行李托运、登机、起飞等都有自己的规则和规定)。每一层都有自己的一套协议(可能不止一种协议,(比如不同的终端可能有不同的登机流程)。所有层的协议放在一起就称为协议栈——之所以如此称为栈是可以看上面的飞行过程以及两边进程的对应关系,正是LIFO,即整个操作满足栈的特性(对于例如,上图左边的出发过程的最后一个程序是运行起飞,而右边的到达过程的第一个程序是跑道降落)。

OSI 模型和 TCP/IP 堆栈:

大学里著名的OSI七层模型你一定学过:

OSI七层网络模型

然后你用wireshark等工具研究了半天,也找不到会话层和表示层在哪里。

你需要知道的是,这个OSI模型是为所有(也就是抽象的)网络设计的,而不是为互联网设计的(其实设计之初并没有考虑互联网)——所以这个东西是对于我们来说理论意义大于现实意义。

互联网使用的分层模型称为TCP/IP协议栈。它是一个五层模型:

TCP/IP协议栈五层模型

我们来分析一下这五层的用途:

  • 首先,通信双方需要针对特定​​的应用场景以特定的格式传输数据。数据格式由应用层协议规定;
  • 这些数据需要通过物理实体(光纤、铜线、网卡等)从源一步步传输到目的地。 物理层涉及这些比特的物理传输;
  • 如前所述,源和目的地不是通过电缆直接连接,而是通过路由器进行转发。那么如何在两个节点(链路)之间传输数据是链路层要处理的事情;
  • 当数据通过链路层传输到中转站路由器时,路由器需要使用一定的规则(协议)来决定接下来要发送到哪条链路(走哪个出口)并完成转发——由网络层负责“路由查找”工作(具体工作规定为IP协议路由协议);
  • 数据传输是由前面的物理层(实际物理传输介质)、链路层(两个节点之间的传输规则)和网络层(寻路)完成的。然而,互联网的这三层虽然可以传输数据,但是并不可靠(其他网络模型如ATM的CBR模型可以保证网络层数据的可靠传输,但是互联网的设计原则是让网络本身更简单,所以还没有在这三层提供可靠性保证),无法保证数据能够准确、及时、安全地传送到目的地——例如,如果路由器队列已满,后续数据将被丢弃(并且不会给出任何通知),TTL已经用完(路由选择出现问题,数据在网络中丢失)也会被丢弃。互联网的原则是保持网络本身简单,并在终端系统(源主机和目标主机)上实现这种复杂的可靠性保证。 传输层用于保证数据可靠性(保证送达、流量控制)——当然,如果应用本身出于性能考虑不需要这一层可靠性保证,则不需要做。互联网传输层使用的协议是 TCP 和 UDP。

可以看出,五层中最底层的四层是为了第五层数据的可靠传输而设计的。下一层是在上一层的基础上工作的;最底层的三层工作在整个网络的每个节点(主机和路由器)和链路上,而传输层和应用层则工作在端系统(源和目的地)。主持人)。

有人可能会问,互联网的五层协议没有OSI中的会话层和表示层。这两层不重要吗?

我们发现互联网的五层协议中,最底层的四层都是为数据传输服务的,所以我们可以将整个模型概括为两大层:应用层和传输层(包括最底层的四层) )。然而,这里两层之间实际上要做很多事情:传输层很可能对应用层数据进行分段(数据太大,无法一次传输),因此应用层必须重新组装数据收到数据后;应用层数据在传输前可能需要进行压缩,以减少网络流量的使用,因此接收后需要进行解压缩;为了安全,应用层数据在网络上传输之前可能需要加密,因此接收后需要解密;由于通信双方系统的异构性,通信双方需要就数据的某些方面达成一致,例如多字节字符的编码、值的大端表示等。

互联网的答案是:让应用层来处理这些杂事!

所以应用层协议一般都兼有会话和表示功能,比如HTTP协议中的各种头信息(包括字符编码、文本格式、是否压缩、压缩策略、安全策略等),使得双方HTTP客户端和服务器应用程序对数据的含义有很好的理解。

传输单元:

快递的运输单位称为小包,互联网借用了这个术语。不过中文翻译不叫“包”,而是叫Group(包)(是不是瞬间提升了n倍)?

每一层组都有自己特定的名称(不然每一层都称为组的话很容易混淆):

物理层不能称为严格意义上的“分组”

所以当你以后听到“TCP数据包”和“TCP段”时,不要担心它们之间的区别——根本没有区别。

网络小包和快递小包的区别在于,在快递运输中,我们经常提供小包裹,然后快递公司将其包装成大包裹——网络正好相反。在网络上,应用层提供大包(例如HTTP报文(长度可能有几十兆),如果传输层不能一次传输它们,就会被分成小包。这些包可能会被分割成小包)传输到网络层和链路层后分成更小的组。小分组。

数据包由两部分组成:标头和有效负载。在 header 中放入一些元数据,比如协议版本、加密算法、校验和、实际数据长度等;有效负载是实际数据:

整个网络分层体现在数据包结构上就像俄罗斯套娃一样:下层(如网络层)从上层(如传输层)拿到数据包后(包含包头和上层有效载荷),它添加自己的头,组成一个新的组并交给您的下属:

这么说还是比较抽象,拿个包看一下就明白了。

网络分层的操作流程:

让我们抓取一个HTTP数据包来看看实际的数据包结构:

那么这样的数据包是如何生成和使用的呢?涉及到打包和拆包的过程:

在发送端(源主机),应用层将消息(上图中橙色部分)传递给传输层;传输层收到报文后,附加上传输层的报头(上图绿色部分,包括端口、序列号等信息),这个报头和来自应用层的报文一起构成了报文段传输层的,一直延续到网络层;网络层收到报文段后,添加自己的报头(上图中蓝色部分,包括IP地址等信息),形成网络层的数据报,传递给网络层链路层;链路层拿到传输的数据后继续添加自己的头(上图红色部分,包括mac地址等信息),形成链路层,最后传输到物理层层传输介质。

以上过程就是发送端的打包过程。当接收方(路由器或目标主机)收到数据时,需要进行反向解包。

根据设备工作的层数不同,需要解包到的级别也不同。链路层设备(如链路层交换机)只需要从源数据包中提取链路层信息(mac地址),并根据该信息转发数据包——链路层以上的信息对它来说是一个黑匣子,不需要被照顾;网络层设备(如路由器)需要取出网络层报头(IP地址等信息)并据此做出相应的动作(如根据目标IP进行转发)。目的主机需要对各层进行解包,最终获得应用层报文,并根据应用层协议进行相应的处理。

注意,除了目标主机之外,其他接收者(例如路由器)也是发送者。因此,这些设备除了在收到数据包后对数据包进行解包以获得必要的信息外,还需要在转发数据包之前对数据包进行密封。例如,路由器收到数据包后,首先在链路层进行解包,得到mac信息。发现目标mac地址是自己后,再在网络层解包(因为它工作在网络层),得到IP信息。根据目的IP地址和自身的路由转发表,决定将数据包转发到某个出端口。在转发之前,首先要修改数据包的网络层头,并将TTL值减一(相应地,校验和也必须改变。如果是NAT路由器,需要经过NAT转发,源IP也必须改变)修改一下。和端口,这个我们稍后再说);然后还需要修改链路层头,更新mac地址(源mac改为自身,目标mac改为下一跳目标设备)。

整个数据传输过程中的解包,请参考下图:

图片来自《计算机网络:自顶向下方法》

在结束网络分层架构的讨论之前,你可能还有一个疑问:在拆包过程中,下层如何知道数据包应该交给哪个处理器交给上层处理?例如,网络层如何知道将数据包交给TCP处理器还是UDP处理器?

因此,每层协议的头部都包含一个指向上层协议的“指针”,如图:

说完了网络分层架构,我们重点来说一下网络层

路由器

我们一开始就说过,互联网上的主机并不是直接相连的,而是通过许多路由器形成一条链式路径(因此两个节点之间的线路称为link,负责两个细节)节点之间的通信称为链路层)。这里的核心设备是路由器

路由器是网络层数据包交换机。所谓数据包交换机,是指按照一定的路由规则转发数据包(如果你现在还对“数据包”这个名字感到不舒服,那么你就认为它是快递包)的设备,让数据包从一个链接到另一个。路,终于到达目的地。为了进行转发,交换机必须依赖源数据包的某些信息,并查找自己的转发表来决定将数据包发送到哪个出口 - 网络层数据包交换机参考这张转发表(转发规则)基于网络层信息,特别是IP(记住我们谈论的是互联网,其他网络模型不一定是IP)。

路由器所做的核心工作是根据源数据包的目标 IP 将源数据包转发到适当的传出链路。

路由器的原理大致如下:

图片来自《计算机网络:自顶向下方法》

路由器主要由输入端口、输出端口、交换结构和路由处理器四部分组成。

数据包首先从输入端口进入。输入端口取出网络层头,获取目的IP,根据IP查找自己的路由转发表,决定将数据包交给哪个输出端口,然后将数据包放入到交换结构的相应位置,交换结构实际上将数据包发送到相应的输出端口

上面提到的转发表是由路由处理器(普通CPU加相关软件)计算出来的。处理器根据相关的路由算法计算出本路由器的转发表,并将其复制到每个输入端口,输入端口根据这张表进行数据包转发。

转发表本质上是IP到网络端口的映射,大致如下(对于Linux使用route -n,对于Mac使用netstat -nr):

以上是我本机的路由转发表。有两张网卡(Netif字段):en0(物理网卡)和tap0(虚拟网卡,用于与公司的VPN连接)。你会发现转发表的大部分IP列(第一列)都不是完整的IP,而是前缀。转发表的匹配策略为最长前缀匹配。上面定义了两个默认策略(当所有IP前缀都无法匹配时使用该策略)。两者中,首先使用tap0(即VPN)。根据上面的配置,当我访问大多数外部服务时,我使用的是VPN网络。上面有一个14的规则,表示14开头的IP都去en0。

需要注意的是,路由器的处理单位是数据包(数据报),物理层数据是以比特为单位传输的。通常,数据报的所有位不会同时到达路由器输入端口。此时,路由器需要等待数据包的所有位都到达后才能开始处理数据包(而不是在第一个位到达后才进行处理),因此存在延迟。另外,路由器解包、查表、转发也需要时间(虽然这些时间一般以纳秒为单位),所以数据每次经过路由器时,都不可避免地产生网络延迟——如何优化路由算法来减少数据包通过的时间?路由器的数量以及优化路由器本身的处理性能是网络层需要解决的核心问题。

此外,如果路由器的处理性能跟不上,数据包的到达速度大于路由器的转发速度,数据包就会堆积在等待处理的队列中。当队列已满时,后续的数据包将被丢弃。这就是我们常说的丢包。由于Internet的网络层不提供可靠性保证,路由器会直接丢弃数据包而不通知发送者。因此,为了获得传输的可靠性,必须在上层(如传输层)实现相关的保障机制。

IP

IP协议:

IPv4 数据报大致如下所示:

虽然只有20个字节,但是内容还是相当复杂的。

有4位记录头长度——也就是说,IPv4头长度不是固定的!问题出在“服务类型”上,因为某些服务类型有额外的 4 字节扩展信息。

与分片相关的部分有3个部分 - 当出局链路的MTU(最大传输单元)不足以容纳整个数据包时,数据包将被分成多个小数据包发送,因此最终这些将必须被削减。划分后的组被整合到原来的大组中,因此附加信息(标识、组偏移等)必须记录在这些组中。

TTL是IP数据报的生存期。该值在发送端设置,然后每经过路由器就减1。当值为0时,直接丢弃——如果没有这个东西,如果一个数据包在网络中迷失了,那么你就会成为一个孤独的幽灵,整天在互联网上徘徊(无休止的转发) 。

如前所述,上层协议表示数据报到达目的主机后应交给哪个上层协议处理器进行处理。这里交给TCP处理。

头校验和是按照一定算法生成的值,用于防止头信息被篡改。由于每个路由器都会修改 TTL 值,因此也必须重新计算校验和。

由于历史原因,IPv4的设计存在两大问题:

  1. 不适合路由器。首先,报头的长度不固定,这使得路由器无法优化这方面的性能。必须先从header中获取长度,然后取出完整的header;然后里面有一个校验和,每次经过路由器时TTL都会改变。 ,这需要每个路由器重新计算报头校验和。像路由器这样对性能要求极其苛刻的设备(不是说家里只服务两三个人的路由器,而是骨干网上的路由器)不适合做这些事情。
  2. IP地址数量严重不足。 IPv4只有4个字节,相当于超过40亿个地址,这对于互联网爆炸式增长的今天来说是小得可怜。

当然,我们不能事后评论 20 世纪 80 年代初设计的东西,当时网络流量以字节为单位,而且网络仅用于军事和科学研究。当时的设计者可能从未想到互联网会在全球范围内使用。相比性能,他们可能更多地考虑带宽(因此IP地址只有4个字节,报头也是变长的,数据包受不同链路的MTU限制)。能力,必须进一步划分)。

IPv6针对这些问题进行了优化,其设计原则是性能高于一切

IPv6使用40字节的固定长度报头,以便路由器可以进行相应的优化。

IPv6 也不支持分段。如果某个链路不支持这么大的数据包,则会直接向发送方返回错误,并发送较小的数据包。

IPv6不计算校验和,数据的准确性留给上层来保证。

这样,IPv6的40字节定长头中,32字节是源IP和目的IP,只用8字节来记录其他信息。

分类寻址和 CIDR:

IPv4地址长度为4字节,十进制范围为0.0.0.0到255.255.255.255。 IP 地址由 网络地址 + 主机地址 组成。在最初的设计中,IP地址被分为A、B、C等几类。A、B、C这三类代表了地址中哪些部分是网络地址,哪些部分是主机地址。 A类地址规定IP的第一部分是网络地址,接下来的三部分构成主机地址,第一部分的最高位必须为0; B类地址的前两部分是网络地址,后两部分是主机地址,并且最高位两位必须是10; C类地址的前三部分是网络地址,最后一部分是主机地址,最高三位必须是110。如图:

将IP地址分为网络部分和主机部分是一个好主意。它引入了子网的概念,使得路由选择具有层次性。路由器计算转发策略时,只需将数据包转发到整个子网(具体是转发到该子网的网关路由器),而不关心目的主机在子网中的哪个位置;数据包到达子网后,由子网内的路由器进一步转发。

这就好像你想去深圳南山区大学城,你先从北京坐飞机到深圳,然后去南山区,最后找到南山区大学城的位置,而不是从一开始就锁定特定位置。地点。

但是,这种IP分类方式带来了很大的问题,会造成大量的IP浪费。我们来看看A类地址。网络部分有 2^7 - 2 = 126 个(之所以减 2 是因为全 0、全 1 都是特殊地址),主机部分有 2^24 - 2 = 16,777,214 。这是什么意思? A类地址总共只能分配给126个组织,每个组织最多可以拥有1600万台主机!一般教科书都会说“A类地址一般用于主机数量较多的大型网络”之类的废话。问题是,这仅有的126个地址该分配给谁呢?这不是一个技术问题,而更可能是一个政治问题。

我们看一下C类,这一类地址总共可以有2^21 - 2 = 2,097,150个网络地址(超过200万个),而每个网络地址(网段)只能有2^8个- 2 = 254 台主机!如果你走到街上,闭着眼睛指着一家公司,很可能就会超过这个数字。当然,你可能认为C类地址少也没关系。 NAT不适合内网传播吗?问题是为什么分配到 A 类的组织不能玩 NAT?

所以从目前来看,IP地址的这种分类是极其不合理的。 A类和B类会造成大量浪费,而C类则远远不够。

所以,这种分类寻址方式很早就被送进了博物馆,现在全世界都采用一种分配策略,叫做Classless Interdomain Routing(Classless Interdomain Routing,CIDR)。这个名字很混乱,强调它是一种无类别的分配方法。简单理解就是它仍然继承了分类方法的思想,即将IP地址分为两部分:网段和主机段;但是不再局限于以点(.)来划分网段和主机段,可以用任意的每一位来表示网段,而主机段不仅仅是一台主机,还可以是进一步划分为子网。

子网

看下图:

图中有两台路由器连接8台主机,路由器之间有连接。

此图总共显示了 4 个子网,它们使用适当的 IP 前缀 作为子网标识符。

最左边的三台主机均以220.1.1开头,我们记录为220.1.1.0/24。这里的24称为子网掩码,代表IP中的高位24位。子网地址(网段)。子网内所有主机的IP地址均以此子网地址开头。同样,右边的子网地址是220.1.2,下面的两台机器是220.1.3。

上面的路由器有三个网口,其中两个网口分别连接到两个子网,第三个连接到另一台路由器,而这两个路由器也组成了一个独立的子网220.1.8.0/24。

现在我们看看主机220.1.1.2(以下简称主机A)如何向主机220.1.3.20(以下简称主机B)发送消息。

从上图可以看出,两台主机处于不同的子网,经过两个路由器(两跳)。首先,主机A查找自己的路由表(它的路由表不需要有220.1.3.0/24网段的单独转发记录,它直接到默认网关路由器),发现它要发送数据包发送至其自己的网关路由器 220.1。 1.1(以下简称路由器A)。

Router A 的转发表会有类似如下的转发规则(假设 Router A 下面通过网口 if1 连接到 Router B):

RouterA 获取数据报头中的目标 IP 信息并查找转发表后,将报文转发到网口 if1(IP 地址为 220.1.8.1),然后通过网络端口(具体来说,指定网络端口 if2)。

路由器B拿到组后,查找自己的转发表,发现需要转发到网口if3(假设路由器下面220.1.3.1对应的网口称为if3),于是该组进入目标子网,然后通过子网内部通信机制最终传输到目标主机220.1.3.20。

现在有一个问题。路由器A如何知道220.1.3.0/24的数据包需要通过网口if1转发给路由器B(即路由器A中的转发表记录是如何写的)?

可以由网管手动写入,也可以由路由协议自动计算(记住路由器中有一个路由处理器)。 Router B 负责子网 220.1.3.0/24,但其他路由器并不知道这一点,因此 Router B(通过网络端口 if2)不得不大声宣布:“请将 220.1.3.0/24 的所有数据报发送给我!” ”

子网分层和地址聚合:

查看上面的子网220.1.3.0/24。你认为这是C类地址吗?

如果是120.1.3.0/24怎么办?注意,在分类寻址中,120属于A类地址(A类的范围是1-126)。既然是A类地址,为什么要用24位作为网段呢?

前面说过,分类寻址方式在博物馆里已经存在很长时间了。现在世界上使用的是CIDR。这是一种无类寻址方法,所以不要再考虑ABC了。

还有一个问题是,120.1.3.0/24中正确的8位是否一定只用于主机?

答案是否定的。

子网可以是分层的。子网可以进一步划分为子网。事实上,120.1.3.0/24并不是一级网络。属于更大的子网如120.1.0.0/16(具体划分取决于ISP本身)。整个网络是如下的树形结构:

例如,我们继续对120.1.3.0/24进行子网划分,将后8位的前4位作为子网地址,后4位作为主机地址。这样的子网可以容纳 2^4 - 2 = 14 台主机:

注意上面的 128(二进制:10000000)、192(二进制:11000000)和 224(二进制:11100000)都属于网络段。当然这些子网也可以通过多个路由器形成更复杂的网络拓扑。

这种子网分层使得一个路由器的出口不一定是指向某台主机,而是指向一个网段(该子网的网关路由器),这个网段(子网)是对一批 IP 地址的聚合。

自治系统(Autonomous System,AS)

有上百万上图那种子网分布在世界各地,要想让这些子网(其内部的主机)之间无障碍地通信,子网网关(路由器)需要进行复杂的路由计算,它必须记录到任何一个子网应该怎么走,这不但要求全世界所有的路由器都必须使用同样的路由选择算法,而且会导致路由器的转发表非常庞大。

就像公司会通过增加部门等组织结构来应对人员规模,因特网也通过对这些路由器本身进行组织化来应对规模复杂性。前面说同一个网段的主机可形成一个子网,这些主机之间可以直接通信,但无法直接跟子网外部通信,跟外部通信是通过网关路由器来实现的。类似地,我们将一群路由器(这些路由器一般属于同一个 ISP 或公司)组织在一起形成一个自治系统,这些路由器之间可直接通信,而且都知道自己到任何其他路由器的最短路径,但这些路由器不能跟自治系统外部的路由器通信,他们必须通过指定的一台或几台网关路由器和外面的路由器通信。同样,外面的那些路由器也是被组织进其它的自治系统中,所以这种通信实际上是自治系统之间的通信。

如图有 3 个自治系统,其中 AS1 有两个网关路由器 1d 和 1c,AS2 的网关路由器是 2c,AS3 的是 3c。自治系统内部的路由器之间直接或间接相连,都知道彼此通信的路径。现在假如 1b 子网的主机要和 3b子网的主机通信,则 1b 查找自己的路由表,发现目标在本 AS 外面,需要将分组交给网关路由器 1c,1c 查找自己的转发表后将分组发给 3c,最后由 3c 转给 3b。

这样 1b 就不用关心 3b 到底位于 AS3 中的哪个位置,直接把分组甩给网关,网关再甩给对面的网关就行了。

同样,如果 AS2 中的 2b 要和 AS3 中的 3b 通信,则需要通过 AS1 转发。

这里有个问题,AS1 有两个网关出口,上面说的 1b 怎么知道应该把分组转给网关 1c 而不是 1d 呢?

这就涉及到自治系统之间的路由选择。全世界所有自治系统间都运行同样的路由选择算法 BGP(Broder Gateway Protocol,边界网关协议), 通过该算法,全世界的自治系统之间就能知道如何到达任何一个其他自治系统了,BGP 算法本身很复杂,大致意思是这样的:

  1. AS3 告诉邻居 AS1:通过我可以到 220.1.0.0/16(这个地址段就是 AS3 管理的);

  2. AS1 的网关路由器收到消息后,广播给本 AS 内部所有路由器:通过我(AS1 的网关 1c)可以到 220.1.0.0/16;

  3. 于是这些路由器便在自己的转发表里面记录一条转发策略,我们拿 1b 为例:假设 1b 到 1c 的最短路径是 1b -> 1a -> 1c(这是通过 AS 内部路由选择算法算出来的),其下一跳是 1a,假设 1b 通过网口 if1 和 1a 相连,则 1b 会在其转发表中记录:

    220.1.0.0/16 -> if1

  4. AS1 的另一个网关路由器 1d 当然也收到了这条消息,它在自己的转发表中记录一条转发策略后,还会将这条消息告诉其邻居 AS2:通过我(AS1)可以到达 220.1.0.0/16;

  5. 于是 AS2 内部也重复上面的步骤;

当然实际算法会复杂很多,比如如何选择 AS3 间的最短路径等。

一个 ISP(如中国移动) 或公司(如阿里云)往往会有多个自治系统,每个自治系统需要向相关注册机构(中国是 CNNIC)申请自治号(ASN),在 AS 间路由选择算法中需要用到自治号。

可以从https://www.sychzs.cn/as.php查看某个 IP 所属的自治系统信息,比如我们看看 36.152.44.96:

这个 IP 属于中国移动江苏分公司的自治系统 AS56046 管理,该自治系统对外宣告的 IP 段是 36.152.44.0/22。注意看右侧的 AS Path,它表示自治系统的“36.152.44.0/22都发给我”这条消息向外传给了哪些其它自治系统(从右往左看)。我们看看第一条的详情:

该消息从中移江苏的自治系统传播到中移总部的 AS9808,然后传播到中移香港,再到英国,最后到美国。

我们再通过 https://www.sychzs.cn/AS56046 看看这个 AS 详情:

该自治系统是在 APNIC(亚太互联网信息中心,属于区域注册机构,CNNIC 是其下属的国家注册机构。中国移动的 IP 也是由 APNIC 分配的)注册的,虽然这个 AS 是用于江苏地区,但注册公司是中国移动(而不是江苏分公司)。该 AS 一共持有 1484 个 IPv4 前缀,一共有 300 多万个 IP 地址(注意其持有的 IPv6 有多达 860 多亿!)。途中蓝色圈圈中是这些 IPv4 地址的使用分布情况。

这些是 1484 个 IPv4 前缀中的一小部分:

需要注意的是,自治系统内部以及自治系统之间的路由选择策略是不同的。自治系统内部的路径选择一般着重考虑性能,而自治系统之间的策略可能更多考虑的是商业和政治等经济、社会因素。比如联通用户访问移动网络中的服务器,只会经过联通和移动的自治系统,不可能经过电信的自治系统中转,哪怕从技术上来说这样路径更短。

IP 地址的分配

在《听说你很懂 DNS?》一文中我们已经提过,全世界的 IP 地址都是由 ICANN(Internet Corporation for Assigned Names and Numbers,互联网名称与数字地址分配机构)管理和分配的(具体是其下设机构 IANA),ICANN 将地址分配给各区域注册机构(比如亚太的 APNIC),区域注册机构再分配给国家/地区注册机构(如中国的 CNNIC),区域注册机构也可以直接分配给一些大型 ISP(如中国移动)。

目前 IANA 在全球设立五大区域注册机构:

其中 APNIC 分管亚太地区。

以下是 IANA 的地址分配情况(部分):

我们发现,IANA 的分配都是以 8 作为子网掩码,属于粗粒度分配,各区域拿到这些地址段后,会更细粒度地分配给国家/地区的注册中心。比如上面将 014/8 分配给了亚太,亚太可以再将 14.192/10 分配给中国的 CNNIC,CNNIC 再将 14.240/12 分配给阿里云等公司。

上面有个 012/8 是分配给美国贝尔实验室了,017/8 分配给苹果了,019/8 给福特了。前面说过,历史上 IP 地址曾采用分类编址法,这里面这些 8 位掩码的都属于 A 类地址(1-126 的都属于 A 类),按照当时的想法,这类地址是分配给一些大型公司的(当然也都是美国的),比如 IBM、AT&T、苹果、福特、通用等,后面很快发现这种搞法行不通,所以废弃了分类编址法,去官网看下会发现目前绝大部分的“A 类”地址还是分配给了区域注册机构。

当然所谓的“分配”并不是免费的,比如阿里云从 CNNIC 申请了 1000 多万的 IP 资源,每年需要交一笔不菲的年费给 CNNIC。跟域名一样,这也是一块肥水。

另外我们特别看下 47.106.193.19 这个 IP 地址,看其 47 开头,查找 IANA 官网发现它归属北美的 ARIN,但查一下该 IP 的 whois 信息发现该 IP 是阿里巴巴(阿里云)的——难道阿里云不是从 CNNIC 申请地址,跑到美国找 ARIN 了?

我们看下 whois:

$ whois 47.106.193.19
......
refer:        www.sychzs.cn
inetnum:      47.0.0.0 - 47.255.255.255
organisation: Administered by ARIN
status:       LEGACY
whois:        www.sychzs.cn
changed:      1991-01
source:       IANA
# www.sychzs.cn
NetRange:       47.98.0.0 - 47.112.255.255
CIDR:           47.104.0.0/13, 47.112.0.0/16, 47.100.0.0/14, 47.98.0.0/15
NetName:        APNIC
......
Organization:   Asia Pacific Network Information Centre (APNIC)
RegDate:        2015-04-01
......
% Abuse contact for '47.104.0.0 - 47.111.255.255' is 'support@www.sychzs.cn'
inetnum:        47.104.0.0 - 47.111.255.255
netname:        ALISOFT
descr:          Aliyun Computing Co., LTD
......
source:         APNIC
irt:            IRT-CNNIC-CN
......
% Information related to '47.104.0.0/13AS37963'
route:          47.104.0.0/13
descr:          Hangzhou Alibaba Advertising Co.,Ltd.
country:        CN
origin:         AS37963
......

信息很长,做了截取。可以看出,在 1991 年 IANA 将 47/8 分配给了 ARIN,ARIN 在 2015 年将其中的网段 47.104.0.0/13, 47.112.0.0/16, 47.100.0.0/14, 47.98.0.0/15 转给了 APNIC,APNIC 将其中的某些网段分配给了 CNNIC,阿里云从 CNNIC 申请了 47.104.0.0/13 这段地址。

内网与 NAT 技术

IPv4 面临的一个严峻问题是地址资源枯竭,虽然上世纪 90 年代 IETF 就开始研发 IPv6,但由于网络层设施涉及到整个网络的所有结点(而不仅仅是端系统),其升级替换的工程量浩大,至今仍未普及。

一个替代方案是采用可复用的私有 IP。和公有 IP 全球唯一性不同,私有 IP 仅在某个范围(局域网)内是唯一的,出了这个范围,不能保证其唯一性。

ICANN 为A、B、C 三类地址各保留了一个私有 IP 段,分别是:10.0.0.0/8、172.16.0.0/12、192.168.0.0/16。

注意到 172/8 号段在 1993 年分配给 ARIN(美国互联网号码注册中心) 了,而 172.16 私网是在 1996 年的RFC1918中定义的,也就是说这段号码是后面从 ARIN 中收回的。

我们现在无论是在家庭还是公司中基本都是用的私有 IP,大致是这样:

一个问题是,既然内网的 IP 地址不是全球唯一的,无法在公网上使用,那当我通过浏览器在内网访问百度服务器,百度服务器的数据是怎么找到我的内网这台电脑的呢?

内网和公网的通信需要用到叫做 NAT(Network Address Translation,网络地址转换)的技术。NAT 的原理是,NAT 路由器的两块网卡,一块连接内网,使用内网 IP,一块连接外网,使用外网 IP。路由器接收到内网主机发送的分组后,取出分组首部的 IP 信息,将其中的源 IP(内网 IP,上面的 192.168.1.10)替换成自己的外网 IP(138.20.11.10),并且生成一个该路由器尚未使用的新端口号(上面的 4590)替换掉源端口号(3000),用这个新的 IP 和端口号替换掉分组中的源 IP 和端口,然后转发出去。同时,路由器将内网的 IP+端口号与新的外网 IP+端口号的映射关系记录到 NAT 转发表中。

目标服务器(如百度)接收到分组后,取出首部一看,该分组是 138.20.11.10 发来的,即它认为是那个路由器发的,而不知道其实是路由器后面的局域网主机发的。服务器返回的分组的目标 IP 和端口自然是 138.20.11.10 和 4590,该分组自然会被上面那个 NAT 路由器收到。NAT 路由器从外网收到分组后,拿到目标 IP 和端口号,去 NAT 转换表查,发现对应的内网 IP 和端口是 192.168.1.10 和 3000,于是修改分组的首部,最后通过局域网发送给目标主机。

NAT 转换表

看到这样的骚操作你是不是不由得竖起大拇指?人类的大脑终究还是聪明的,自己挖的坑自己"完美"地填平了。

别急,还有更骚的操作。

我家中使用无线路由上网,分配的局域网 IP 是 192.168.1.6,网关是 192.168.1.1。网关路由器的出口接到中国移动的路由器,我们看看那边分配的 IP:

说我的“外网” IP 是 100.64.148.126。处于好奇,我用 ip138 查了下这个 IP 的详情:

纳尼?这也是个局域网 IP?在三个私有 IP 段没见过 100 开头的啊?

于是赶紧跑到 IANA 官网查一下,在底下脚注看到这么句话:

100.64.0.0/10 reserved for Shared Address Space [RFC6598].

说是在 RFC6598 中将其定义为共享地址空间,翻开该 RFC,有这么一段话:

This document requests the allocation of an IPv4 /10 address block to be used as Shared Address Space to accommodate the needs of Carrier Grade NAT (CGN) devices. It is anticipated that Service Providers will use this Shared Address Space to number the interfaces that connect CGN devices to Customer Premises Equipment (CPE).

Shared Address Space is distinct from RFC 1918 private address space because it is intended for use on Service Provider networks.However, it may be used in a manner similar to RFC 1918 private address space on routing equipment that is able to do address translation across router interfaces when the addresses are identical on two different interfaces. Details are provided in the text of this document.

如果你跟我一样英文不好,就不要去钻研上面这么一大段话了,大致意思是 100.64.0.0/10 这个网段是专门给网络服务提供商(ISP)用的私有 IP。因为 ISP 的客户(家庭、公司)已经在使用 RFC1918 定义的三个私有 IP 段了(就是10、172.16、192.168),所以 ISP 就不能使用这三个网段做私有 IP 了——否则当你家的路由器遇到目标 IP 是 192.168.1.10 它到底是要转给内部呢还是转给 ISP 呢?

ISP 为啥也要玩局域网呢?还不是因为 IP 不够用嘛!你想中国移动、中国电信有多少客户(家庭、公司),得要多少公网 IP 才能玩得转?所以他们在局域网外再套一层局域网,于是我们和外网的通信就变成这样子:

然而,NAT 并不是一项完美的技术。

从上面图就能看出来,NAT 路由器要去修改分组首部,并维护 NAT 转换表,这多少会带来些许的网络时延,特别是在两层 NAT “加持”下。

路由器本来属于网络层设备,而端口号是放在传输层的——意味着这个网络层设备需要取出并修改传输层首部,这在设计上违背了分层原则。

局域网主机用的私有 IP,这导致它无法直接对外提供服务(想想外面的主机怎样去寻址 192.168.1.10?),因而无法直接实现 P2P。要想在这种情况下实现 P2P,需使用 NAT 穿越技术(此处不详细讨论这种技术,感兴趣的可自行百度)。另外 NAT 也限制了物联网的发展,比如你家有一台美的的电暖气,该电暖气能够联网控制,但由于电暖气位于局域网,用的是私有 IP,它无法直接和你的手机相连,必须通过美的的中央服务器中继。

可能更大的影响是,NAT 技术限制了 IPv6 的普及速度。试想如果没有 NAT 技术,每台主机想要联网就必须持有外网 IP,这种情况下全世界的 IPv4 地址早已枯竭,逼迫各大运营商和公司去实施 IPv6。而现在有了 NAT,公司可以玩内网,运营商也可以玩 NAT,钱照赚不误的情况下,谁会有动力花大财力去升级设备?公司(ISP 当然属于公司)是以盈利导向的,在当前大有盈利的情况下,傻子才去做那种短期看不到回报的大手笔投资。所以世界上 IPv6 的推进非常缓慢,即便中国在很早(上世纪 90 年代末)就开始关注 IPv6 了,但至今仍未普及。

现实中的网络

想想你家里是怎么接入互联网的。

首先你要打电话找一家电信运营商(接入 ISP,比如中国移动),他们会就近网点派人上门给你拉光纤,装个一体化路由器(光猫和路由器一体化设备),设置或者不设置一个 IP(一般是通过 ISP 的 DHCP 服务器自动获取),然后你交了钱,就能上网了。

假如你现在访问 www.sychzs.cn,电脑通过 DNS 查询获取 IP 后,请求是如何在网络上一路狂奔走到百度的某个机房的呢?

这取决于 DNS 返回的 IP 归属情况。目前大公司的权威 DNS 都有智能解析的能力,假如你是在武汉,用的移动网络,如果百度在武汉有数据中心,而且还跟移动有合作,那它多半会返回武汉移动的 IP 给你,此时你的请求不需要出城,也不需要跨运营商网络,请求进入接入 ISP (就是给你办宽带的那家)网络后,经过武汉移动的某个自治系统可能就直接到达目的地了。

假如百度在武汉没有移动数据中心,那他可能会返回一个其它城市的移动 IP 给你,比如江苏南京的移动 IP。此时你的请求进入接入 ISP 网络后,很可能通过城域网而后交换进入骨干网,然后跑到南京。具体怎么走取决于中国移动的网络基础设施的架构。

但如果返回的是百度在武汉的联通数据中心 IP 呢?此时数据报能直接从武汉移动网络进入武汉联通网络吗?很可能不能。移动和联通属于两家 ISP,如果他俩在武汉没有实现互联互通的话,数据就必须出城跑到能互联互通的那个城市(假如是广州),然后在那个城市进入联通网络,然后再跑回武汉百度的数据中心。这就是为啥 CDN 会尽量选择和客户在同一家网络的结点返回——不同家的网络,即使客户和服务器面对面站着,数据报也有可能要跑遍大半个中国。

假如我们要访问美国的某个网站呢(虽然大部分访问不了)?这就比较复杂了。首先你的数据报进入接入 ISP 的自治系统后,几番路由,进入中国移动的骨干网,然后通过某个核心节点(每家骨干网一般会在一些省会城市建设核心节点,其中一些核心节点能够通往国外)经由海底光缆传输到美国的某家运营商的核心节点(具体取决于目标 IP 归属),而后一层一层逐步路由到目的地。

整个网络从逻辑上大致是下面的等级关系:

最接近用户的是接入 ISP 网络(一般就是给你办宽带的那家),接入 ISP 会连入区域 ISP 网络,区域 ISP 网络进一步接入到第一层 ISP。区域 ISP 之间、第一层 ISP 之间一般会互联。区域 ISP 一般也会接入到多家第一层 ISP。

不过这个理论图你了解下就行了,实际中关系和概念可能都不同,每家运营商网络架构可能都不同,比如有些运营商会采用城域网-省网-骨干网的层次架构,有些则直接采用城域网-骨干网架构。

这里面有个 IXP,中文叫互联网交换中心(Internet Exchange Point),目的是让多家运营商(网络接入商 ISP、内容提供商 ICP)在这里交换数据,而不用为了从一个服务商网络进入另一个服务商网络就要绕地球大半圈——因为现实中不同运营商之间一般都是只在顶层(骨干网)互联互通。IXP 是本地化交换中心,什么意思呢,刚才说假如移动和联通在武汉没有实现互联互通,那么移动用户想要访问同一个城市的联通网络上的服务器,就得跑到遥远的地方(意味着要经过很多个路由,而每个路由转发都会带来额外时延)跨网后再跑回来,大部分时间都是在浪费生命,而采用 IXP 方案的话就是在武汉建立一个本地交换中心,各运营商之间都可以在这里直接互通。IXP 在欧美很火,但在中国一直发展不起来。和欧美 ISP 百花齐放不同,中国主要就三座大山(后面广电也进入了),各有各的利益考虑。打个比方,假如移动的网络设施比电信少很多(实际上就是少),大部分移动用户访问的网络服务都要经过电信的网络,这时候移动是要给电信钱的。搞了 IXP 后,虽然能同城跨网访问了,但 IXP 国际惯例是双方免费互通,电信愿意?所以这种事情就跟中国的携号转网一样,往往是剃头的挑子一头热,甚至两头都不热。中国曾经在政府主导下搞了北上广三个国家级交换中心,但没搞起来。这些大佬基本是通过顶层直连的方式互通。



相关文章