4. DHCP客户端-服务器协议规范 (Specification of the DHCP Client-Server Protocol)
在本节中, 我们假设DHCP服务器有一个网络地址块, 可以从中满足新地址的请求。每个服务器还在本地永久存储中维护已分配地址和租期的数据库。
4.1 构造和发送DHCP消息 (Constructing and sending DHCP messages)
DHCP客户端和服务器都通过填写消息固定格式部分的字段并在可变长度选项区域中附加标记数据项来构造DHCP消息。选项区域首先包括一个四个八位字节的'魔术cookie' (在第3节中描述), 然后是选项。最后一个选项必须始终是'end'选项。
DHCP使用UDP作为其传输协议。从客户端到服务器的DHCP消息发送到'DHCP服务器'端口 (67), 从服务器到客户端的DHCP消息发送到'DHCP客户端'端口 (68)。具有多个网络地址 (例如, 多宿主主机) 的服务器可以在传出DHCP消息中使用其任何网络地址。
'服务器标识符'字段用于在DHCP消息中标识DHCP服务器, 并用作从客户端到服务器的目标地址。具有多个网络地址的服务器必须准备接受其任何网络地址作为DHCP消息中标识该服务器的地址。为了适应可能不完整的网络连接, 服务器必须选择一个地址作为'服务器标识符', 根据服务器的最佳判断, 该地址可从客户端访问。例如, 如果DHCP服务器和DHCP客户端连接到同一子网 (即, 来自客户端的消息中的'giaddr'字段为零), 则服务器应该选择服务器用于在该子网上通信的IP地址作为'服务器标识符'。如果服务器在该子网上使用多个IP地址, 则可以使用任何此类地址。如果服务器通过DHCP中继代理接收到消息, 则服务器应该从接收消息的接口中选择一个地址作为'服务器标识符' (除非服务器有其他更好的信息来做出选择)。DHCP客户端必须使用'服务器标识符'选项中提供的IP地址用于向DHCP服务器的任何单播请求。
客户端在获得其IP地址之前广播的DHCP消息必须将IP头中的源地址字段设置为0。
如果来自客户端的DHCP消息中的'giaddr'字段非零, 则服务器将任何返回消息发送到BOOTP中继代理上的'DHCP服务器'端口, 其地址出现在'giaddr'中。如果'giaddr'字段为零且'ciaddr'字段非零, 则服务器将DHCPOFFER和DHCPACK消息单播到'ciaddr'中的地址。如果'giaddr'为零且'ciaddr'为零, 并且设置了广播位, 则服务器将DHCPOFFER和DHCPACK消息广播到0xffffffff。如果未设置广播位且'giaddr'为零且'ciaddr'为零, 则服务器将DHCPOFFER和DHCPACK消息单播到客户端的硬件地址和'yiaddr'地址。在所有情况下, 当'giaddr'为零时, 服务器将任何DHCPNAK消息广播到0xffffffff。
如果DHCP消息中的选项扩展到'sname'和'file'字段, 则'选项过载 (Option Overload)' 选项必须出现在'options'字段中, 其值为1、2或3, 如RFC 1533中所述。如果'选项过载'选项出现在'options'字段中, 则'options'字段中的选项必须由'end'选项终止, 并且可以包含一个或多个'pad'选项来填充options字段。'sname'和'file'字段中的选项 (如果由'选项过载'选项指示使用) 必须以该字段的第一个八位字节开始, 必须由'end'选项终止, 并且必须后跟'pad'选项以填充该字段的其余部分。'options'、'sname'和'file'字段中的任何单个选项必须完全包含在该字段中。必须首先解释'options'字段中的选项, 以便可以解释任何'选项过载'选项。接下来必须解释'file'字段 (如果'选项过载'选项指示'file'字段包含DHCP选项), 然后是'sname'字段。
要在'选项'标记中传递的值可能太长而无法适合单个选项可用的255个八位字节 (例如, '路由器'选项中的路由器列表 [21])。除非在选项文档中另有说明, 否则选项只能出现一次。客户端将同一选项的多个实例的值连接成单个参数列表以进行配置。
DHCP客户端负责所有消息重传。客户端必须采用包含随机指数退避算法的重传策略来确定重传之间的延迟。重传之间的延迟应该选择为允许基于客户端和服务器之间互联网的特性从服务器传递回复的足够时间。例如, 在10Mb/sec以太网互联网中, 第一次重传之前的延迟应该是4秒, 由从-1到+1范围内选择的均匀随机数的值随机化。时钟提供分辨率粒度小于一秒的客户端可以选择非整数随机化值。下一次重传之前的延迟应该是8秒, 由从-1到+1范围内选择的均匀数字的值随机化。随后的重传延迟应该加倍, 最多64秒。客户端可以向用户提供重传尝试的指示, 作为配置过程进度的指示。
'xid'字段由客户端用于将传入的DHCP消息与待处理的请求匹配。DHCP客户端必须以最小化使用与另一个客户端使用的'xid'相同的'xid'的机会的方式选择'xid'。例如, 客户端可以在每次客户端重新启动时选择不同的随机初始'xid', 然后使用顺序'xid'直到下次重新启动。为每次重传选择新的'xid'是一个实现决策。客户端可以选择重用相同的'xid'或为每条重传的消息选择新的'xid'。
通常, DHCP服务器和BOOTP中继代理尝试使用单播传递直接向客户端传递DHCPOFFER、DHCPACK和DHCPNAK消息。IP目标地址 (在IP头中) 设置为DHCP 'yiaddr'地址, 链路层目标地址设置为DHCP 'chaddr'地址。不幸的是, 某些客户端实现在实现配置有效IP地址之前无法接收此类单播IP数据报 (导致死锁, 其中客户端的IP地址在客户端配置有IP地址之前无法传递)。
在其协议软件配置有IP地址之前无法接收单播IP数据报的客户端应该在该客户端发送的任何DHCPDISCOVER或DHCPREQUEST消息中将'flags'字段中的BROADCAST位设置为1。BROADCAST位将向DHCP服务器和BOOTP中继代理提供提示, 以将任何消息广播到客户端子网上的客户端。在其协议软件配置之前可以接收单播IP数据报的客户端应该将BROADCAST位清除为0。BOOTP澄清文档讨论了使用BROADCAST位的后果 [21]。
直接向DHCP客户端发送或中继DHCP消息的服务器或中继代理 (即, 不是发送到'giaddr'字段中指定的中继代理) 应该检查'flags'字段中的BROADCAST位。如果此位设置为1, 则应该使用IP广播地址 (最好是0xffffffff) 作为IP目标地址和链路层广播地址作为链路层目标地址将DHCP消息作为IP广播发送。如果BROADCAST位清除为0, 则应该将消息作为IP单播发送到'yiaddr'字段中指定的IP地址和'chaddr'字段中指定的链路层地址。如果无法进行单播, 则可以使用IP广播地址 (最好是0xffffffff) 作为IP目标地址和链路层广播地址作为链路层目标地址将消息作为IP广播发送。
4.2 DHCP服务器管理控制 (DHCP server administrative controls)
DHCP服务器不需要响应它们接收的每条DHCPDISCOVER和DHCPREQUEST消息。例如, 网络管理员为了对连接到网络的客户端保持严格控制, 可以选择配置DHCP服务器仅响应先前通过某些外部机制注册的客户端。DHCP规范仅描述客户端和服务器选择交互时客户端和服务器之间的交互; 描述系统管理员可能想要使用的所有管理控制超出了DHCP规范的范围。特定的DHCP服务器实现可以包含网络管理员期望的任何控制或策略。
在某些环境中, DHCP服务器在确定特定客户端的正确参数时必须考虑DHCPDISCOVER或DHCPREQUEST消息中包含的供应商类选项的值。
DHCP服务器需要使用某个唯一标识符将客户端与其租期关联。客户端可以选择通过'客户端标识符'选项显式提供标识符。如果客户端提供'客户端标识符', 则客户端必须在所有后续消息中使用相同的'客户端标识符', 并且服务器必须使用该标识符来标识客户端。如果客户端不提供'客户端标识符'选项, 则服务器必须使用'chaddr'字段的内容来标识客户端。DHCP客户端在'客户端标识符'选项中使用客户端所连接的子网内唯一的标识符至关重要。使用'chaddr'作为客户端的唯一标识符可能会导致意外结果, 因为该标识符可能与可能移至新客户端的硬件接口相关联。某些站点可能选择使用制造商的序列号作为'客户端标识符', 以避免由于在计算机之间传输硬件接口而导致客户端网络地址发生意外变化。站点还可以选择使用DNS名称作为'客户端标识符', 导致地址租期与DNS名称而不是特定硬件盒关联。
DHCP客户端可以自由使用任何策略在从中接收DHCPOFFER消息的服务器中选择DHCP服务器。DHCP的客户端实现应该提供一种机制, 供用户直接选择'供应商类标识符'值。
4.3 DHCP服务器行为 (DHCP server behavior)
DHCP服务器根据该客户端绑定的当前状态处理来自客户端的传入DHCP消息。DHCP服务器可以从客户端接收以下消息:
- DHCPDISCOVER
- DHCPREQUEST
- DHCPDECLINE
- DHCPRELEASE
- DHCPINFORM
表3给出了服务器在DHCP消息中使用字段和选项的情况。本节的其余部分描述了DHCP服务器对每条可能的传入消息的操作。
4.3.1 DHCPDISCOVER消息 (DHCPDISCOVER message)
当服务器从客户端接收到DHCPDISCOVER消息时, 服务器为请求客户端选择网络地址。如果没有可用的地址, 服务器可以选择向系统管理员报告问题。如果地址可用, 则应该按如下方式选择新地址:
- 客户端当前地址 (如客户端当前绑定中记录的), 否则
- 客户端以前的地址 (如客户端 (现已过期或释放) 绑定中记录的), 如果该地址在服务器的可用地址池中且尚未分配, 否则
- '请求的IP地址'选项中请求的地址, 如果该地址有效且尚未分配, 否则
- 从服务器的可用地址池中分配的新地址; 地址根据接收消息的子网选择 (如果'giaddr'为0) 或根据转发消息的中继代理的地址 ('giaddr'不为0时)。
如第4.2节所述, 服务器可以出于管理原因分配与请求的地址不同的地址, 或者即使有可用的空闲地址, 也可能拒绝向特定客户端分配地址。
请注意, 在某些网络架构中 (例如, 具有多个分配给物理网络段的IP子网的互联网), DHCP客户端可能应该从与'giaddr'中记录的地址不同的子网分配地址。因此, DHCP不要求从'giaddr'中的子网为客户端分配地址。服务器可以自由选择其他子网, 并且描述可能选择分配的IP地址的方式超出了DHCP规范的范围。
虽然不是DHCP正确操作所必需的, 但服务器不应该在客户端响应服务器的DHCPOFFER消息之前重用所选的网络地址。服务器可以选择将地址记录为提供给客户端。
服务器还必须选择租期的到期时间, 如下所示:
- 如果客户端在DHCPDISCOVER消息中没有请求特定租期并且客户端已经具有已分配的网络地址, 则服务器返回先前分配给该地址的租期到期时间 (请注意, 客户端必须显式请求特定租期以延长先前分配地址的到期时间), 否则
- 如果客户端在DHCPDISCOVER消息中没有请求特定租期并且客户端没有已分配的网络地址, 则服务器分配本地配置的默认租期时间, 否则
- 如果客户端在DHCPDISCOVER消息中请求了特定租期 (无论客户端是否具有已分配的网络地址), 则服务器可以选择返回请求的租期 (如果租期对本地策略可接受) 或选择另一个租期。
DHCP服务器使用的字段和选项表 (Fields and options used by DHCP servers)
| 字段 | DHCPOFFER | DHCPACK | DHCPNAK |
|---|---|---|---|
| op | BOOTREPLY | BOOTREPLY | BOOTREPLY |
| htype | (来自"分配号码" RFC) | ||
| hlen | (硬件地址长度,以八位字节为单位) | ||
| hops | 0 | 0 | 0 |
| xid | 来自客户端DHCPDISCOVER消息的'xid' | 来自客户端DHCPREQUEST消息的'xid' | 来自客户端DHCPREQUEST消息的'xid' |
| secs | 0 | 0 | 0 |
| ciaddr | 0 | 来自DHCPREQUEST的'ciaddr'或0 | 0 |
| yiaddr | 提供给客户端的IP地址 | 分配给客户端的IP地址 | 0 |
| siaddr | 下一个引导服务器的IP地址 | 下一个引导服务器的IP地址 | 0 |
| flags | 来自客户端DHCPDISCOVER消息的'flags' | 来自客户端DHCPREQUEST消息的'flags' | 来自客户端DHCPREQUEST消息的'flags' |
| giaddr | 来自客户端DHCPDISCOVER消息的'giaddr' | 来自客户端DHCPREQUEST消息的'giaddr' | 来自客户端DHCPREQUEST消息的'giaddr' |
| chaddr | 来自客户端DHCPDISCOVER消息的'chaddr' | 来自客户端DHCPREQUEST消息的'chaddr' | 来自客户端DHCPREQUEST消息的'chaddr' |
| sname | 服务器主机名或选项 | 服务器主机名或选项 | (未使用) |
| file | 客户端引导文件名或选项 | 客户端引导文件名或选项 | (未使用) |
| options | 选项 | 选项 |
| 选项 | DHCPOFFER | DHCPACK | DHCPNAK |
|---|---|---|---|
| 请求的IP地址 | 不得 (MUST NOT) | 不得 (MUST NOT) | 不得 (MUST NOT) |
| IP地址租期时间 | 必须 (MUST) | 必须 (MUST) (DHCPREQUEST) 不得 (MUST NOT) (DHCPINFORM) | 不得 (MUST NOT) |
| 使用'file'/'sname'字段 | 可以 (MAY) | 可以 (MAY) | 不得 (MUST NOT) |
| DHCP消息类型 | DHCPOFFER | DHCPACK | DHCPNAK |
| 参数请求列表 | 不得 (MUST NOT) | 不得 (MUST NOT) | 不得 (MUST NOT) |
| 消息 | 应该 (SHOULD) | 应该 (SHOULD) | 应该 (SHOULD) |
| 客户端标识符 | 不得 (MUST NOT) | 不得 (MUST NOT) | 可以 (MAY) |
| 供应商类标识符 | 可以 (MAY) | 可以 (MAY) | 可以 (MAY) |
| 服务器标识符 | 必须 (MUST) | 必须 (MUST) | 必须 (MUST) |
| 最大消息大小 | 不得 (MUST NOT) | 不得 (MUST NOT) | 不得 (MUST NOT) |
| 所有其他 | 可以 (MAY) | 可以 (MAY) | 不得 (MUST NOT) |
表3: DHCP服务器使用的字段和选项
一旦确定了网络地址和租期, 服务器就会使用提供的配置参数构造DHCPOFFER消息。重要的是, 所有DHCP服务器返回相同的参数 (可能新分配的网络地址除外), 以确保无论客户端选择哪个服务器, 客户端行为都是可预测的。配置参数必须通过按以下给定的顺序应用以下规则来选择。网络管理员负责配置多个DHCP服务器以确保来自这些服务器的响应一致。服务器必须向客户端返回:
- 客户端的网络地址, 由本节前面给出的规则确定,
- 客户端租期的到期时间, 由本节前面给出的规则确定,
- 客户端请求的参数, 根据以下规则:
- 如果服务器已明确配置参数的默认值, 则服务器必须在'option'字段的适当选项中包含该值, 否则
- 如果服务器将参数识别为主机需求文档中定义的参数, 则服务器必须在'option'字段的适当选项中包含主机需求文档中给出的该参数的默认值, 否则
- 服务器不得返回该参数的值,
- 服务器必须提供尽可能多的请求参数, 并且必须省略它无法提供的任何参数。除非DHCP选项和BOOTP供应商扩展文档中明确允许, 否则服务器必须仅包含每个请求的参数一次。
- 现有绑定中与主机需求文档默认值不同的任何参数,
- 特定于此客户端的任何参数 (由DHCPDISCOVER或DHCPREQUEST消息中'chaddr'或'客户端标识符'的内容标识), 例如, 由网络管理员配置,
- 特定于此客户端类的任何参数 (由DHCPDISCOVER或DHCPREQUEST消息中'供应商类标识符'选项的内容标识), 例如, 由网络管理员配置; 参数必须通过客户端的供应商类标识符与服务器中标识的客户端类之间的精确匹配来标识,
- 客户端子网上具有非默认值的参数。
服务器可以选择返回用于确定DHCPOFFER消息中参数的'供应商类标识符', 以帮助客户端选择接受哪个DHCPOFFER。服务器将DHCPDISCOVER消息中的'xid'字段插入到DHCPOFFER消息的'xid'字段中, 并将DHCPOFFER消息发送给请求客户端。
4.3.2 DHCPREQUEST消息 (DHCPREQUEST message)
DHCPREQUEST消息可能来自响应来自服务器的DHCPOFFER消息的客户端, 来自验证先前分配的IP地址的客户端或来自延长网络地址租期的客户端。如果DHCPREQUEST消息包含'服务器标识符'选项, 则该消息是响应DHCPOFFER消息的。否则, 该消息是验证或延长现有租期的请求。如果客户端在DHCPREQUEST消息中使用'客户端标识符', 则它必须在所有后续消息中使用相同的'客户端标识符'。如果客户端在DHCPDISCOVER消息中包含请求参数的列表, 则它必须在所有后续消息中包含该列表。
DHCPACK消息中的任何配置参数不应该与客户端正在响应的较早DHCPOFFER消息中的参数冲突。客户端应该使用DHCPACK消息中的参数进行配置。
客户端按如下方式发送DHCPREQUEST消息:
SELECTING状态期间生成的DHCPREQUEST:
客户端在'服务器标识符'中插入所选服务器的地址, 'ciaddr'必须为零, '请求的IP地址'必须填写所选DHCPOFFER的yiaddr值。
请注意, 客户端可以选择收集多条DHCPOFFER消息并选择"最佳"提供。客户端通过在DHCPREQUEST消息中标识提供服务器来指示其选择。如果客户端没有收到可接受的提供, 则客户端可以选择尝试另一条DHCPDISCOVER消息。因此, 服务器可能不会收到特定的DHCPREQUEST, 从中他们可以决定客户端是否接受了提供。因为服务器没有基于DHCPOFFER提交任何网络地址分配, 所以服务器可以自由地重用提供的网络地址来响应后续请求。作为实现细节, 服务器不应该重用提供的地址, 并且可以使用实现特定的超时机制来决定何时重用提供的地址。
INIT-REBOOT状态期间生成的DHCPREQUEST:
'服务器标识符'不得填写, '请求的IP地址'选项必须填写客户端对其先前分配地址的概念。'ciaddr'必须为零。客户端正在寻求验证先前分配的缓存配置。如果'请求的IP地址'不正确或在错误的网络上, 服务器应该向客户端发送DHCPNAK消息。
通过检查'giaddr'、'请求的IP地址'选项的内容和数据库查找来确定处于INIT-REBOOT状态的客户端是否在正确的网络上。如果DHCP服务器检测到客户端在错误的网络上 (即, 将本地子网掩码或远程子网掩码 (如果'giaddr'不为零) 应用于'请求的IP地址'选项值的结果与现实不匹配), 则服务器应该向客户端发送DHCPNAK消息。
如果网络正确, 则DHCP服务器应该检查客户端对其IP地址的概念是否正确。如果不正确, 则服务器应该向客户端发送DHCPNAK消息。如果DHCP服务器没有此客户端的记录, 则它必须保持沉默, 并且可以向网络管理员输出警告。这种行为对于同一线路上非通信DHCP服务器的和平共存是必要的。
如果DHCPREQUEST消息中的'giaddr'为0x0, 则客户端与服务器在同一子网上。服务器必须将DHCPNAK消息广播到0xffffffff广播地址, 因为客户端可能没有正确的网络地址或子网掩码, 并且客户端可能不响应ARP请求。
如果在DHCPREQUEST消息中设置了'giaddr', 则客户端在不同的子网上。服务器必须在DHCPNAK中设置广播位, 以便中继代理将DHCPNAK广播到客户端, 因为客户端可能没有正确的网络地址或子网掩码, 并且客户端可能不响应ARP请求。
RENEWING状态期间生成的DHCPREQUEST:
'服务器标识符'不得填写, '请求的IP地址'选项不得填写, 'ciaddr'必须填写客户端的IP地址。在这种情况下, 客户端完全配置, 并且正在尝试延长其租期。此消息将是单播的, 因此不会有中继代理参与其传输。因为'giaddr'因此未填写, DHCP服务器将信任'ciaddr'中的值, 并在回复客户端时使用它。
客户端可以选择在T1之前续订或延长其租期。服务器可以选择不延长租期 (作为网络管理员的策略决定), 但无论如何都应该返回DHCPACK消息。
REBINDING状态期间生成的DHCPREQUEST:
'服务器标识符'不得填写, '请求的IP地址'选项不得填写, 'ciaddr'必须填写客户端的IP地址。在这种情况下, 客户端完全配置, 并且正在尝试延长其租期。此消息必须广播到0xffffffff IP广播地址。DHCP服务器应该在回复DHCPREQUEST之前检查'ciaddr'的正确性。
来自REBINDING客户端的DHCPREQUEST旨在适应具有多个DHCP服务器以及用于维护由多个服务器管理的租期之间一致性的机制的站点。DHCP服务器只有在具有本地管理权限的情况下才可以延长客户端的租期。
4.3.3 DHCPDECLINE消息 (DHCPDECLINE message)
如果服务器收到DHCPDECLINE消息, 则客户端通过其他方式发现建议的网络地址已在使用中。服务器必须将网络地址标记为不可用, 并且应该通知本地系统管理员可能的配置问题。
4.3.4 DHCPRELEASE消息 (DHCPRELEASE message)
收到DHCPRELEASE消息后, 服务器将网络地址标记为未分配。服务器应该保留客户端初始化参数的记录, 以便在响应来自客户端的后续请求时可能重用。
4.3.5 DHCPINFORM消息 (DHCPINFORM message)
服务器通过将DHCPACK消息直接发送到DHCPINFORM消息的'ciaddr'字段中给出的地址来响应DHCPINFORM消息。服务器不得向客户端发送租期到期时间, 并且不应该填写'yiaddr'。服务器在DHCPACK消息中包含其他参数, 如第4.3.1节中定义的。
4.3.6 客户端消息 (Client messages)
表4详细说明了来自不同状态的客户端的消息之间的差异。
| INIT-REBOOT | SELECTING | RENEWING | REBINDING | |
|---|---|---|---|---|
| 广播/单播 | 广播 | 广播 | 单播 | 广播 |
| server-ip | 不得 (MUST NOT) | 必须 (MUST) | 不得 (MUST NOT) | 不得 (MUST NOT) |
| requested-ip | 必须 (MUST) | 必须 (MUST) | 不得 (MUST NOT) | 不得 (MUST NOT) |
| ciaddr | 零 | 零 | IP地址 | IP地址 |
表4: 来自不同状态的客户端消息
4.4 DHCP客户端行为 (DHCP client behavior)
图5给出了DHCP客户端的状态转换图。客户端可以从服务器接收以下消息:
- DHCPOFFER
- DHCPACK
- DHCPNAK
DHCPINFORM消息未在图5中显示。客户端只需发送DHCPINFORM并等待DHCPACK消息。一旦客户端选择了其参数, 它就完成了配置过程。
表5给出了客户端在DHCP消息中使用字段和选项的情况。本节的其余部分描述了DHCP客户端对每条可能的传入消息的操作。以下部分中的描述对应于先前在第3.1节中描述的完整配置过程, 后续部分中的文本对应于第3.2节中描述的简化配置过程。
DHCP客户端状态转换图 (State-transition diagram for DHCP clients)
-------- -------
| | +-------------------------->| |<-------------------+
| INIT- | | +-------------------->| INIT | |
| REBOOT |DHCPNAK/ +---------->| |<---+ |
| |重启 | | ------- | |
-------- | DHCPNAK/ | | |
| 丢弃提供 | -/发送DHCPDISCOVER |
-/发送DHCPREQUEST | | |
| | | DHCPACK v | |
----------- | (不接受)/ ----------- | |
| | | 发送DHCPDECLINE | | |
| REBOOTING | | | | SELECTING |<----+ |
| | | / | | |DHCPOFFER/ |
----------- | / ----------- | |收集 |
| | / | | | 回复 |
DHCPACK/ | / +----------------+ +-------+ |
记录租期, 设置| | v 选择提供/ |
定时器T1, T2 ------------ 发送DHCPREQUEST | |
| +----->| | DHCPNAK, 租期过期/ |
| | | REQUESTING | 停止网络 |
DHCPOFFER/ | | | |
丢弃 ------------ | |
| | | | ----------- |
| +--------+ DHCPACK/ | | |
| 记录租期, 设置 -----| REBINDING | |
| 定时器T1, T2 / | | |
| | DHCPACK/ ----------- |
| v 记录租期, 设置 ^ |
+----------------> ------- /定时器T1,T2 | |
+----->| |<---+ | |
| | BOUND |<---+ | |
DHCPOFFER, DHCPACK, | | | T2过期/ DHCPNAK/
DHCPNAK/丢弃 ------- | 广播 停止网络
| | | | DHCPREQUEST |
+-------+ | DHCPACK/ | |
T1过期/ 记录租期, 设置 | |
发送DHCPREQUEST 定时器T1, T2 | |
到租用服务器 | | |
| ---------- | |
| | |------------+ |
+->| RENEWING | |
| |----------------------------+
----------
图5: DHCP客户端的状态转换图
4.4.1 初始化和网络地址分配 (Initialization and allocation of network address)
客户端从INIT状态开始并形成DHCPDISCOVER消息。客户端应该在一到十秒之间等待随机时间, 以使启动时DHCP的使用不同步。客户端将'ciaddr'设置为0x00000000。客户端可以通过包含'参数请求列表'选项来请求特定参数。客户端可以通过包含'请求的IP地址'和'IP地址租期时间'选项来建议网络地址和/或租期时间。如果需要传递DHCP回复消息, 客户端必须在'chaddr'字段中包含其硬件地址。客户端可以在'客户端标识符'选项中包含不同的唯一标识符, 如第4.2节所述。如果客户端在DHCPDISCOVER消息中包含请求参数的列表, 则它必须在所有后续消息中包含该列表。
客户端生成并记录随机事务标识符, 并将该标识符插入'xid'字段。客户端记录自己的本地时间, 以供以后用于计算租期到期。然后, 客户端在本地硬件广播地址上将DHCPDISCOVER广播到0xffffffff IP广播地址和'DHCP服务器'UDP端口。
如果到达的DHCPOFFER消息的'xid'与最近的DHCPDISCOVER消息的'xid'不匹配, 则必须静默丢弃DHCPOFFER消息。任何到达的DHCPACK消息必须静默丢弃。
客户端在一段时间内收集DHCPOFFER消息, 从 (可能许多) 传入的DHCPOFFER消息中选择一条DHCPOFFER消息 (例如, 第一条DHCPOFFER消息或来自先前使用的服务器的DHCPOFFER消息), 并从DHCPOFFER消息中的'服务器标识符'选项中提取服务器地址。客户端收集消息的时间和用于选择一个DHCPOFFER的机制取决于实现。
DHCP客户端使用的字段和选项表 (Fields and options used by DHCP clients)
| 字段 | DHCPDISCOVER DHCPINFORM | DHCPREQUEST | DHCPDECLINE, DHCPRELEASE |
|---|---|---|---|
| op | BOOTREQUEST | BOOTREQUEST | BOOTREQUEST |
| htype | (来自"分配号码" RFC) | ||
| hlen | (硬件地址长度,以八位字节为单位) | ||
| hops | 0 | 0 | 0 |
| xid | 由客户端选择 | 来自服务器DHCPOFFER消息的'xid' | 由客户端选择 |
| secs | 0或自DHCP过程开始以来的秒数 | 0或自DHCP过程开始以来的秒数 | 0 |
| flags | 如果客户端需要广播回复则设置'BROADCAST'标志 | 如果客户端需要广播回复则设置'BROADCAST'标志 | 0 |
| ciaddr | 0 (DHCPDISCOVER) 客户端的网络地址 (DHCPINFORM) | 0或客户端的网络地址 (BOUND/RENEW/REBIND) | 0 (DHCPDECLINE) 客户端的网络地址 (DHCPRELEASE) |
| yiaddr | 0 | 0 | 0 |
| siaddr | 0 | 0 | 0 |
| giaddr | 0 | 0 | 0 |
| chaddr | 客户端的硬件地址 | 客户端的硬件地址 | 客户端的硬件地址 |
| sname | 选项 (如果在'sname/file'选项中指示); 否则未使用 | 选项 (如果在'sname/file'选项中指示); 否则未使用 | (未使用) |
| file | 选项 (如果在'sname/file'选项中指示); 否则未使用 | 选项 (如果在'sname/file'选项中指示); 否则未使用 | (未使用) |
| options | 选项 | 选项 | (未使用) |
| 选项 | DHCPDISCOVER DHCPINFORM | DHCPREQUEST | DHCPDECLINE, DHCPRELEASE |
|---|---|---|---|
| 请求的IP地址 | 可以 (MAY) (DISCOVER) 不得 (MUST NOT) (INFORM) | 必须 (MUST) (SELECTING或INIT-REBOOT中) 不得 (MUST NOT) (BOUND或RENEWING中) | 必须 (MUST) (DHCPDECLINE), 不得 (MUST NOT) (DHCPRELEASE) |
| IP地址租期时间 | 可以 (MAY) (DISCOVER) 不得 (MUST NOT) (INFORM) | 可以 (MAY) | 不得 (MUST NOT) |
| 使用'file'/'sname'字段 | 可以 (MAY) | 可以 (MAY) | 可以 (MAY) |
| DHCP消息类型 | DHCPDISCOVER/ DHCPINFORM | DHCPREQUEST | DHCPDECLINE/ DHCPRELEASE |
| 客户端标识符 | 可以 (MAY) | 可以 (MAY) | 可以 (MAY) |
| 供应商类标识符 | 可以 (MAY) | 可以 (MAY) | 不得 (MUST NOT) |
| 服务器标识符 | 不得 (MUST NOT) | 必须 (MUST) (SELECTING后) 不得 (MUST NOT) (INIT-REBOOT, BOUND, RENEWING或REBINDING后) | 必须 (MUST) |
| 参数请求列表 | 可以 (MAY) | 可以 (MAY) | 不得 (MUST NOT) |
| 最大消息大小 | 可以 (MAY) | 可以 (MAY) | 不得 (MUST NOT) |
| 消息 | 不应该 (SHOULD NOT) | 不应该 (SHOULD NOT) | 应该 (SHOULD) |
| 站点特定 | 可以 (MAY) | 可以 (MAY) | 不得 (MUST NOT) |
| 所有其他 | 可以 (MAY) | 可以 (MAY) | 不得 (MUST NOT) |
表5: DHCP客户端使用的字段和选项
如果参数可接受, 客户端从'服务器标识符'字段记录提供参数的服务器的地址, 并在DHCPREQUEST广播消息的'服务器标识符'字段中发送该地址。一旦来自服务器的DHCPACK消息到达, 客户端就被初始化并移至BOUND状态。DHCPREQUEST消息包含与DHCPOFFER消息相同的'xid'。客户端将租期到期时间记录为发送原始请求的时间与DHCPACK消息中租期持续时间的总和。客户端应该对建议的地址执行检查, 以确保地址尚未使用。例如, 如果客户端在支持ARP的网络上, 则客户端可以为建议的请求发出ARP请求。当为建议的地址广播ARP请求时, 客户端必须将自己的硬件地址填写为发送者的硬件地址, 并将0填写为发送者的IP地址, 以避免混淆同一子网上其他主机中的ARP缓存。如果网络地址似乎正在使用中, 则客户端必须向服务器发送DHCPDECLINE消息。客户端应该广播ARP回复以宣布客户端的新IP地址并清除客户端子网上主机中的任何过时ARP缓存条目。
4.4.2 使用已知网络地址初始化 (Initialization with known network address)
客户端从INIT-REBOOT状态开始并发送DHCPREQUEST消息。客户端必须在DHCPREQUEST消息中插入其已知的网络地址作为'请求的IP地址'选项。客户端可以通过包含'参数请求列表'选项来请求特定配置参数。客户端生成并记录随机事务标识符, 并将该标识符插入'xid'字段。客户端记录自己的本地时间, 以供以后用于计算租期到期。客户端不得在DHCPREQUEST消息中包含'服务器标识符'。然后, 客户端在本地硬件广播地址上将DHCPREQUEST广播到'DHCP服务器'UDP端口。
一旦来自任何服务器的'xid'字段与客户端的DHCPREQUEST消息中的字段匹配的DHCPACK消息到达, 客户端就被初始化并移至BOUND状态。客户端将租期到期时间记录为发送DHCPREQUEST消息的时间与DHCPACK消息中租期持续时间的总和。
4.4.3 使用外部分配的网络地址初始化 (Initialization with an externally assigned network address)
客户端发送DHCPINFORM消息。客户端可以通过包含'参数请求列表'选项来请求特定配置参数。客户端生成并记录随机事务标识符, 并将该标识符插入'xid'字段。客户端将自己的网络地址放在'ciaddr'字段中。客户端不应该请求租期时间参数。
如果客户端知道服务器的地址, 则客户端将DHCPINFORM单播到DHCP服务器, 否则它将消息广播到有限 (全1) 广播地址。DHCPINFORM消息必须定向到'DHCP服务器'UDP端口。
一旦来自任何服务器的'xid'字段与客户端的DHCPINFORM消息中的字段匹配的DHCPACK消息到达, 客户端就被初始化。
如果客户端在合理的时间内 (60秒或4次尝试, 如果使用第4.1节中建议的超时) 没有收到DHCPACK, 则它应该显示一条消息通知用户该问题, 然后应该使用适当的默认值开始网络处理, 如附录A所示。
4.4.4 广播和单播的使用 (Use of broadcast and unicast)
DHCP客户端广播DHCPDISCOVER、DHCPREQUEST和DHCPINFORM消息, 除非客户端知道DHCP服务器的地址。客户端将DHCPRELEASE消息单播到服务器。因为客户端拒绝使用服务器提供的IP地址, 所以客户端广播DHCPDECLINE消息。
当DHCP客户端在INIT或REBOOTING状态下知道DHCP服务器的地址时, 客户端可以在DHCPDISCOVER或DHCPREQUEST中使用该地址而不是IP广播地址。客户端还可以使用单播向已知的DHCP服务器发送DHCPINFORM消息。如果客户端没有收到发送到已知DHCP服务器的IP地址的DHCP消息的响应, 则DHCP客户端恢复使用IP广播地址。
4.4.5 重新获取和到期 (Reacquisition and expiration)
客户端维护两个时间T1和T2, 它们指定客户端尝试延长其在网络地址上的租期的时间。T1是客户端进入RENEWING状态并尝试联系最初发出客户端网络地址的服务器的时间。T2是客户端进入REBINDING状态并尝试联系任何服务器的时间。T1必须早于T2, T2又必须早于客户端租期到期的时间。
为了避免对同步时钟的需要, T1和T2在选项中表示为相对时间 [2]。
在时间T1, 客户端移至RENEWING状态并 (通过单播) 向服务器发送DHCPREQUEST消息以延长其租期。客户端将DHCPREQUEST中的'ciaddr'字段设置为其当前网络地址。客户端记录发送DHCPREQUEST消息的本地时间, 以用于计算租期到期时间。客户端不得在DHCPREQUEST消息中包含'服务器标识符'。
'xid'与客户端的DHCPREQUEST消息的'xid'不匹配的任何DHCPACK消息都将被静默丢弃。当客户端从服务器接收到DHCPACK时, 客户端将租期到期时间计算为客户端发送DHCPREQUEST消息的时间与DHCPACK消息中租期持续时间的总和。客户端已成功重新获取其网络地址, 返回BOUND状态并可以继续网络处理。
如果在时间T2之前没有DHCPACK到达, 则客户端移至REBINDING状态并 (通过广播) 发送DHCPREQUEST消息以延长其租期。客户端将DHCPREQUEST中的'ciaddr'字段设置为其当前网络地址。客户端不得在DHCPREQUEST消息中包含'服务器标识符'。
时间T1和T2由服务器通过选项配置。T1默认为 (0.5 * duration_of_lease)。T2默认为 (0.875 * duration_of_lease)。时间T1和T2应该在固定值周围选择一些随机"模糊", 以避免客户端重新获取的同步。
客户端可以选择在T1之前续订或延长其租期。服务器可以根据网络管理员设置的策略选择延长客户端的租期。服务器应该返回T1和T2, 并且它们的值应该从其原始值调整以考虑租期上的剩余时间。
在RENEWING和REBINDING状态下, 如果客户端没有收到对其DHCPREQUEST消息的响应, 则客户端应该在重新传输DHCPREQUEST消息之前等待直到T2 (在RENEWING状态下) 的剩余时间的一半和剩余租期时间的一半 (在REBINDING状态下), 最少60秒。
如果租期在客户端收到DHCPACK之前到期, 则客户端移至INIT状态, 必须立即停止任何其他网络处理并请求网络初始化参数, 就像客户端未初始化一样。如果客户端随后收到DHCPACK, 向该客户端分配其先前的网络地址, 则客户端应该继续网络处理。如果客户端被赋予新的网络地址, 则它不得继续使用先前的网络地址, 并且应该通知本地用户该问题。
4.4.6 DHCPRELEASE
如果客户端不再需要使用其分配的网络地址 (例如, 客户端正常关闭), 则客户端向服务器发送DHCPRELEASE消息。请注意, DHCP的正确操作不依赖于DHCPRELEASE消息的传输。