跳到主要内容

3. 客户端-服务器协议

DHCP 使用 RFC 951 中定义的 BOOTP 消息格式, 该格式见表 1 和图 1. 从客户端发送到服务器的每条 DHCP 消息, 其 'op' 字段包含 BOOTREQUEST. 从服务器发送到客户端的每条 DHCP 消息, 其 'op' 字段使用 BOOTREPLY.

DHCP 消息 'options' 字段的前四个 octets 分别包含十进制值 99, 130, 83 和 99 (这与 RFC 1497 [17] 中定义的 magic cookie 相同). 'options' 字段的其余部分由称为 "options" 的带标签参数列表组成. RFC 1497 中列出的所有 "vendor extensions" 也都是 DHCP options. RFC 1533 给出了为 DHCP 使用而定义的完整 options 集.

目前已经定义了若干 options. 其中一个特定 option, 即 "DHCP message type" option, 必须包含在每条 DHCP 消息中. 该 option 定义 DHCP 消息的 "type". 根据 DHCP 消息类型, 可以允许, 要求或不允许其他 options.

在本文档中, 包含 'DHCP message type' option 的 DHCP 消息将按该消息的类型来称呼; 例如, 带有 'DHCP message type' option 类型 1 的 DHCP 消息将称为 "DHCPDISCOVER" 消息.


3.1 客户端-服务器交互: 分配网络地址

下面对客户端与服务器之间协议交换的摘要, 引用了表 2 中描述的 DHCP 消息. 图 3 的时间线图展示了典型客户端-服务器交互中的时序关系. 如果客户端已经知道自己的地址, 可以省略其中一些步骤; 这种简化交互在第 3.2 节中描述.

1. 客户端在其本地物理子网上广播 DHCPDISCOVER 消息. DHCPDISCOVER 消息 MAY 包含建议网络地址和租约时长取值的 options. BOOTP relay agents 可以把该消息转发给不在同一物理子网上的 DHCP servers.

2. 每个服务器都可以用 DHCPOFFER 消息响应, 该消息在 'yiaddr' 字段中包含一个可用网络地址 (并在 DHCP options 中包含其他配置参数). 服务器不必保留所提供的网络地址, 但如果服务器避免把所提供的网络地址分配给另一个客户端, 协议会更高效. 分配新地址时, 服务器 SHOULD 检查所提供的网络地址是否已在使用; 例如, 服务器可以用 ICMP echo request 探测该地址. 服务器实现 SHOULD 允许网络管理员选择禁用对新分配地址的探测. 服务器将 DHCPOFFER 消息发送给客户端, 必要时使用 BOOTP relay agent.


DHCP 消息

消息用途
DHCPDISCOVER客户端广播, 用于定位可用服务器.
DHCPOFFER服务器响应 DHCPDISCOVER 发给客户端, 提供配置参数.
DHCPREQUEST客户端发给服务器的消息, 用于 (a) 请求某个服务器提供的参数并隐式拒绝所有其他 offer, (b) 在系统重启等情况下确认先前分配地址的正确性, 或 (c) 延长某个网络地址的租约.
DHCPACK服务器发给客户端, 携带配置参数, 包括已承诺的网络地址.
DHCPNAK服务器发给客户端, 表示客户端对网络地址的认知不正确 (例如客户端已移动到新子网) 或客户端租约已过期.
DHCPDECLINE客户端发给服务器, 表示网络地址已在使用.
DHCPRELEASE客户端发给服务器, 放弃网络地址并取消剩余租约.
DHCPINFORM客户端发给服务器, 仅请求本地配置参数; 客户端已经拥有外部配置的网络地址.

表 2: DHCP 消息


时间线图

            Server          Client          Server
(not selected) (selected)

v v v
| | |
| Begins initialization |
| | |
| _____________/|\____________ |
|/DHCPDISCOVER | DHCPDISCOVER \|
| | |
Determines | Determines
configuration | configuration
| | |
|\ | ____________/ |
| \________ | /DHCPOFFER |
| DHCPOFFER\ |/ |
| \ | |
| Collects replies |
| \| |
| Selects configuration |
| | |
| _____________/|\____________ |
|/ DHCPREQUEST | DHCPREQUEST\ |
| | |
| | Commits configuration
| | |
| | _____________/|
| |/ DHCPACK |
| | |
| Initialization complete |
| | |
. . .
. . .
| | |
| Graceful shutdown |
| | |
| |\ ____________ |
| | DHCPRELEASE \|
| | |
| | Discards lease
| | |
v v v

Figure 3: Timeline diagram of messages exchanged between DHCP
client and servers when allocating a new network address

3. 客户端从一个或多个服务器接收一个或多个 DHCPOFFER 消息. 客户端可以选择等待多个响应. 客户端基于 DHCPOFFER 消息中提供的配置参数, 选择一个服务器并向其请求配置参数. 客户端广播 DHCPREQUEST 消息, 该消息 MUST 包含 'server identifier' option 以表明所选择的服务器, 并 MAY 包含指定期望配置值的其他 options. 'requested IP address' option MUST 设置为所选服务器 DHCPOFFER 消息中 'yiaddr' 的值. 该 DHCPREQUEST 消息通过 DHCP/BOOTP relay agents 广播和中继. 为帮助确保任何 BOOTP relay agents 将 DHCPREQUEST 消息转发到接收原始 DHCPDISCOVER 消息的同一组 DHCP servers, DHCPREQUEST 消息 MUST 使用 DHCP 消息头中 'secs' 字段的相同值, 并发送到与原始 DHCPDISCOVER 消息相同的 IP 广播地址. 如果客户端没有收到 DHCPOFFER 消息, 客户端超时并重传 DHCPDISCOVER 消息.

4. 服务器接收来自客户端的 DHCPREQUEST 广播. 未被 DHCPREQUEST 消息选中的服务器将该消息作为通知, 表明客户端已拒绝该服务器的 offer. DHCPREQUEST 消息中选中的服务器将客户端 binding 提交到持久存储, 并用包含请求客户端配置参数的 DHCPACK 消息响应. 'client identifier' 或 'chaddr' 与已分配网络地址的组合构成客户端租约的唯一标识符, 客户端和服务器都使用它来识别任何 DHCP 消息中引用的租约. DHCPACK 消息中的任何配置参数 SHOULD NOT 与客户端正在响应的较早 DHCPOFFER 消息中的参数冲突. 此时服务器 SHOULD NOT 检查所提供的网络地址. DHCPACK 消息中的 'yiaddr' 字段填入所选网络地址.

如果所选服务器无法满足 DHCPREQUEST 消息 (例如请求的网络地址已被分配), 服务器 SHOULD 用 DHCPNAK 消息响应.

服务器 MAY 选择将 DHCPOFFER 消息中提供给客户端的地址标记为不可用. 如果服务器没有从该客户端收到 DHCPREQUEST 消息, 则 SHOULD 将 DHCPOFFER 消息中提供给该客户端的地址标记为可用.

5. 客户端接收带配置参数的 DHCPACK 消息. 客户端 SHOULD 对参数执行最终检查 (例如对分配的网络地址执行 ARP), 并记录 DHCPACK 消息中指定的租约时长. 此时客户端已配置完成. 如果客户端检测到地址已在使用 (例如通过 ARP), 客户端 MUST 向服务器发送 DHCPDECLINE 消息并重新开始配置过程. 为避免循环情况下产生过多网络流量, 客户端 SHOULD 在重新开始配置过程前至少等待十秒.

如果客户端收到 DHCPNAK 消息, 客户端重新开始配置过程.

如果客户端既未收到 DHCPACK 也未收到 DHCPNAK 消息, 客户端按第 4.1 节的重传算法超时并重传 DHCPREQUEST 消息. 客户端 SHOULD 选择足够多次重传 DHCPREQUEST, 以提供联系到服务器的充分概率, 同时不让客户端 (以及该客户端用户) 在放弃之前等待过久; 例如, 按第 4.1 节所述重传的客户端可能重传 DHCPREQUEST 消息四次, 总延迟 60 秒, 然后重新开始初始化过程. 如果客户端在采用重传算法后既未收到 DHCPACK 也未收到 DHCPNAK 消息, 客户端回到 INIT 状态并重新开始初始化过程. 客户端 SHOULD 通知用户初始化过程失败且正在重新开始.

6. 客户端可以选择通过向服务器发送 DHCPRELEASE 消息来放弃其网络地址租约. 客户端在 DHCPRELEASE 消息中用其 'client identifier' 或 'chaddr' 以及网络地址标识要释放的租约. 如果客户端获取租约时使用了 'client identifier', 则它 MUST 在 DHCPRELEASE 消息中使用同一 'client identifier'.


3.2 客户端-服务器交互: 重用先前分配的网络地址

如果客户端记得并希望重用先前分配的网络地址, 客户端可以选择省略上一节中描述的一些步骤. 图 4 的时间线图展示了客户端重用先前分配网络地址时典型客户端-服务器交互的时序关系.

1. 客户端在其本地子网上广播 DHCPREQUEST 消息. 该消息在 'requested IP address' option 中包含客户端网络地址. 由于客户端尚未收到其网络地址, 它 MUST NOT 填写 'ciaddr' 字段. BOOTP relay agents 将该消息转发给不在同一子网上的 DHCP servers. 如果客户端使用 'client identifier' 获取其地址, 则客户端 MUST 在 DHCPREQUEST 消息中使用同一 'client identifier'.

2. 知道客户端配置参数的服务器用 DHCPACK 消息响应客户端. 服务器 SHOULD NOT 检查客户端网络地址是否已在使用; 此时客户端可能会响应 ICMP Echo Request 消息.

            Server          Client          Server

v v v
| | |
| Begins |
| initialization |
| | |
| /|\ |
| _________ __/ | \__________ |
| /DHCPREQUEST | DHCPREQUEST\ |
|/ | \|
| | |
Locates | Locates
configuration | configuration
| | |
|\ | /|
| \ | ___________/ |
| \ | / DHCPACK |
| \ _______ |/ |
| DHCPACK\ | |
| Initialization |
| complete |
| \| |
| | |
| (Subsequent |
| DHCPACKS |
| ignored) |
| | |
| | |
v v v

Figure 4: Timeline diagram of messages exchanged between DHCP
client and servers when reusing a previously allocated
network address

如果客户端请求无效 (例如客户端已移动到新子网), 服务器 SHOULD 用 DHCPNAK 消息响应客户端. 如果服务器的信息不能保证准确, 服务器 SHOULD NOT 响应. 例如, 如果某服务器识别出一个针对已过期 binding 的请求, 而该 binding 属于另一个服务器, 除非这些服务器正在使用显式机制维护服务器之间的一致性, 否则该服务器 SHOULD NOT 用 DHCPNAK 响应.

如果 DHCPREQUEST 消息中的 'giaddr' 为 0x0, 客户端与服务器在同一子网上. 服务器 MUST 将 DHCPNAK 消息广播到 0xffffffff 广播地址, 因为客户端可能没有正确网络地址或子网掩码, 并且可能不响应 ARP 请求. 否则, 服务器 MUST 将 DHCPNAK 消息发送到 'giaddr' 中记录的 BOOTP relay agent IP 地址. 随后 relay agent 会将消息直接转发到客户端硬件地址, 因而即使客户端已移动到新网络, DHCPNAK 也能被交付.

3. 客户端接收带配置参数的 DHCPACK 消息. 客户端对参数执行最终检查 (如第 3.1 节), 并记录 DHCPACK 消息中指定的租约时长. 具体租约由 'client identifier' 或 'chaddr' 以及网络地址隐式标识. 此时客户端已配置完成.

如果客户端检测到 DHCPACK 消息中的 IP 地址已在使用, 客户端 MUST 向服务器发送 DHCPDECLINE 消息, 并通过请求新网络地址重新开始配置过程. 该动作对应于客户端移动到 DHCP 状态图中的 INIT 状态, 该状态图在第 4.4 节中描述.

如果客户端收到 DHCPNAK 消息, 它不能重用记住的网络地址. 它必须改为通过重新开始配置过程来请求新地址, 这次使用第 3.1 节描述的非简化过程. 该动作也对应于客户端移动到 DHCP 状态图中的 INIT 状态.

如果客户端既未收到 DHCPACK 也未收到 DHCPNAK 消息, 客户端按第 4.1 节中的重传算法超时并重传 DHCPREQUEST 消息. 客户端 SHOULD 选择足够多次重传 DHCPREQUEST, 以提供联系到服务器的充分概率, 同时不让客户端和用户在放弃之前等待过久; 例如, 按第 4.1 节所述重传的客户端可能重传 DHCPREQUEST 消息四次, 总延迟 60 秒, 然后重新开始初始化过程. 如果客户端在采用重传算法后既未收到 DHCPACK 也未收到 DHCPNAK 消息, 客户端 MAY 选择在未过期租约的剩余时间内使用先前分配的网络地址和配置参数. 这对应于移动到图 5 所示客户端状态转换图中的 BOUND 状态.

4. 客户端可以选择通过向服务器发送 DHCPRELEASE 消息来放弃其网络地址租约. 客户端在 DHCPRELEASE 消息中用其 'client identifier' 或 'chaddr' 以及网络地址标识要释放的租约.

注意, 在这种客户端本地保留其网络地址的情况下, 客户端通常不会在正常关闭期间放弃其租约. 只有当客户端明确需要放弃其租约时, 例如客户端即将移动到不同子网时, 客户端才会发送 DHCPRELEASE 消息.


3.3 时间值的解释和表示

客户端为网络地址获取固定时间段的租约 (可能是永久). 在整个协议中, 时间以秒为单位表示. 时间值 0xffffffff 保留用于表示 "infinity" (无限).

由于客户端和服务器的时钟可能不同步, DHCP 消息中的时间表示为相对时间, 并相对于客户端本地时钟解释. 使用无符号 32 位字以秒为单位表示相对时间, 可提供从 0 到约 100 年的相对时间范围, 足以用于通过 DHCP 测量相对时间.

上一段给出的租约时长解释算法假定客户端和服务器时钟相对稳定. 如果两个时钟之间存在漂移, 服务器可能在客户端之前认为租约已过期. 为了补偿, 服务器可以向客户端返回比服务器提交到其本地客户端信息数据库中的租约时长更短的租约时长.


3.4 使用外部配置网络地址获取参数

如果客户端已通过其他方式 (例如手工配置) 获取网络地址, 它可以使用 DHCPINFORM 请求消息获取其他本地配置参数. 收到 DHCPINFORM 消息的服务器会构造 DHCPACK 消息, 其中包含适合该客户端的任何本地配置参数, 但不分配新地址, 不检查现有 binding, 不填写 'yiaddr', 也不包含租约时间参数. 服务器 SHOULD 将 DHCPACK 回复单播到 DHCPINFORM 消息 'ciaddr' 字段给出的地址.

服务器 SHOULD 检查 DHCPINFORM 消息中的网络地址是否一致, 但 MUST NOT 检查现有租约. 服务器形成包含请求客户端配置参数的 DHCPACK 消息, 并将 DHCPACK 消息直接发送给客户端.


3.5 DHCP 中的客户端参数

并非所有客户端都需要初始化 Appendix A 中列出的所有参数. 使用两种技术减少从服务器传输到客户端的参数数量. 首先, 大多数参数在 Host Requirements RFCs 中定义了默认值; 如果客户端没有从服务器收到覆盖默认值的参数, 客户端就使用这些默认值. 其次, 在其初始 DHCPDISCOVER 或 DHCPREQUEST 消息中, 客户端可以向服务器提供自己感兴趣的特定参数列表. 如果客户端在 DHCPDISCOVER 消息中包含参数列表, 它 MUST 在任何后续 DHCPREQUEST 消息中包含该列表.

客户端 SHOULD 包含 'maximum DHCP message size' option, 以告知服务器可以把 DHCP 消息做多大. 返回给客户端的参数仍可能超过 DHCP 消息中为 options 分配的空间. 在这种情况下, 两个额外 option flags (必须出现在消息的 'options' 字段中) 表明 'file' 和 'sname' 字段将用于 options.

客户端可以通过包含 'parameter request list' option 告知服务器它感兴趣的配置参数. 该 option 的数据部分按 tag number 明确列出请求的 options.

此外, 客户端可以在 DHCPDISCOVER 消息中建议网络地址和租约时间取值. 客户端可以包含 'requested IP address' option, 以建议分配某个特定 IP 地址, 并可以包含 'IP address lease time' option, 以建议它希望的租约时间. 在 DHCPDISCOVER 或 DHCPREQUEST 消息中允许其他表示配置参数 "hints" (提示) 的 options. 但是, 服务器可以忽略额外 options, 多个服务器也可能不会为某些 options 返回相同值. 只有当客户端正在验证先前分配且已缓存的网络参数时, 才在 DHCPREQUEST 消息中填写 'requested IP address' option. 客户端只有在 BOUND, RENEWING 或 REBINDING 状态下已正确配置 IP 地址时才填写 'ciaddr' 字段.

如果服务器收到带无效 'requested IP address' 的 DHCPREQUEST 消息, 服务器 SHOULD 用 DHCPNAK 消息响应客户端, 并可选择向系统管理员报告该问题. 服务器可以在 'message' option 中包含错误消息.


3.6 多接口客户端中 DHCP 的使用

具有多个网络接口的客户端必须通过每个接口独立使用 DHCP, 以获取这些独立接口的配置参数.


3.7 客户端何时应使用 DHCP

只要本地网络参数可能已经改变, 客户端 SHOULD 使用 DHCP 重新获取或验证其 IP 地址和网络参数; 例如在系统启动时或从本地网络断开后, 因为本地网络配置可能在客户端或用户不知情的情况下发生变化.

如果客户端知道先前网络地址且无法联系本地 DHCP server, 客户端可以继续使用先前网络地址, 直到该地址租约过期. 如果租约在客户端能够联系 DHCP server 之前过期, 客户端必须立即停止使用先前网络地址, 并可以通知本地用户该问题.