4. DHCP 客户端-服务器协议规范
在本节中, 我们假定 DHCP server 拥有一组网络地址, 可用于满足新地址请求. 每个服务器还会在本地永久存储中维护已分配地址和租约数据库.
4.1 构造和发送 DHCP 消息
DHCP clients 和 servers 都通过填写消息固定格式部分中的字段, 并在可变长度 option 区域追加带标签数据项来构造 DHCP 消息. options 区域首先包含四 octet 的 'magic cookie' (见第 3 节), 后面跟随 options. 最后一个 option 必须始终是 'end' option.
DHCP 使用 UDP 作为传输协议. 从客户端发往服务器的 DHCP 消息发送到 'DHCP server' 端口 (67), 从服务器发往客户端的 DHCP 消息发送到 'DHCP client' 端口 (68). 具有多个网络地址的服务器 (例如 multi-homed host) 可以在发出的 DHCP 消息中使用其任一网络地址.
'server identifier' 字段既用于在 DHCP 消息中标识 DHCP server, 也用作从客户端到服务器的目的地址. 具有多个网络地址的服务器必须准备好接受其任一网络地址作为 DHCP 消息中标识该服务器的地址. 为适应可能不完整的网络连通性, 服务器必须选择一个据其所知可从客户端到达的地址作为 'server identifier'. 例如, 如果 DHCP server 和 DHCP client 连接在同一子网 (即来自客户端消息中的 'giaddr' 字段为零), 服务器应选择其在该子网上通信所用的 IP 地址作为 'server identifier'. 如果服务器在该子网上使用多个 IP 地址, 可使用其中任一地址. 如果服务器通过 DHCP relay agent 收到消息, 服务器应选择接收该消息的接口上的地址作为 'server identifier' (除非服务器有其他更好的选择依据). DHCP clients 对 DHCP server 的任何单播请求都必须使用 'server identifier' option 中提供的 IP 地址.
客户端在获得自身 IP 地址之前广播的 DHCP 消息, 其 IP 头中的源地址字段必须设为 0.
如果来自客户端的 DHCP 消息中 'giaddr' 字段非零, 服务器会把任何返回消息发送到 'giaddr' 中出现地址所对应 BOOTP relay agent 的 'DHCP server' 端口. 如果 'giaddr' 字段为零且 'ciaddr' 字段非零, 服务器将 DHCPOFFER 和 DHCPACK 消息单播到 'ciaddr' 中的地址. 如果 'giaddr' 为零, 'ciaddr' 为零, 且 broadcast bit 已设置, 服务器将 DHCPOFFER 和 DHCPACK 消息广播到 0xffffffff. 如果 broadcast bit 未设置, 'giaddr' 为零且 'ciaddr' 为零, 服务器将 DHCPOFFER 和 DHCPACK 消息单播到客户端硬件地址和 'yiaddr' 地址. 在所有情况下, 当 'giaddr' 为零时, 服务器都会把任何 DHCPNAK 消息广播到 0xffffffff.
如果 DHCP 消息中的 options 扩展到 'sname' 和 'file' 字段, 'option overload' option MUST 出现在 'options' 字段中, 其值为 RFC 1533 规定的 1, 2 或 3. 如果 'option overload' option 出现在 'options' 字段中, 'options' 字段中的 options MUST 由 'end' option 终止, 并 MAY 包含一个或多个 'pad' options 来填满 options 字段. 'sname' 和 'file' 字段中的 options (如果按 'option overload' option 指示正在使用) MUST 从该字段的第一个 octet 开始, MUST 由 'end' option 终止, 并 MUST 后跟 'pad' options 以填满该字段剩余部分. 'options', 'sname' 和 'file' 字段中的任何单个 option MUST 完全包含在该字段内. MUST 首先解释 'options' 字段中的 options, 以便解释任何 'option overload' options. 接下来 MUST 解释 'file' 字段 (如果 'option overload' option 指示 'file' 字段包含 DHCP options), 然后解释 'sname' 字段.
要在 'option' tag 中传递的值可能太长, 无法放入单个 option 可用的 255 octets 中 (例如 'router' option [21] 中的路由器列表). 除非 options 文档另有规定, options 只能出现一次. 客户端会把同一 option 的多个实例值串接成单个参数列表用于配置.
DHCP clients 负责所有消息重传. 客户端 MUST 采用包含随机化指数退避算法的重传策略, 以确定重传之间的延迟. 重传之间的延迟 SHOULD 根据客户端和服务器之间互联网络的特性选择, 以留出足够时间交付来自服务器的回复. 例如, 在 10Mb/sec Ethernet 互联网络中, 第一次重传前的延迟 SHOULD 为 4 秒, 并用从 -1 到 +1 范围内均匀随机数的值进行随机化. 时钟分辨率粒度小于一秒的客户端可以选择非整数随机化值. 下一次重传前的延迟 SHOULD 为 8 秒, 并用从 -1 到 +1 范围内均匀随机数的值进行随机化. 后续重传的重传延迟 SHOULD 加倍, 直到最大 64 秒. 客户端 MAY 向用户提供重传尝试指示, 作为配置过程进度的提示.
'xid' 字段由客户端用于将收到的 DHCP 消息与未完成请求匹配. DHCP client MUST 选择 'xid', 使其尽量减少使用与另一个客户端所用 'xid' 相同值的机会. 例如, 客户端可以在每次重启时选择不同的随机初始 'xid', 随后在下一次重启前使用顺序 'xid'. 每次重传是否选择新的 'xid' 是实现决定. 客户端可以选择重用同一 'xid', 也可以为每条重传消息选择新的 'xid'.
通常, DHCP servers 和 BOOTP relay agents 会尝试使用单播传递, 将 DHCPOFFER, DHCPACK 和 DHCPNAK 消息直接交付给客户端. IP 目的地址 (在 IP 头中) 设为 DHCP 'yiaddr' 地址, 链路层目的地址设为 DHCP 'chaddr' 地址. 遗憾的是, 一些客户端实现在配置有效 IP 地址之前无法接收这类单播 IP 数据报 (导致死锁: 在客户端配置 IP 地址之前无法交付客户端 IP 地址).
在其协议软件配置 IP 地址之前无法接收单播 IP 数据报的客户端, SHOULD 在其发送的任何 DHCPDISCOVER 或 DHCPREQUEST 消息中将 'flags' 字段的 BROADCAST bit 设为 1. BROADCAST bit 会提示 DHCP servers 和 BOOTP relay agents 在客户端所在子网上广播任何发给客户端的消息. 在协议软件配置前即可接收单播 IP 数据报的客户端 SHOULD 将 BROADCAST bit 清为 0. BOOTP 澄清文档讨论了使用 BROADCAST bit 的影响 [21].
直接向 DHCP client 发送或中继 DHCP 消息的服务器或 relay agent (即不是发给 'giaddr' 字段指定的 relay agent) SHOULD 检查 'flags' 字段中的 BROADCAST bit. 如果该位设为 1, DHCP 消息 SHOULD 作为 IP 广播发送, 使用 IP 广播地址 (最好是 0xffffffff) 作为 IP 目的地址, 并使用链路层广播地址作为链路层目的地址. 如果 BROADCAST bit 清为 0, 消息 SHOULD 作为 IP 单播发送到 'yiaddr' 字段指定的 IP 地址和 'chaddr' 字段指定的链路层地址. 如果无法单播, 消息 MAY 作为 IP 广播发送, 使用 IP 广播地址 (最好是 0xffffffff) 作为 IP 目的地址, 并使用链路层广播地址作为链路层目的地址.
4.2 DHCP server 管理控制
DHCP servers 不需要响应收到的每条 DHCPDISCOVER 和 DHCPREQUEST 消息. 例如, 为严格控制连接到网络的客户端, 网络管理员可以选择配置 DHCP servers 仅响应已通过某种外部机制预先注册的客户端. DHCP 规范只描述客户端和服务器选择交互时的交互过程; 描述系统管理员可能希望使用的所有管理控制超出 DHCP 规范范围. 具体 DHCP server 实现可以纳入网络管理员期望的任何控制或策略.
在某些环境中, DHCP servers 在确定特定客户端的正确参数时, 必须考虑 DHCPDISCOVER 或 DHCPREQUEST 消息中包含的 vendor class options 值.
DHCP server 需要使用某种唯一标识符将客户端与其租约关联. 客户端 MAY 选择通过 'client identifier' option 显式提供标识符. 如果客户端提供 'client identifier', 客户端 MUST 在所有后续消息中使用同一 'client identifier', 服务器 MUST 使用该标识符识别客户端. 如果客户端未提供 'client identifier' option, 服务器 MUST 使用 'chaddr' 字段内容识别客户端. 为了 DHCP 正确运行, 客户端在 'client identifier' option 中使用在其所连接子网内唯一的标识符至关重要. 使用 'chaddr' 作为客户端唯一标识符可能导致意外结果, 因为该标识符可能与可移动到新客户端的硬件接口关联. 一些站点可能选择使用制造商序列号作为 'client identifier', 以避免硬件接口在计算机之间转移导致客户端网络地址意外变化. 站点也可以选择使用 DNS 名称作为 'client identifier', 使客户端网络地址与 DNS 名称而不是特定硬件机器关联.
DHCP clients 可以自由使用任何策略, 在收到 DHCPOFFER 消息的服务器中选择 DHCP server. DHCP 的客户端实现 SHOULD 提供一种机制, 让用户直接选择 'vendor class identifier' 值.
4.3 DHCP server 行为
DHCP server 根据该客户端 binding 的当前状态处理来自客户端的传入 DHCP 消息. DHCP server 可以从客户端接收以下消息:
- DHCPDISCOVER
- DHCPREQUEST
- DHCPDECLINE
- DHCPRELEASE
- DHCPINFORM
表 3 给出服务器在 DHCP 消息中对字段和 options 的使用. 本节其余部分描述 DHCP server 针对每种可能传入消息采取的动作.
4.3.1 DHCPDISCOVER 消息
当服务器从客户端收到 DHCPDISCOVER 消息时, 服务器为请求客户端选择网络地址. 如果没有可用地址, 服务器可以选择向系统管理员报告问题. 如果有可用地址, 新地址 SHOULD 按如下方式选择:
- 客户端当前 binding 中记录的客户端当前地址, ELSE
- 客户端已过期或已释放 binding 中记录的客户端先前地址, 前提是该地址在服务器可用地址池中且尚未分配, ELSE
- 'Requested IP Address' option 中请求的地址, 前提是该地址有效且尚未分配, ELSE
- 从服务器可用地址池分配的新地址; 地址基于接收该消息的子网 ('giaddr' 为 0 时) 或转发该消息的 relay agent 地址 ('giaddr' 非 0 时) 选择.
如第 4.2 节所述, 出于管理原因, 服务器 MAY 分配一个不同于所请求地址的地址, 或即使有空闲地址也可以拒绝向特定客户端分配地址.
注意, 在某些网络架构中 (例如一个物理网段分配了多个 IP 子网的 internets), DHCP client 可能应被分配一个不同于 'giaddr' 中记录地址所在子网的地址. 因此, DHCP 不要求客户端必须从 'giaddr' 所在子网分配地址. 服务器可以自由选择其他子网, 而描述如何选择已分配 IP 地址的方法超出 DHCP 规范范围.
虽然 DHCP 正确运行并不要求这样做, 但在客户端响应服务器 DHCPOFFER 消息之前, 服务器 SHOULD NOT 重用所选网络地址. 服务器可以选择记录该地址已提供给客户端.
服务器还必须为租约选择过期时间, 如下:
- IF 客户端未在 DHCPDISCOVER 消息中请求特定租约且客户端已有已分配网络地址, 服务器返回先前分配给该地址的租约过期时间 (注意, 客户端必须显式请求特定租约才能延长先前分配地址的过期时间), ELSE
- IF 客户端未在 DHCPDISCOVER 消息中请求特定租约且客户端没有已分配网络地址, 服务器分配本地配置的默认租约时间, ELSE
- IF 客户端在 DHCPDISCOVER 消息中请求了特定租约 (无论客户端是否已有已分配网络地址), 服务器可以选择返回所请求租约 (如果该租约符合本地策略), 或选择另一个租约.
DHCP servers 使用的字段和 options
| Field | DHCPOFFER | DHCPACK | DHCPNAK |
|---|---|---|---|
| op | BOOTREPLY | BOOTREPLY | BOOTREPLY |
| htype | (from "Assigned Numbers" RFC) | ||
| hlen | (hardware address length in octets) | ||
| hops | 0 | 0 | 0 |
| xid | 'xid' from client DHCPDISCOVER message | 'xid' from client DHCPREQUEST message | 'xid' from client DHCPREQUEST message |
| secs | 0 | 0 | 0 |
| ciaddr | 0 | 'ciaddr' from DHCPREQUEST or 0 | 0 |
| yiaddr | IP address offered to client | IP address assigned to client | 0 |
| siaddr | IP address of next bootstrap server | IP address of next bootstrap server | 0 |
| flags | 'flags' from client DHCPDISCOVER message | 'flags' from client DHCPREQUEST message | 'flags' from client DHCPREQUEST message |
| giaddr | 'giaddr' from client DHCPDISCOVER message | 'giaddr' from client DHCPREQUEST message | 'giaddr' from client DHCPREQUEST message |
| chaddr | 'chaddr' from client DHCPDISCOVER message | 'chaddr' from client DHCPREQUEST message | 'chaddr' from client DHCPREQUEST message |
| sname | Server host name or options | Server host name or options | (unused) |
| file | Client boot file name or options | Client boot file name or options | (unused) |
| options | options | options |
| Option | DHCPOFFER | DHCPACK | DHCPNAK |
|---|---|---|---|
| Requested IP address | MUST NOT | MUST NOT | MUST NOT |
| IP address lease time | MUST | MUST (DHCPREQUEST)<br/>MUST NOT (DHCPINFORM) | MUST NOT |
| Use 'file'/'sname' fields | MAY | MAY | MUST NOT |
| DHCP message type | DHCPOFFER | DHCPACK | DHCPNAK |
| Parameter request list | MUST NOT | MUST NOT | MUST NOT |
| Message | SHOULD | SHOULD | SHOULD |
| Client identifier | MUST NOT | MUST NOT | MAY |
| Vendor class identifier | MAY | MAY | MAY |
| Server identifier | MUST | MUST | MUST |
| Maximum message size | MUST NOT | MUST NOT | MUST NOT |
| All others | MAY | MAY | MUST NOT |
表 3: DHCP servers 使用的字段和 options
确定网络地址和租约后, 服务器使用所提供的配置参数构造 DHCPOFFER 消息. 重要的是, 所有 DHCP servers 都应返回相同参数 (新分配网络地址这一可能例外除外), 以确保无论客户端选择哪个服务器, 客户端行为都是可预测的. 配置参数 MUST 按以下给定顺序应用规则来选择. 网络管理员负责配置多个 DHCP servers, 以确保这些服务器返回一致响应. 服务器 MUST 向客户端返回:
- 客户端网络地址, 按本节前面给出的规则确定,
- 客户端租约过期时间, 按本节前面给出的规则确定,
- 客户端请求的参数, 按以下规则:
- IF 服务器已为该参数显式配置默认值, 服务器 MUST 在 'option' 字段中适当 option 内包含该值, ELSE
- IF 服务器识别该参数为 Host Requirements Document 中定义的参数, 服务器 MUST 在 'option' 字段中适当 option 内包含 Host Requirements Document 给出的该参数默认值, ELSE
- 服务器 MUST NOT 返回该参数的值,
- 服务器 MUST 尽可能提供更多请求参数, 并 MUST 省略无法提供的任何参数. 除非 DHCP Options and BOOTP Vendor Extensions 文档明确允许, 服务器 MUST 只包含每个请求参数一次.
- 现有 binding 中任何不同于 Host Requirements Document 默认值的参数,
- 特定于该客户端的任何参数 (由 DHCPDISCOVER 或 DHCPREQUEST 消息中 'chaddr' 或 'client identifier' 内容标识), 例如由网络管理员配置的参数,
- 特定于该客户端类别的任何参数 (由 DHCPDISCOVER 或 DHCPREQUEST 消息中 'Vendor class identifier' option 内容标识), 例如由网络管理员配置的参数; 参数必须通过客户端 vendor class identifiers 与服务器中标识的 client class 精确匹配来识别,
- 客户端子网上具有非默认值的参数.
服务器 MAY 选择在 DHCPOFFER 消息中返回用于确定参数的 'vendor class identifier', 以帮助客户端选择接受哪个 DHCPOFFER. 服务器将 DHCPDISCOVER 消息中的 'xid' 字段插入 DHCPOFFER 消息的 'xid' 字段, 并将 DHCPOFFER 消息发送给请求客户端.
4.3.2 DHCPREQUEST 消息
DHCPREQUEST 消息可能来自响应服务器 DHCPOFFER 消息的客户端, 也可能来自验证先前分配 IP 地址的客户端, 或来自延长网络地址租约的客户端. 如果 DHCPREQUEST 消息包含 'server identifier' option, 该消息就是对 DHCPOFFER 消息的响应. 否则, 该消息是验证或延长现有租约的请求. 如果客户端在 DHCPREQUEST 消息中使用 'client identifier', 它 MUST 在所有后续消息中使用同一 'client identifier'. 如果客户端在 DHCPDISCOVER 消息中包含请求参数列表, 它 MUST 在所有后续消息中包含该列表.
DHCPACK 消息中的任何配置参数 SHOULD NOT 与客户端正在响应的较早 DHCPOFFER 消息中的参数冲突. 客户端 SHOULD 使用 DHCPACK 消息中的参数进行配置.
客户端按如下方式发送 DHCPREQUEST 消息:
SELECTING 状态期间生成的 DHCPREQUEST:
客户端在 'server identifier' 中插入所选服务器地址, 'ciaddr' MUST 为零, 'requested IP address' MUST 填入所选 DHCPOFFER 中的 yiaddr 值.
注意, 客户端可以选择收集多个 DHCPOFFER 消息并选择 "best" offer. 客户端通过在 DHCPREQUEST 消息中标识提供该 offer 的服务器来表示其选择. 如果客户端没有收到可接受的 offers, 客户端可以选择尝试另一条 DHCPDISCOVER 消息. 因此, 服务器可能收不到可用于判断客户端是否接受 offer 的具体 DHCPREQUEST. 由于服务器尚未基于 DHCPOFFER 承诺任何网络地址分配, 因而服务器可自由重用已提供的网络地址来响应后续请求. 作为实现细节, 服务器不应重用已提供地址, 并可以使用实现特定的超时机制来决定何时重用已提供地址.
INIT-REBOOT 状态期间生成的 DHCPREQUEST:
'server identifier' MUST NOT 填写, 'requested IP address' option MUST 填入客户端认为先前分配给自己的地址. 'ciaddr' MUST 为零. 客户端正在尝试验证先前分配并缓存的配置. 如果 'requested IP address' 不正确或位于错误网络, 服务器 SHOULD 向客户端发送 DHCPNAK 消息.
判断 INIT-REBOOT 状态中的客户端是否位于正确网络, 需要检查 'giaddr', 'requested IP address' option 内容并执行数据库查找. 如果 DHCP server 检测到客户端位于错误网络 (即把本地子网掩码或远程子网掩码 ('giaddr' 非零时) 应用于 'requested IP address' option 值的结果与现实不符), 则服务器 SHOULD 向客户端发送 DHCPNAK 消息.
如果网络正确, DHCP server 应检查客户端对其 IP 地址的认知是否正确. 如果不正确, 服务器 SHOULD 向客户端发送 DHCPNAK 消息. 如果 DHCP server 没有该客户端记录, 它 MUST 保持沉默, 并 MAY 向网络管理员输出警告. 这种行为是同一线路上不通信 DHCP servers 和平共存所必需的.
如果 DHCPREQUEST 消息中的 'giaddr' 为 0x0, 客户端与服务器在同一子网上. 服务器 MUST 将 DHCPNAK 消息广播到 0xffffffff 广播地址, 因为客户端可能没有正确网络地址或子网掩码, 并且可能不响应 ARP 请求.
如果 DHCPREQUEST 消息中设置了 'giaddr', 客户端位于不同子网. 服务器 MUST 在 DHCPNAK 中设置 broadcast bit, 以便 relay agent 将 DHCPNAK 广播给客户端, 因为客户端可能没有正确网络地址或子网掩码, 并且可能不响应 ARP 请求.
RENEWING 状态期间生成的 DHCPREQUEST:
'server identifier' MUST NOT 填写, 'requested IP address' option MUST NOT 填写, 'ciaddr' MUST 填入客户端 IP 地址. 在这种情况下, 客户端已完全配置, 并正在尝试延长其租约. 该消息将单播, 因此不会有 relay agents 参与其传输. 因为 'giaddr' 因此未填写, DHCP server 会信任 'ciaddr' 中的值, 并在回复客户端时使用它.
客户端 MAY 选择在 T1 之前续订或延长其租约. 服务器可以选择不延长租约 (作为网络管理员的策略决定), 但无论如何都应返回 DHCPACK 消息.
REBINDING 状态期间生成的 DHCPREQUEST:
'server identifier' MUST NOT 填写, 'requested IP address' option MUST NOT 填写, 'ciaddr' MUST 填入客户端 IP 地址. 在这种情况下, 客户端已完全配置, 并正在尝试延长其租约. 该消息 MUST 广播到 0xffffffff IP 广播地址. DHCP server SHOULD 在回复 DHCPREQUEST 前检查 'ciaddr' 的正确性.
来自 REBINDING 客户端的 DHCPREQUEST 旨在适应具有多个 DHCP servers 且具有维护多个服务器所管理租约之间 binding 一致性机制的站点. DHCP server 只有在具有本地管理授权时 MAY 延长客户端租约.
4.3.3 DHCPDECLINE 消息
如果服务器收到 DHCPDECLINE 消息, 表示客户端已通过其他方式发现建议的网络地址已在使用. 服务器 MUST 将该网络地址标记为不可用, 并 SHOULD 通知本地系统管理员可能存在配置问题.
4.3.4 DHCPRELEASE 消息
收到 DHCPRELEASE 消息后, 服务器将该网络地址标记为未分配. 服务器 SHOULD 保留客户端初始化参数记录, 以便响应来自该客户端的后续请求时可能重用.
4.3.5 DHCPINFORM 消息
服务器通过直接向 DHCPINFORM 消息 'ciaddr' 字段给出的地址发送 DHCPACK 消息来响应 DHCPINFORM 消息. 服务器 MUST NOT 向客户端发送租约过期时间, 并 SHOULD NOT 填写 'yiaddr'. 服务器按第 4.3.1 节定义在 DHCPACK 消息中包含其他参数.
4.3.6 客户端消息
表 4 详细说明来自不同状态客户端的消息之间的差异.
| INIT-REBOOT | SELECTING | RENEWING | REBINDING | |
|---|---|---|---|---|
| Broadcast/unicast | Broadcast | Broadcast | Unicast | Broadcast |
| server-ip | MUST NOT | MUST | MUST NOT | MUST NOT |
| requested-ip | MUST | MUST | MUST NOT | MUST NOT |
| ciaddr | zero | zero | IP address | IP address |
表 4: 不同状态下的客户端消息
4.4 DHCP client 行为
图 5 给出 DHCP client 的状态转换图. 客户端可以从服务器接收以下消息:
- DHCPOFFER
- DHCPACK
- DHCPNAK
DHCPINFORM 消息未显示在图 5 中. 客户端只需发送 DHCPINFORM 并等待 DHCPACK 消息. 一旦客户端选择了其参数, 配置过程即结束.
表 5 给出客户端在 DHCP 消息中对字段和 options 的使用. 本节其余部分描述 DHCP client 针对每种可能传入消息采取的动作. 下一小节中的描述对应于第 3.1 节先前描述的完整配置过程, 再下一小节中的文本对应于第 3.2 节描述的简化配置过程.
DHCP clients 状态转换图
-------- -------
| | +-------------------------->| |<-------------------+
| INIT- | | +-------------------->| INIT | |
| REBOOT |DHCPNAK/ +---------->| |<---+ |
| |Restart | | ------- | |
-------- | DHCPNAK/ | | |
| Discard offer | -/Send DHCPDISCOVER |
-/Send DHCPREQUEST | | |
| | | DHCPACK v | |
----------- | (not accept)/ ----------- | |
| | | Send DHCPDECLINE | | |
| REBOOTING | | | | SELECTING |<----+ |
| | | / | | |DHCPOFFER/ |
----------- | / ----------- | |Collect |
| | / | | | replies |
DHCPACK/ | / +----------------+ +-------+ |
Record lease, set| | v Select offer/ |
timers T1, T2 ------------ Send DHCPREQUEST | |
| +----->| | DHCPNAK, Lease expired/ |
| | | REQUESTING | Halt network |
DHCPOFFER/ | | | |
Discard ------------ | |
| | | | ----------- |
| +--------+ DHCPACK/ | | |
| Record lease, set -----| REBINDING | |
| timers T1, T2 / | | |
| | DHCPACK/ ----------- |
| v Record lease, ^ |
+----------------> ------- /set T1,T2 | |
+----->| |<---+ | |
| | BOUND |<---+ | |
DHCPOFFER, DHCPACK, | | | T2 expires/ DHCPNAK/
DHCPNAK/Discard ------- | Broadcast Halt network
| | | | DHCPREQUEST |
+-------+ | DHCPACK/ | |
T1 expires/ Record lease, set | |
Send DHCPREQUEST timers T1, T2 | |
to leasing server | | |
| ---------- | |
| | |------------+ |
+->| RENEWING | |
| |----------------------------+
----------
Figure 5: State-transition diagram for DHCP client
4.4.1 初始化和网络地址分配
客户端从 INIT 状态开始并形成 DHCPDISCOVER 消息. 客户端 SHOULD 等待 1 到 10 秒之间的随机时间, 以避免启动时 DHCP 使用同步. 客户端将 'ciaddr' 设为 0x00000000. 客户端 MAY 通过包含 'parameter request list' option 请求特定参数. 客户端 MAY 通过包含 'requested IP address' 和 'IP address lease time' options 建议网络地址和/或租约时间. 如有必要为交付 DHCP 回复消息, 客户端 MUST 在 'chaddr' 字段中包含其硬件地址. 如第 4.2 节所述, 客户端 MAY 在 'client identifier' option 中包含不同的唯一标识符. 如果客户端在 DHCPDISCOVER 消息中包含请求参数列表, 它 MUST 在所有后续消息中包含该列表.
客户端生成并记录随机事务标识符, 并将该标识符插入 'xid' 字段. 客户端记录自身本地时间, 供以后计算租约过期时间使用. 然后客户端在本地硬件广播地址上向 0xffffffff IP 广播地址和 'DHCP server' UDP 端口广播 DHCPDISCOVER.
如果到达的 DHCPOFFER 消息的 'xid' 与最近 DHCPDISCOVER 消息的 'xid' 不匹配, 该 DHCPOFFER 消息必须静默丢弃. 任何到达的 DHCPACK 消息都必须静默丢弃.
客户端在一段时间内收集 DHCPOFFER 消息, 从可能很多的传入 DHCPOFFER 消息中选择一个 (例如第一个 DHCPOFFER 消息或来自先前使用过服务器的 DHCPOFFER 消息), 并从 DHCPOFFER 消息中的 'server identifier' option 提取服务器地址. 客户端收集消息的时长以及选择一个 DHCPOFFER 的机制取决于实现.
DHCP clients 使用的字段和 options
| Field | DHCPDISCOVER<br/>DHCPINFORM | DHCPREQUEST | DHCPDECLINE,<br/>DHCPRELEASE |
|---|---|---|---|
| op | BOOTREQUEST | BOOTREQUEST | BOOTREQUEST |
| htype | (from "Assigned Numbers" RFC) | ||
| hlen | (hardware address length in octets) | ||
| hops | 0 | 0 | 0 |
| xid | selected by client | 'xid' from server DHCPOFFER message | selected by client |
| secs | 0 or seconds since DHCP process began | 0 or seconds since DHCP process began | 0 |
| flags | Set 'BROADCAST' flag if client requires broadcast reply | Set 'BROADCAST' flag if client requires broadcast reply | 0 |
| ciaddr | 0 (DHCPDISCOVER)<br/>client's network address (DHCPINFORM) | 0 or client's network address (BOUND/RENEW/REBIND) | 0 (DHCPDECLINE)<br/>client's network address (DHCPRELEASE) |
| yiaddr | 0 | 0 | 0 |
| siaddr | 0 | 0 | 0 |
| giaddr | 0 | 0 | 0 |
| chaddr | client's hardware address | client's hardware address | client's hardware address |
| sname | options (if indicated in 'sname/file' option); otherwise unused | options (if indicated in 'sname/file' option); otherwise unused | (unused) |
| file | options (if indicated in 'sname/file' option); otherwise unused | options (if indicated in 'sname/file' option); otherwise unused | (unused) |
| options | options | options | (unused) |
| Option | DHCPDISCOVER<br/>DHCPINFORM | DHCPREQUEST | DHCPDECLINE,<br/>DHCPRELEASE |
|---|---|---|---|
| Requested IP address | MAY (DISCOVER)<br/>MUST NOT (INFORM) | MUST (in SELECTING or INIT-REBOOT)<br/>MUST NOT (in BOUND or RENEWING) | MUST (DHCPDECLINE),<br/>MUST NOT (DHCPRELEASE) |
| IP address lease time | MAY (DISCOVER)<br/>MUST NOT (INFORM) | MAY | MUST NOT |
| Use 'file'/'sname' fields | MAY | MAY | MAY |
| DHCP message type | DHCPDISCOVER/<br/>DHCPINFORM | DHCPREQUEST | DHCPDECLINE/<br/>DHCPRELEASE |
| Client identifier | MAY | MAY | MAY |
| Vendor class identifier | MAY | MAY | MUST NOT |
| Server identifier | MUST NOT | MUST (after SELECTING)<br/>MUST NOT (after INIT-REBOOT, BOUND, RENEWING or REBINDING) | MUST |
| Parameter request list | MAY | MAY | MUST NOT |
| Maximum message size | MAY | MAY | MUST NOT |
| Message | SHOULD NOT | SHOULD NOT | SHOULD |
| Site-specific | MAY | MAY | MUST NOT |
| All others | MAY | MAY | MUST NOT |
表 5: DHCP clients 使用的字段和 options
如果参数可接受, 客户端从 'server identifier' 字段记录提供这些参数的服务器地址, 并在 DHCPREQUEST 广播消息的 'server identifier' 字段中发送该地址. 一旦来自服务器的 DHCPACK 消息到达, 客户端即初始化完成并进入 BOUND 状态. DHCPREQUEST 消息包含与 DHCPOFFER 消息相同的 'xid'. 客户端将租约过期时间记录为原始请求发送时间与 DHCPACK 消息中租约时长之和. 客户端 SHOULD 检查建议地址, 确保该地址尚未使用. 例如, 如果客户端位于支持 ARP 的网络, 客户端可以对建议地址发出 ARP 请求. 广播针对建议地址的 ARP 请求时, 客户端必须把自己的硬件地址填入发送方硬件地址, 并把发送方 IP 地址填为 0, 以避免混淆同一子网上其他主机的 ARP 缓存. 如果网络地址看起来已在使用, 客户端 MUST 向服务器发送 DHCPDECLINE 消息. 客户端 SHOULD 广播 ARP reply 来公告客户端的新 IP 地址, 并清除客户端子网上各主机中过时的 ARP 缓存项.
4.4.2 使用已知网络地址初始化
客户端从 INIT-REBOOT 状态开始并发送 DHCPREQUEST 消息. 客户端 MUST 在 DHCPREQUEST 消息中将其已知网络地址作为 'requested IP address' option 插入. 客户端可以通过包含 'parameter request list' option 请求特定配置参数. 客户端生成并记录随机事务标识符, 并将该标识符插入 'xid' 字段. 客户端记录自身本地时间, 供以后计算租约过期时间使用. 客户端 MUST NOT 在 DHCPREQUEST 消息中包含 'server identifier'. 然后客户端在本地硬件广播地址上向 'DHCP server' UDP 端口广播 DHCPREQUEST.
一旦任何服务器发来的 DHCPACK 消息到达, 且其 'xid' 字段与客户端 DHCPREQUEST 消息中的字段匹配, 客户端即初始化完成并进入 BOUND 状态. 客户端将租约过期时间记录为 DHCPREQUEST 消息发送时间与 DHCPACK 消息中租约时长之和.
4.4.3 使用外部分配网络地址初始化
客户端发送 DHCPINFORM 消息. 客户端 MAY 通过包含 'parameter request list' option 请求特定配置参数. 客户端生成并记录随机事务标识符, 并将该标识符插入 'xid' 字段. 客户端将自己的网络地址放入 'ciaddr' 字段. 客户端 SHOULD NOT 请求租约时间参数.
如果客户端知道 DHCP server 地址, 则将 DHCPINFORM 单播给该 DHCP server; 否则将消息广播到受限 (全 1) 广播地址. DHCPINFORM 消息 MUST 定向到 'DHCP server' UDP 端口.
一旦任何服务器发来的 DHCPACK 消息到达, 且其 'xid' 字段与客户端 DHCPINFORM 消息中的字段匹配, 客户端即初始化完成.
如果客户端在合理时间内 (如果使用第 4.1 节建议的超时, 则为 60 秒或 4 次尝试) 没有收到 DHCPACK, 它 SHOULD 显示消息告知用户该问题, 然后 SHOULD 按 Appendix A 使用适当默认值开始网络处理.
4.4.4 广播和单播的使用
除非客户端知道 DHCP server 地址, DHCP clients 会广播 DHCPDISCOVER, DHCPREQUEST 和 DHCPINFORM 消息. 客户端将 DHCPRELEASE 消息单播给服务器. 由于客户端正在拒绝使用服务器提供的 IP 地址, 客户端会广播 DHCPDECLINE 消息.
当 DHCP client 在 INIT 或 REBOOTING 状态中知道 DHCP server 地址时, 客户端可以在 DHCPDISCOVER 或 DHCPREQUEST 中使用该地址, 而不是使用 IP 广播地址. 客户端也可以使用单播将 DHCPINFORM 消息发送给已知 DHCP server. 如果客户端对发送到已知 DHCP server IP 地址的 DHCP 消息没有收到响应, DHCP client 会恢复使用 IP 广播地址.
4.4.5 重新获取和过期
客户端维护两个时间 T1 和 T2, 它们指定客户端尝试延长其网络地址租约的时间. T1 是客户端进入 RENEWING 状态并尝试联系最初发放客户端网络地址的服务器的时间. T2 是客户端进入 REBINDING 状态并尝试联系任意服务器的时间. T1 MUST 早于 T2, 而 T2 又 MUST 早于客户端租约过期时间.
为避免需要同步时钟, T1 和 T2 在 options 中表示为相对时间 [2].
在时间 T1, 客户端移动到 RENEWING 状态, 并通过单播向服务器发送 DHCPREQUEST 消息以延长其租约. 客户端在 DHCPREQUEST 中将 'ciaddr' 字段设为其当前网络地址. 客户端记录发送 DHCPREQUEST 消息时的本地时间, 用于计算租约过期时间. 客户端 MUST NOT 在 DHCPREQUEST 消息中包含 'server identifier'.
任何到达且 'xid' 与客户端 DHCPREQUEST 消息的 'xid' 不匹配的 DHCPACK 消息都会被静默丢弃. 当客户端从服务器收到 DHCPACK 时, 客户端把租约过期时间计算为发送 DHCPREQUEST 消息的时间与 DHCPACK 消息中租约时长之和. 客户端已成功重新获取其网络地址, 返回 BOUND 状态并可继续网络处理.
如果在时间 T2 前没有 DHCPACK 到达, 客户端移动到 REBINDING 状态, 并通过广播发送 DHCPREQUEST 消息以延长其租约. 客户端在 DHCPREQUEST 中将 'ciaddr' 字段设为其当前网络地址. 客户端 MUST NOT 在 DHCPREQUEST 消息中包含 'server identifier'.
时间 T1 和 T2 可由服务器通过 options 配置. T1 默认为 (0.5 * duration_of_lease). T2 默认为 (0.875 * duration_of_lease). T1 和 T2 SHOULD 围绕固定值选择一些随机 "fuzz" (扰动), 以避免客户端重新获取同步.
客户端 MAY 选择在 T1 之前续订或延长其租约. 服务器可以按网络管理员设置的策略选择延长客户端租约. 服务器 SHOULD 返回 T1 和 T2, 且其值 SHOULD 从原始值调整, 以考虑租约剩余时间.
在 RENEWING 和 REBINDING 状态中, 如果客户端未收到其 DHCPREQUEST 消息的响应, 客户端 SHOULD 在重传 DHCPREQUEST 消息前等待剩余时间的一半: RENEWING 状态中为到 T2 的剩余时间的一半, REBINDING 状态中为剩余租约时间的一半, 但最少为 60 秒.
如果租约在客户端收到 DHCPACK 前过期, 客户端移动到 INIT 状态, MUST 立即停止任何其他网络处理, 并像未初始化客户端一样请求网络初始化参数. 如果客户端随后收到为该客户端分配其先前网络地址的 DHCPACK, 客户端 SHOULD 继续网络处理. 如果客户端获得新网络地址, 它 MUST NOT 继续使用先前网络地址, 并 SHOULD 通知本地用户该问题.
4.4.6 DHCPRELEASE
如果客户端不再需要使用其已分配网络地址 (例如客户端正常关闭), 客户端向服务器发送 DHCPRELEASE 消息. 注意, DHCP 的正确运行并不依赖 DHCPRELEASE 消息的传输.