正如寄信需要一个地址一样,在网络世界里,同样也需要地址的概念。在 TCP/IP 协议栈中,IP 用来表示网络世界的地址。IP 网络中每台主机都有唯一的 IP 地址。IP 地址是一个 32 位的二进制序列组成。为了便于在上层应用中方便地表示 IP 地址,可以把 32 位的二进制数序列分为 4 个单元,每个单元占 8 位,然后用十进制整数来表示每个单元,这些十进制数的取值范围是 0~255。

新的 IPv6 标准将采用 128 位的地址,大大扩充了可用地址的数目。IPv6 地址通常为冒号分隔的 8 个区块,每个区块是 4 个十六进制数字

有些计算机(尤其是服务器)有固定的地址,有些计算机(特别是局域网和无线连接上的客户端)可能每次启动时会收到不同的地址,这通常由 DHCP 服务器提供的。在写代码时不要假定系统有相同的 IP 地址。

IP 报文在互联网上传输时,可能要经历多个物理网络,才能从源主机到达目标主机。由于不同硬件的物理特性不同,对数据帧的最大长度都有不同的限制,这个最大长度被称为最大传输单元(Maximum Transmission Unit,MTU)。那么在不同的物理网之间就可能需要对 IP 报文进行分片,这个工作通常由路由器负责完成。

IP 报文格式

image.png
IP 协议的结构比较简单,我们重点说下数据包的生存时间,即 TTL,它是数据包可经过的最多路由器总数。TTL初始值由源主机设置后,数据包在传输过程中每经过一个路由器 TTL 值则减 1 ,当该字段为 0 时,数据包被丢弃,并发送 ICMP 报文通知源主机,以防止源主机无休止地发送报文。

这里扩展说一下 ICMP(Internet Control Message Protocol),它是检测传输网络是否通畅、主机是否可达、路由是否可用等网络运行状态的协议。ICMP 虽然并不传输用户数据,但是对评估网络健康状态非常重要,经常使用的 ping、tracert 命令就是基于 ICMP 检测网络状态的有力工具。

上图中 TTL 右侧是挂载协议标识,用来表示 IP 数据包里放置的子数据包协议类型,比如 6 代表 TCP,17 代表UDP 等。

保留网段

通常我们所在的单位或者组织,会使用诸如 10.0.x.x 或者 192.168.x.x 这样的 IP 地址,你可能会纳闷,这样的 IP 到底代表了什么呢?不同的组织使用同样的 IP 会不会导致冲突呢?

背后的原因是这样的,国际标准组织在 IPv4 地址空间里面,专门划出了一些网段,这些网段不会用做公网上的 IP,而是仅仅保留作内部使用,我们把这些地址称作保留网段。

下表是三个保留网段,其可以容纳的计算机主机个数分别是 16777216 个、1048576 个和 65536 个。
image.png

子网掩码

在网络 IP 划分的时候,我们需要区分两个概念。

第一是网络(network)的概念,它表示的是这组 IP 共同的部分,比如在 192.168.1.1 ~ 192.168.1.255 这个区间里,它们共同的部分是 192.168.1.0。

第二是主机(host)的概念,它表示的是这组 IP 不同的部分,上面的例子中 1 ~ 255 就是不同的那些部分,表示在这个网络中有 255 个可用的不同 IP。

子网掩码用来确定 IP 地址中前几部分是网络地址,后几部分是主机地址。一般,一个 IPv4 地址的第一个,前两个或前三个字节是属于网络的一部分,上面图片中的第一行中的 10 是对应的网络字节部分,网络有 1 个字节而主机有 3 个字节,我们将一个字节的子网记作 255.0.0.0。相对的,第二行中的网络有 2 个字节,第三行中的网络有 3 个字节。

网络地址位数由子网掩码决定,你可以将 IP 地址与子网掩码进行二进制与(&)操作,就得到了网络的值。子网掩码一般看起来像是 255.255.255.0(二进制为 11111111.11111111.11111111.00000000),比如你的 IP 地址是 192.0.2.12,使用这个子网掩码时,你的网络就会是 192.0.2.12 & 255.255.255.0 的值:192.0.2.0。

子网掩码能接受任意个位,而不单纯是上面讨论的 8,16 或 24 个比特而已。所以你可以有一个子网掩码为 255.255.255.252(二进制位 11111111.11111111.11111111.11111100),这个子网掩码能切出一个 30 个位的网络以及 2 个位的主机,所以这个网络最多有四台 host,因为变化的部分只有最后两位,即 2*2=4。

注意,子网掩码的格式永远都是二进制格式:前面是一连串的 1,后面跟着一连串的 0。不过一大串的数字会有点不好用,比如像 255.192.0.0 这样的子网掩码,人们无法直观地知道有多少个 1,多少个 0,后来人们发明了新的办法,你只需要将一个斜线放在 IP 地址后面,接着用一个十进制的数字用以表示网络的位数,类似这样:192.0.2.12/30, 这样就很容易知道有 30 个 1, 2 个 0,所以主机个数为 4。

数据包发送过程

IP 协议是面向包的协议,即数据被分为若干小数据包,然后分别传输它们。IP 网络上的主机只能直接向本地网上的其他主机发送数据包。主机实际上有两个不同性质的地址:物理地址和 IP 地址。物理地址是由主机上的网卡来标识的,物理地址才是主机的真实地址。

当主机 A 向同一个网络上的另一个主机 B 发包时,主机 A 会通过地址解析协议(ARP)获得对方的物理地址,然后把包发给主机 B。ARP 协议的运行机制为,主机 A 在网络上广播一个 ARP 消息:主机 B 的物理地址是多少,接着,主机 B 就会进行响应,把自身的物理地址告诉主机 A。

当主机 A 向另一个网络上的另一个主机 B 发包时,主机 A 先利用 ARP 协议找到本地网络上的路由器的物理地址,把包转发给它。路由器会按照如下步骤处理数据包:

  • 如果数据包的生命周期已到,则该数据包被抛弃
  • 搜索路由表,优先搜索路由表中的主机,如果能找到具有目标 IP 地址的主机则将数据包发送给该主机
  • 匹配失败则继续搜索路由表,匹配同子网的路由器,如果找到匹配的路由器则将数据包转发给该路由器
  • 匹配失败则继续搜索路由表,匹配同网络的路由器,如果匹配则把数据包转发给路由器
  • 如果以上匹配操作都失败,就搜索默认路由,如果默认路由不存在,则丢弃数据包

从以上过程可以看出,IP 协议并不保证一定把数据包送达目标主机,在发送过程中,会因为数据包生命周期结束或找不到路由而丢弃数据包。

域名

尽管 IP 地址能够唯一标识网络上的主机,但 IP 地址是数字型的,用户记忆数字型的 IP 地址很不方便。为了克服直接使用 IP 地址的不足,于是我们使用更方便记忆的服务器名称来代替服务器 IP 地址。在引入 DNS 之前是通过一个称为 host.txt 的文本文件把网络中各计算机的计算机名称与其对应的 IP 地址一一列出来实现解析的。但随着计算机名称越来越多,Host 文件已无法承受如此大的负荷。

后来人们又发明了另一种基于域的分层命名方案,即所谓的域名(Domain Name)。域名地址具有易于理解的字面含义,便于记忆。它也可以将主机名映射成对应 IP 地址。当需要把主机名解析为 IP 地址时,应用程序就调用一个解析器将该名字作为 DNS 请求报文参数,以 UDP 方式发送给本地 DNS 服务器。然后本地 DNS 服务器查找该名字,并将找到的 IP 地址响应给解析器,解析器再返回给应用程序。

DNS 域名也不是单一结构的,而是包含至少两个层次的分级结构,因为单一结构的域名无法满足全球如此多互联网用户的需求。目前的全球域名按照从大到小的结构,形成了一棵树状结构。实际访问一个域名时,是从最底层开始写起:image.png

DNS

DNS(Domain Name System)协议采用 DNS 服务器来提供把域名转换为 IP 地址的服务。DNS 服务器分布在网络的各个地方,它们存放了域名与 IP 地址的映射信息。用户需要访问网络上某个主机时,只需提供主机的直观的域名,DNS 协议首先请求地理上比较近的 DNS 服务器进行域名到 IP 地址的转换,如果在该服务器中不存在此域名信息,DNS 协议再让远方的 DNS 服务器提供服务。

为了提高每台 DNS 名称服务器的运行效率和利用率,提出了区域的概念,可以让一台或多台 DNS 名称服务器负责一个区域的计算机域名解析。当然,越上一级别区域的 DNS 名称服务器的负担越重,因为它同时还会为下级区域中的 DNS 名称服务器提供解析支持,在下级区域中的 DNS 名称服务器解析不了或满负荷时提供帮助。

1. DNS 服务器种类

为了有效管理整个互联网的 DNS 域名解析工作,DNS 系统开发者也设计了一个与分层的 DNS 域名结构类似的层次化 DNS 名称服务器结构。把所有 DNS 名称服务器自高到低分成 4 个级别:根名称服务器顶级名称服务器权威名称服务器本地名称服务器

1)根名称服务器
根名称服务器是互联网管理机构配置建立的,是最高层次的名称服务器,负责对互联网上的所有的 “顶级名称服务器” 进行管理,有全部的顶级名称服务器的 IP 地址和域名映射。

根名称服务器并不直接用于名称解析,因为这些根名称服务器上也没有保存全部的互联网域名记录(仅负责管理顶级域名服务器)。根名称服务器的作用仅是当用户本地名称服务器解析不了某个顶级域名时告诉本地名称服务器去找哪个顶级名称服务器。

2)顶级名称服务器
顶级名称服务器就是各顶级域名自己的名称服务器,负责它们各自所管理的顶级域名解析,并通常还具有二级名称服务器的地址信息。每一个顶级域名都有自己的域名服务器。

3)权威名称服务器
权威名称服务器是针对前面所说的 DNS 区域提供名称解析服务而专门配置、建立的名称服务器,可为用户提供最权威的 DNS 域名解析。每一个域名在互联网上都可以找到一台权威名称服务器。

4)本地名称服务器
本地名称服务器是指用户端操作系统所配置的,由本地提供的名称服务器。它是离用户最近的互联网名称服务器。用户发出的 DNS 域名解析请求首先到达的就是本地名称服务器。

2. DNS 解析流程

DNS 有两种域名解析方式:一种是递归解析(默认),另一种是迭代解析。递归解析是当所配置的本地名称服务器解析不了时,后面的查询工作由本地名称服务器替代 DNS 客户端进行的,只需要本地名称服务器向 DNS 客户端返回最终的查询结果即可;迭代解析则是所有查询工作都由 DNS 客户端自己进行。

2.1 递归解析

1)当用户在浏览器中输入域名并按下回车键后,会先查询浏览器缓存有没有这个域名对应的解析过的 IP 地址,如果有该域名的记录项则直接返回该结果;如果用户的浏览器缓存中没有该域名的记录,浏览器会查找操作系统缓存中是否有这个域名对应的 DNS 解析结果。操作系统也会有一个域名解析的过程,在 Linux 中可以通过 /etc/hosts 文件来设置,如果在这里指定了一个域名对应的 IP 地址,那浏览器会先使用这个 IP 地址。

2)上述步骤都是在本机完成的,所以在下图中没有表示出来,到这里还没有涉及真正的域名解析服务器。如果在本机中仍无法完成域名的解析,客户端就会向本机配置的本地名称服务器发出 DNS 域名查询请求,在 Linux 下可以通过如下方式查询配置的 DNS Server。
image.png

3)如果本地名称服务器仍然没有命中,本地名称服务器再以 DNS 客户端的角色发送与前面一样的 DNS 域名查询请求给根名称服务器。根名称服务器收到 DNS 请求后,把查询到的所请求的 DNS 域名中顶级域名所对应的顶级名称服务器地址返回给本地名称服务器。

4)本地名称服务器根据顶级名称服务器地址向对应的顶级名称服务器发送与前面一样的 DNS 域名查询请求。

5)对应的顶级名称服务器在收到 DNS 查询请求后,也是先查询自己的缓存,如果有所请求的 DNS 域名的记录项,则把对应的记录项返回给本地名称服务器,然后再由本地名称服务器返回给 DNS 客户端,否则向本地名称服务器返回所请求的 DNS 域名中的二级域名所对应的二级名称服务器地址

6)然后本地名称服务器继续按照前面介绍的方法一次次地向三级、四级名称服务器查询,直到最终的对应域名所在区域的权威名称服务器返回最终的记录给本地名称服务器。然后再由本地名称服务器返回给DNS 客户,同时本地名称服务器会缓存本次查询得到的记录项。
IP 协议 - 图5

2.2 迭代解析

1)客户端向本机配置的本地名称服务器发出 DNS 域名查询请求。

2)本地名称服务器收到请求后,先查询本地的缓存,如果有记录则直接把结果返回给客户端;如果没有则向 DNS 客户端返回一条 DNS 应答报文,报文中会给出一些参考信息,如本地名称服务器上的根名称服务器地址等。

3)DNS 客户端在收到本地名称服务器的应答报文后,会根据其中的根名称服务器地址信息向对应的根名称服务器再次发出与前面一样的 DNS 查询请求报文。

4)根名称服务器收到 DNS 查询请求报文后,通过查询自己的 DNS 数据库得到请求 DNS 域名中顶级域名所对应的顶级名称服务器信息,然后以一条 DNS 应答报文返回给 DNS 客户端。

5)DNS 客户端根据来自根名称服务器应答报文中的对应顶级名称服务器地址信息向该顶级名称服务器发出与前面一样的 DNS 查询请求报文。

6)顶级名称服务器在收到 DNS 查询请求后,先查询自己的缓存,如果有则把对应的记录项返回给 DNS 客户端,否则通过查询后把对应域名中二级域名所对应的二级名称服务器地址信息以一条 DNS 应答报文返回给 DNS 客户端。然后循环查询,直到最终的权威名称服务器返回到最终的记录。

IP 协议 - 图6

3. 跟踪域名解析过程

在 Linux 和 Windows 下都可以用 nslookup 命令来查询域名的解析结果:
image.png

在 Linux 系统中还可以使用 dig 命令来查询 DNS 的解析过程:
image.png
QUESTION SECTION 部分表示当前查询的域名是一个 A 记录。ANSWER SECTION 部分返回了这个域名对应的 IP 地址。此外,还可以通过增加 +trace 参数跟踪这个域名的解析过程:
image.png
上面清楚地显示了整个域名是如何发起和解析的,从根域名(.)到顶级域名(.com)再到名称域名(taobao.com.)的整个过程都显示出来了。还可以看出 DNS 的服务器有多个备份,可以从任何一台查询到解析结果。