3. 客户端-服务器协议 (The Client-Server Protocol)
DHCP使用RFC 951中定义的BOOTP消息格式, 如表1和图1所示。从客户端发送到服务器的每条DHCP消息的'op'字段包含BOOTREQUEST。BOOTREPLY用于从服务器发送到客户端的每条DHCP消息的'op'字段中。
DHCP消息的'options'字段的前四个八位字节分别包含 (十进制) 值99、130、83和99 (这与RFC 1497 [17] 中定义的魔术cookie相同)。'options'字段的其余部分由称为"选项"的标记参数列表组成。RFC 1497中列出的所有"供应商扩展"也是DHCP选项。RFC 1533给出了为DHCP定义的完整选项集。
到目前为止已经定义了几个选项。一个特定的选项 - "DHCP消息类型 (DHCP Message Type)" 选项 - 必须包含在每条DHCP消息中。此选项定义DHCP消息的"类型"。根据DHCP消息类型, 可能允许、需要或不允许其他选项。
在本文档中, 包含'DHCP消息类型'选项的DHCP消息将按消息类型引用; 例如, 具有'DHCP消息类型'选项类型1的DHCP消息将被称为"DHCPDISCOVER"消息。
3.1 客户端-服务器交互 - 分配网络地址 (Client-server interaction - allocating a network address)
以下对客户端和服务器之间协议交换的总结涉及表2中描述的DHCP消息。图3中的时间轴图显示了典型客户端-服务器交互中的时序关系。如果客户端已经知道其地址, 则可以省略某些步骤; 第3.2节描述了这种简化交互。
1. 客户端在其本地物理子网上广播DHCPDISCOVER消息。DHCPDISCOVER消息可以包含建议网络地址和租期持续时间值的选项。BOOTP中继代理可以将消息传递给不在同一物理子网上的DHCP服务器。
2. 每个服务器可以使用DHCPOFFER消息响应, 该消息在'yiaddr'字段中包含可用的网络地址 (以及DHCP选项中的其他配置参数)。服务器不需要保留提供的网络地址, 尽管如果服务器避免将提供的网络地址分配给另一个客户端, 协议将更有效地工作。在分配新地址时, 服务器应该检查提供的网络地址尚未使用; 例如, 服务器可以使用ICMP回显请求探测提供的地址。服务器应该实现为网络管理员可以选择禁用对新分配地址的探测。服务器使用BOOTP中继代理 (如有必要) 向客户端传输DHCPOFFER消息。
DHCP消息类型 (DHCP messages)
| 消息 | 用途 |
|---|---|
| DHCPDISCOVER | 客户端广播以定位可用服务器。 |
| DHCPOFFER | 服务器响应DHCPDISCOVER, 向客户端提供配置参数。 |
| DHCPREQUEST | 客户端向服务器发送的消息, 可以是: (a) 从一个服务器请求提供的参数并隐式拒绝来自所有其他服务器的提供, (b) 在例如系统重新启动后确认先前分配的地址的正确性, 或 (c) 延长特定网络地址上的租期。 |
| DHCPACK | 服务器向客户端发送配置参数, 包括已提交的网络地址。 |
| DHCPNAK | 服务器向客户端指示客户端对网络地址的概念不正确 (例如, 客户端已移至新子网) 或客户端的租期已过期。 |
| DHCPDECLINE | 客户端向服务器指示网络地址已在使用中。 |
| DHCPRELEASE | 客户端向服务器放弃网络地址并取消剩余租期。 |
| DHCPINFORM | 客户端向服务器仅请求本地配置参数; 客户端已有外部配置的网络地址。 |
表2: DHCP消息
消息交换时间轴 (Timeline diagram)
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
图3: 分配新网络地址时DHCP客户端和服务器之间交换的消息时间轴图
3. 客户端从一个或多个服务器接收一条或多条DHCPOFFER消息。客户端可以选择等待多个响应。客户端根据DHCPOFFER消息中提供的配置参数, 从中选择一个服务器来请求配置参数。客户端广播DHCPREQUEST消息, 该消息必须包含'服务器标识符'选项以指示它选择了哪个服务器, 并且可以包含指定所需配置值的其他选项。'请求的IP地址'选项必须设置为来自服务器的DHCPOFFER消息中'yiaddr'的值。此DHCPREQUEST消息通过DHCP/BOOTP中继代理广播和中继。为了帮助确保任何BOOTP中继代理将DHCPREQUEST消息转发到接收原始DHCPDISCOVER消息的同一组DHCP服务器, DHCPREQUEST消息必须在DHCP消息头的'secs'字段中使用相同的值, 并且必须发送到与原始DHCPDISCOVER消息相同的IP广播地址。如果客户端未收到DHCPOFFER消息, 则客户端超时并重新传输DHCPDISCOVER消息。
4. 服务器从客户端接收DHCPREQUEST广播。未被DHCPREQUEST消息选择的服务器将该消息用作客户端已拒绝该服务器提供的通知。在DHCPREQUEST消息中选择的服务器将客户端的绑定提交到持久存储, 并使用包含请求客户端的配置参数的DHCPACK消息进行响应。'客户端标识符'或'chaddr'与分配的网络地址的组合构成客户端租期的唯一标识符, 并由客户端和服务器用于标识任何DHCP消息中引用的租期。DHCPACK消息中的任何配置参数不应与客户端正在响应的较早DHCPOFFER消息中的参数冲突。此时服务器不应检查提供的网络地址。DHCPACK消息中的'yiaddr'字段填充所选的网络地址。
如果选定的服务器无法满足DHCPREQUEST消息 (例如, 请求的网络地址已分配), 则服务器应该使用DHCPNAK消息进行响应。
服务器可以选择将在DHCPOFFER消息中提供给客户端的地址标记为不可用。如果服务器未从该客户端收到DHCPREQUEST消息, 则服务器应该将在DHCPOFFER消息中提供给客户端的地址标记为可用。
5. 客户端接收带有配置参数的DHCPACK消息。客户端应该对参数执行最终检查 (例如, ARP检查已分配的网络地址), 并记录DHCPACK消息中指定的租期持续时间。此时, 客户端已配置。如果客户端检测到地址已在使用中 (例如, 通过使用ARP), 则客户端必须向服务器发送DHCPDECLINE消息并重新启动配置过程。客户端应该在重新启动配置过程之前等待至少十秒钟, 以避免在循环情况下产生过多的网络流量。
如果客户端收到DHCPNAK消息, 则客户端重新启动配置过程。
如果客户端既未收到DHCPACK也未收到DHCPNAK消息, 则客户端超时并重新传输DHCPREQUEST消息。客户端根据第4.1节中的重传算法重新传输DHCPREQUEST。客户端应该选择重传DHCPREQUEST足够多次, 以提供足够的概率联系服务器, 而不会导致客户端 (以及该客户端的用户) 在放弃之前等待过长时间; 例如, 如第4.1节所述进行重传的客户端可能会重传DHCPREQUEST消息四次, 总延迟为60秒, 然后重新启动初始化过程。如果客户端在使用重传算法后既未收到DHCPACK也未收到DHCPNAK消息, 则客户端恢复到INIT状态并重新启动初始化过程。客户端应该通知用户初始化过程已失败并正在重新启动。
6. 客户端可以选择通过向服务器发送DHCPRELEASE消息来放弃其在网络地址上的租期。客户端使用其'客户端标识符'或'chaddr'和DHCPRELEASE消息中的网络地址标识要释放的租期。如果客户端在获得租期时使用了'客户端标识符', 则它必须在DHCPRELEASE消息中使用相同的'客户端标识符'。
3.2 客户端-服务器交互 - 重用先前分配的网络地址 (Client-server interaction - reusing a previously allocated network address)
如果客户端记住并希望重用先前分配的网络地址, 则客户端可以选择省略上一节中描述的某些步骤。图4中的时间轴图显示了客户端重用先前分配的网络地址的典型客户端-服务器交互中的时序关系。
1. 客户端在其本地子网上广播DHCPREQUEST消息。该消息在'请求的IP地址'选项中包含客户端的网络地址。由于客户端尚未收到其网络地址, 因此它不得填写'ciaddr'字段。BOOTP中继代理将消息传递给不在同一子网上的DHCP服务器。如果客户端使用'客户端标识符'获取其地址, 则客户端必须在DHCPREQUEST消息中使用相同的'客户端标识符'。
2. 了解客户端配置参数的服务器使用DHCPACK消息响应客户端。服务器不应该检查客户端的网络地址是否已在使用中; 此时客户端可能会响应ICMP回显请求消息。
Server Client Server
v v v
| | |
| Begins |
| initialization |
| | |
| /|\ |
| _________ __/ | \__________ |
| /DHCPREQUEST | DHCPREQUEST\ |
|/ | \|
| | |
Locates | Locates
configuration | configuration
| | |
|\ | /|
| \ | ___________/ |
| \ | / DHCPACK |
| \ _______ |/ |
| DHCPACK\ | |
| Initialization |
| complete |
| \| |
| | |
| (Subsequent |
| DHCPACKS |
| ignored) |
| | |
| | |
v v v
图4: 重用先前分配的网络地址时DHCP客户端和服务器之间交换的消息时间轴图
如果客户端的请求无效 (例如, 客户端已移至新子网), 服务器应该使用DHCPNAK消息响应客户端。如果服务器的信息不能保证准确, 则服务器不应该响应。例如, 识别由另一个服务器拥有的过期绑定请求的服务器不应该使用DHCPNAK进行响应, 除非服务器正在使用显式机制来维护服务器之间的一致性。
如果DHCPREQUEST消息中的'giaddr'为0x0, 则客户端与服务器在同一子网上。服务器必须将DHCPNAK消息广播到0xffffffff广播地址, 因为客户端可能没有正确的网络地址或子网掩码, 并且客户端可能不响应ARP请求。否则, 服务器必须将DHCPNAK消息发送到BOOTP中继代理的IP地址 (如'giaddr'中记录的那样)。中继代理将依次将消息直接转发到客户端的硬件地址, 以便即使客户端已移至新网络, 也可以传递DHCPNAK。
3. 客户端接收带有配置参数的DHCPACK消息。客户端对参数执行最终检查 (如第3.1节所述), 并记录DHCPACK消息中指定的租期持续时间。特定租期由'客户端标识符'或'chaddr'和网络地址隐式标识。此时, 客户端已配置。
如果客户端检测到DHCPACK消息中的IP地址已在使用中, 则客户端必须向服务器发送DHCPDECLINE消息, 并通过请求新的网络地址重新启动配置过程。此操作对应于客户端移至DHCP状态图中的INIT状态, 第4.4节对此进行了描述。
如果客户端收到DHCPNAK消息, 则无法重用其记住的网络地址。它必须通过重新启动配置过程来请求新地址, 这次使用第3.1节中描述的 (非简化) 过程。此操作也对应于客户端移至DHCP状态图中的INIT状态。
如果客户端既未收到DHCPACK也未收到DHCPNAK消息, 则客户端超时并重新传输DHCPREQUEST消息。客户端根据第4.1节中的重传算法重新传输DHCPREQUEST。客户端应该选择重传DHCPREQUEST足够多次, 以提供足够的概率联系服务器, 而不会导致客户端 (以及该客户端的用户) 在放弃之前等待过长时间; 例如, 如第4.1节所述进行重传的客户端可能会重传DHCPREQUEST消息四次, 总延迟为60秒, 然后重新启动初始化过程。如果客户端在使用重传算法后既未收到DHCPACK也未收到DHCPNAK消息, 则客户端可以选择使用先前分配的网络地址和配置参数来处理未过期租期的剩余时间。这对应于移至图5所示的客户端状态转换图中的BOUND状态。
4. 客户端可以选择通过向服务器发送DHCPRELEASE消息来放弃其在网络地址上的租期。客户端使用其'客户端标识符'或'chaddr'和DHCPRELEASE消息中的网络地址标识要释放的租期。
请注意, 在这种情况下, 客户端在本地保留其网络地址, 客户端通常不会在正常关闭期间放弃其租期。只有在客户端明确需要放弃其租期的情况下 (例如, 客户端即将移至不同的子网), 客户端才会发送DHCPRELEASE消息。
3.3 时间值的解释和表示 (Interpretation and representation of time values)
客户端在固定时间段 (可能是无限的) 内获得网络地址的租期。在整个协议中, 时间以秒为单位表示。时间值0xffffffff保留用于表示"无限"。
由于客户端和服务器可能没有同步时钟, 因此在DHCP消息中将时间表示为相对时间, 相对于客户端的本地时钟进行解释。在无符号32位字中以秒为单位表示相对时间, 相对时间范围从0到大约100年, 这对于使用DHCP测量的相对时间来说已经足够了。
前一段中给出的租期持续时间解释算法假设客户端和服务器时钟相对稳定。如果两个时钟之间存在漂移, 服务器可能会在客户端之前认为租期已过期。为了补偿, 服务器可能会向客户端返回比服务器提交到其本地客户端信息数据库的租期持续时间更短的租期持续时间。
3.4 使用外部配置的网络地址获取参数 (Obtaining parameters with externally configured network address)
如果客户端通过其他方式 (例如, 手动配置) 获得了网络地址, 则它可以使用DHCPINFORM请求消息来获取其他本地配置参数。接收DHCPINFORM消息的服务器构造包含适合客户端的任何本地配置参数的DHCPACK消息, 而无需: 分配新地址、检查现有绑定、填写'yiaddr'或包含租期时间参数。服务器应该将DHCPACK回复单播到DHCPINFORM消息的'ciaddr'字段中给出的地址。
服务器应该检查DHCPINFORM消息中的网络地址的一致性, 但不得检查现有租期。服务器形成包含请求客户端的配置参数的DHCPACK消息, 并将DHCPACK消息直接发送给客户端。
3.5 DHCP中的客户端参数 (Client parameters in DHCP)
并非所有客户端都需要初始化附录A中列出的所有参数。使用两种技术来减少从服务器传输到客户端的参数数量。首先, 大多数参数在主机需求RFC中定义了默认值; 如果客户端从服务器收到的参数没有覆盖默认值, 则客户端使用这些默认值。其次, 在其初始DHCPDISCOVER或DHCPREQUEST消息中, 客户端可以向服务器提供客户端感兴趣的特定参数列表。如果客户端在DHCPDISCOVER消息中包含参数列表, 则它必须在任何后续DHCPREQUEST消息中包含该列表。
客户端应该包含'最大DHCP消息大小'选项, 以让服务器知道服务器可以使其DHCP消息有多大。返回给客户端的参数可能仍然超过DHCP消息中分配给选项的空间。在这种情况下, 两个额外的选项标志 (必须出现在消息的'options'字段中) 指示'file'和'sname'字段将用于选项。
客户端可以通过包含'参数请求列表 (Parameter Request List)'选项来通知服务器客户端感兴趣的配置参数。此选项的数据部分按标签号显式列出请求的选项。
此外, 客户端可以在DHCPDISCOVER消息中建议网络地址和租期时间的值。客户端可以包含'请求的IP地址'选项以建议分配特定IP地址, 并且可以包含'IP地址租期时间'选项以建议它想要的租期时间。代表配置参数"提示"的其他选项允许在DHCPDISCOVER或DHCPREQUEST消息中使用。但是, 服务器可能会忽略其他选项, 因此多个服务器可能不会为某些选项返回相同的值。'请求的IP地址'选项仅在客户端验证先前获得的网络参数时才在DHCPREQUEST消息中填写。客户端仅在BOUND、RENEWING或REBINDING状态下使用IP地址正确配置时才填写'ciaddr'字段。
如果服务器收到具有无效'请求的IP地址'的DHCPREQUEST消息, 则服务器应该使用DHCPNAK消息响应客户端, 并可以选择向系统管理员报告问题。服务器可以在'消息'选项中包含错误消息。
3.6 在具有多个接口的客户端中使用DHCP (Use of DHCP in clients with multiple interfaces)
具有多个网络接口的客户端必须通过每个接口独立使用DHCP, 以获取这些单独接口的配置信息参数。
3.7 客户端何时应使用DHCP (When clients should use DHCP)
每当本地网络参数可能已更改时, 客户端应该使用DHCP重新获取或验证其IP地址和网络参数; 例如, 在系统启动时或在从本地网络断开连接后, 因为本地网络配置可能会在客户端或用户不知情的情况下更改。
如果客户端了解先前的网络地址并且无法联系本地DHCP服务器, 则客户端可以继续使用先前的网络地址, 直到该地址的租期到期。如果租期在客户端可以联系DHCP服务器之前到期, 则客户端必须立即停止使用先前的网络地址, 并可以通知本地用户该问题。